Author Archives: Boone Gorges

Record user role changes across a WordPress network for troubleshooting

One of my WP/BP projects experiences a perpetual problem, where every few weeks a handful of users is demoted on one of their blogs – they go mysteriously from Editor to Subscriber, or something like that. This sort of thing is a beast to troubleshoot, because it’s not readily reproducible.

So I wrote a small utility plugin that will help site administrators keep tabs on every role-change through the entire installation. Put the plugin into mu-plugins and the run the installation script, and it’ll fire up every time a user’s `wp_x_capabilities` meta key changes, and record some helpful information about it in a custom database table (user id, logged in user id, blog id, BP group id, stuff like that).

For more on the plugin, and to download it, visit its page on Github.

Sowing the seeds

Today I devoted an unusually large amount of time doing free user support for BuddyPress and WordPress (in IRC, over email, through some Trac tickets, and on WordPress StackExchange, the latter of which I’ve been experimenting with for the first time, and I find pretty cool). I say “unusually large” because while I used to do a lot of this sort of thing, it now falls to the bottom of my list of priorities – I do paid work, and when I’m not doing that I do free software development, and when I’m not doing that I try to get the hell away from my computer. As one of the leaders of the BuddyPress project, I usually justify this balance to myself by saying: There are lots of people who can provide user support for this software as well as I can, but there are few who can do productive development for it like I can, so my time is better spent developing. Generally, I think this is a pretty good argument. But I’m glad that days like today come along occasionally, because they remind me of some basic things about the nature of the community around a piece of free software that you can forget when your head is buried too deep in the codebase.

As an aside, I should note that I use the word ‘community’ in a measured way. The word is often overapplied, as if calling a bunch of people working on similar things “the WordPress community” or “the Digital Humanities community” or “the CUNY community” will, in a feat of performative metamorphosis (like how the Queen’s saying “I dub thee Sir Boone” would ipso facto make me a knight), bring into being the thing it purports to describe. Terminological misgivings to one side, there is an undeniable sense in which the work that we do – and by “we” here I mean specifically free software developers, though the point is quite a bit more general than that – is done in a community, or at least (more formally) a network, insofar as those who work on a common piece of free software never really work in isolation from one another. The development process that underlies these software projects depends on the existence of feedback loops, from the end user to the administrator of the installation to the community leaders to the developers themselves, in the form of bug reports, software patches, feature suggestions, support requests, blog posts, and so on.

These feedback loops are not unique to free software development; they’re not even unique to software. But in free software circles the loops are perhaps uniquely malleable, and the distinctions between user and developer uniquely permeable. Each user is a potential contributor, be it through code or advocacy. But the potential is not realized automatically. It’s obvious enough that users who hate using the software and developers whose patches are ignored will never become part of the community. More interesting is the case where a newbie approaches the community with enthusiasm and skill, but where their offerings are not nurtured and so never become real contributions.

I think this happens more than we would care to admit, and I am happy to take my share of the blame. As a developer, I become emotionally attached to the project, and as a result I sometimes interpret criticism as a personal attack. The parts of development that are least exciting – hunting down and fixing the obscure bugs that affect only a small number of users but, for those users, are ruinous – these make me defensive and sometimes angry, as they take my attention away from the more generative work I’d rather be doing. I value my time so highly that I occasionally get annoyed when someone requests some of that time to answer a “simple” question. In each instance, my attitude as a developer and leader of the project could have the effect of chilling what might otherwise have been a fruitful engagement.

Taking the time to do some “support” is the ideal way to fight these tendencies. People ask questions about the software, contribute patches, suggest improvements, etc, because they like the software and want to use it. These people are friends of the project, and should not be treated as enemies. Taking the time to work directly with users is a way of closing the feedback circuit, of sowing the seeds of future collaboration and contribution. If one out of five people recommends the software to someone else, and one out of a hundred contributes back to the software in the form of documentation or code or advocacy, that’s fruitful enough to make the engagement worthwhile.

Salvaging content from a corrupted WordPress installation

Yesterday a friend emailed me asking for help. Her old WP installation had become corrupt – through a bad plugin or something – and she couldn’t bring it back to life. So she decided to start fresh, with a new WP installation on a new server. She wanted to know if it was possible to salvage her old posts, which (as she could see in PHPMyAdmin) were still in the old database. Here’s a copy of the email I wrote to her, on the off chance that it helps someone else.

Note that this technique should be used as a last resort. Generally, WP installations can be saved with a little bit of know-how and elbow grease. Also note that it assumes that you’re switching domain names in the process. Also note that I wrote this in 10 minutes, off the top of my head – amendments or corrections welcome.

===

For shorthand:
WPA is your old, corrupted installation
WPB is a brand new, totally empty installation of WP
WPC is your new production installation, on the new domain

The first step is to get your content out of WPA and into WPB. WPB should be a totally new, throwaway installation – a local installation would be ideal, but a fresh one on your webhost would be fine. (This should NOT be the same as WPC!!) Visit your WPA database (using PHPMyAdmin or whatever tool you’ve got), and export the following tables:
wp_posts
wp_postmeta
wp_comments
wp_commentmeta

In PHPMyAdmin, that usually just means checking the boxes next to those tables, and clicking an Export button somewhere in the interface.

Next, use PHPMyAdmin to view the database of WPB. Drop/delete the four tables corresponding to the ones you exported (wp_posts, wp_postmeta, wp_comments, wp_commentmeta).

Once these four tables are dropped, use PHPMyAdmin to import the versions you exported from WPA into WPB.

At this point, the posts should be safe and sound in WPB. You can verify by visiting WPB in your web browser. The next step is to use the WP export feature of WPB to get the posts out, in a format that WPC will be able to understand. Go to wp-admin on WPB > Tools > Export. Export everything to a local file. Then go to WPC Dashboard > Tools > Import (you may have to install the WP importer plugin) and import. This process should pull your old posts and pages in, without overwriting anything currently in your system.

It’s also a nice idea to set up a redirect from your old domain to your new one. (That will ensure that links to your old blog by other sites will continue to work, as well as any times you may have linked to your own old content.) Two steps:
1) At your domain registrar, make sure that your old WPA domain points to your WPC installation; this usually means putting the WPC domain as the CNAME attribute on the DNS tab.
2) FTP to WPC, and look for a file in the main WP directory called .htaccess (you may have to enable View Hidden Files or something like that). Near the top of the file, put the following lines:

[code]RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^myOLDdomain.com$ [NC]
RewriteRule ^.*$ http://myNEWdomain.com%{REQUEST_URI} [R=301,L][/code]

Make sure to replace myOLDdomain and myNEWdomain with the relevant domain names. This will redirect any request to myolddomain.com to the corresponding URL on mynewdomain.com, meaning that all your old permalinks should continue to work.

Using init callbacks with TinyMCE and wp_editor() in WordPress

WordPress 3.3 introduced wp_editor(). It’s a big improvement over the earlier hacks needed to get a TinyMCE instance on the WP front end. But it broke the feature in my BuddyPress Docs that detected idle time. The problem, in short, was two-fold: my idle-detection JavaScript was loading before the editor was initialized, and it wasn’t detecting key presses inside of the TinyMCE iframe. The solution to both parts of the problem required passing callbacks to the TinyMCE initialization array, in the setup array. It took me a long time to figure out how to do this, so for posterity’s sake, here are some takeaways.

First, the code:

[code language=”php”]
function bp_docs_add_idle_function_to_tinymce( $initArray ) {
if ( bp_docs_is_bp_docs_page() ) {

$initArray[‘setup’] = ‘function(ed) {
ed.onInit.add(
function(ed) {
_initJQuery();

// Set up listeners
jQuery(‘#’ + ed.id + ‘_parent’).bind(‘mousemove’,function (evt){
_active(evt);
});

bp_docs_load_idle();

}
);

ed.onKeyDown.add(
function(ed) {
_active();
}
);
}’;
}

return $initArray;
}
add_filter( ‘tiny_mce_before_init’, ‘bp_docs_add_idle_function_to_tinymce’ );
[/code]

Some notes:

  • I’m passing a ‘setup’ parameter to the TinyMCE init array by filtering tiny_mce_before_init
  • Only do this when you’re editing a BuddyPress Doc – that’s the bp_docs_is_bp_docs_page() check. I don’t want to mess with every instance of TinyMCE on the installation.
  • The setup parameter has to be a string. This gets tricky when the string is supposed to define an unnamed JS callback, because you have to be very careful about escaping quotes. As a string, your callback has to be wrapped in quotes. Also, when WP prints the TinyMCE parameters (and when it sees that your paramater begins with the string ‘function’) it’s going to wrap it in double-quotes. After lots of messing around, I was able to get this to work by using escaped single-quotes. (If you need to double-embed quotes – like a chain of callbacks – use escaped double-quotes.)
  • Where possible, use TinyMCE’s native events. ed.onKeyDown is one of them. It allows me to call my _active() function whenever a key is pressed inside the editor.
  • There are some kinds of actions that aren’t really detectable using TinyMCE’s events. For instance, I wanted to be able to detect when someone was moving their mouse around the iframe and especially TinyMCE’s toolbar. You can see this where I’m binding my callback to mousemove in the TinyMCE _parent element.
  • _initJQuery() and bp_docs_load_idle() are my own functions that need to run after the editor has finished setting up. That’s why they, along with the bind, are called in a callback of ed.onInit – that’s the generic place to put things that need to happen once the editor is up and running.

SOPA, Media Conglomerates, and the Moral Obligation to Boycott

SOPA, in its current form, is dead. But the fight to keep the internet an open platform for communication, creativity, and commerce is far from over. Pacts like ACTA are in some ways more troubling than SOPA/PIPA, as they represent attempts of copyright extremists to do an end-run around the US Congress. (Rep. Daniel Issa has spoken about this recently.) The root problem is not a specific piece of legislation, or even a single piece of technology, but fundamental disagreements about the nature of intellectual property, the relationship between the producers and consumers of media, and the role of government regulation in shaping and enforcing worldviews (be they conservative and profit-focused, or progressive and individual-focused). The fight will continue for as long as these disagreements persist. And the copyright extremists will continue to have sway as long as they have enormous amounts of money, and as long as the political system is arranged in such a way that deep pockets dictate legislative agendas.

This conception of the problem suggests two broad strategies. First: attempt to change the political structures that allow campaign and lobbying money to play such a significant role in the legislative process. Primarily, this is an argument about campaign finance reform. For a very readable outline of the problem, as well as the sketch of a few specific strategies for combatting it, I highly recommend Lawrence Lessig’s recent book Republic, Lost. Needless to say, solving the problems of money in politics is enormously difficult and complex, so I’ll set it aside for the moment.

The strategy that I want to consider here focuses more directly on the fact that media companies are very rich, and can afford political canoodling. (Operating here on the admittedly oversimplified assumption that media companies – TV, movie, music, book publishers – are driving the legislation.) These companies get their money from the people who buy their wares. So, in theory, if everyone stopped going to the movies, buying music, watching TV, etc, then they’d have no money. In other words, a boycott.

A few days ago, I tweeted something suggestive along these lines:

When you buy music, watch TV, or see a movie, don’t forget: the makers hate the free internet & will spend huge amounts of money to kill it.

Assume that the premise here is right (namely, that the people who make media – by which I mean, those who choose which media gets created in the first place, who fund its creation, who are responsible for its distribution and marketing, etc – hate the internet as it currently stands). That means that when you make them richer by buying their stuff, you are increasing their ability to fight the internet. All things being equal, then, someone who values the open internet should not spend money in this way – that is, you’d be morally obligated to boycott.

But all things are not equal. (Such is life.) There are some factors that may mitigate the obligation to boycott:

  • How valuable is the open internet, really?

    I’m assuming that an open internet is valuable enough to defend. I may be totally wrong about this, or I may be overestimating how valuable it is. The less valuable the internet, the less obliged we are to fight against the forces that would wreck it.

  • How much collateral damage would a boycott cause?

    The supporters of SOPA/PIPA talked a lot about the zillions of Americans who make their livings working for media conglomerates. If boycotting media companies would put them all out of work and out on the street, that’d be a bad thing. Of course, this is a complete caricature. For one thing, you can (and should, and hopefully did) make the very same argument about the zillions of Internet professionals who would be harmed by stifling legislation. More importantly, it’s not as if SOPA vs non-SOPA is a zero-sum game, where media professionals all lose their jobs if SOPAesque bills don’t pass. It’s likely that piracy is not as financially harmful as these companies complain, and it’s likely that there are anti-piracy measures that would not harm Internet professionals.

    There’s another kind of collateral damage you might be worried about: the damage caused to the creative people (musicians, writers, actors) who are directly responsible for the media that people love, and the subsequent damage to the “art” itself. In addition to the general points made in the foregoing paragraph, I’ll add that this assumes that the stuff produced by these companies is worth saving. For every The Wire (or whatever your favorite piece of popular media is), there are thousands upon thousands of pieces of trash. Taking these turds out of circulation is probably a *good* thing. Moreover, new models of direct funding for quality art (think Radiohead, Louis CK, projects taking place on Kickstarter) reduce collateral damage even further.

  • How much do you value the media produced by these companies?

    If you’re a TV junkie, or you love the movies, then it’s certainly rational for you to cling to them a bit more than someone who doesn’t care about these media (see the ‘turd’ comment above).

  • How likely is it that a boycott will make a difference?

    Probably hundreds of millions of Americans are consumers of TV, movies, books, and music. For a company like NBC Universal to take notice of a boycott, much less to change corporate policies as a result of the boycott, would require huge numbers of boycotters. You might thus argue that your individual boycott would have no positive value.

    Sadly, this is at least partly true – I’m sure there are many times more people who would go to bat for their TV shows than for the kind of heady internet freedoms that intellectuals get excited about. That said, January’s blackouts demonstrated a deep dependence on the Internet for a broader swath of Americans than I might have guessed. In any case, even a single dollar kept out of media company coffers is one dollar they can’t use to fight the open internet. The “everybody else is buying media anyway” argument is the same kind of reasoning that leads to looting during blackouts. (See also Kant.)

So what does this all mean? I think that there are a couple of takeaways:

  1. I think there’s a decent case to be made for a broad boycott.
  2. Even in the absence of an organized boycott, I think there’s a decent case to be made for individuals to boycott.
  3. If you care about the internet (if you’re reading this blog post, you probably do), you cannot continue to patronize these media companies without at least recognizing the indirect effects of your actions.

This last point is the most important. Every meaningful decision that you make is an ethical trade-off, and this one is no different. When you continue to patronize media conglomerates, you are saying that what you get from them is worth the damage that you thereby do to the cause of an open internet. You may be right about the value of this trade-off, or you may be wrong, but you can’t in good faith continue to consume without at least thinking about it.

Ning nonsense is an opportunity for WordPress and BuddyPress developers

Another chapter in the Ning saga (see my previous posts on the subject): In the past few days, Ning has been sending out emails indicating that they’ll be wiping out non-premium networks in the course of the next couple weeks (see, for example, this blog post).

It’s no coincidence, of course, that I’ve gotten a number of emails in the last few days about support and/or paid consultation for Ning -> BuddyPress migrations, based on my free plugin Import From Ning. Unfortunately, I’m currently swamped with work, and I’m not available for active plugin support or for paid migration gigs related to Ning.

If you are a WordPress developer looking for work, this is a golden opportunity. For one thing, you can make a good amount of money helping folks to migrate their Ning data to BuddyPress, and generally helping to customize their BuddyPress installations. Most of the hard work is done for you: my Import From Ning plugin, while buggy and in need of some updates for recent versions of WordPress (in particular, the plugin has crummy error handling), has all of the logic you’ll need to parse Ning’s JSON files and process them for BP import. Even if you don’t know much about BuddyPress, you’ll find that the BuddyPress parts of the process are already spelled out for you. You might even learn something about BP along the way!

Furthermore, those developers who are really intrepid could take this opportunity to help the Ning/BP users more generally by taking over development on Import From Ning. If you are doing client work anyway, which may require fixing bugs and adding improvements in the plugin, why not contribute it back to the distribution version? By doing so, you’ll not only be helping to grow the BP community (and the cause of free software over proprietary services!), but you’ll be making a name for yourself as a contributor/committer to a popular plugin. In other words, it’s great publicity, and you’ll be creating a market for your services down the road.

If you are a WordPress or BuddyPress developer who is interested in receiving referrals for Ning migrations, and/or if you’re interested in making contributions to Import From Ning itself, let me know and I’ll add you to my list. (You can leave a comment below, or send me an email – boone <at> gorg <dot> es.)

IKEA standing desk

In the spring of 2011, I converted to a standing desk. At that time, I was unsure that I’d want to stick with the setup, and thus I didn’t want to spend the money on a proper standing setup. So my conversion to standing was effected by a motley collection of milk crates, thick books, and other implements of heightening culled from the corners of my apartment. More than half a year later, I’m still using and loving the standing desk, so I made the decision to get something a bit more permanent.

“Proper” standing desks – those that are built for the purpose – tended, in my research, to fall short in a couple of ways. The first is cost. Decent standing desks seemed to start around four or five hundred bucks, and go (way) up from there. The vagaries of New York living mean that I didn’t want to lay out huge amounts of cash on something that might not fit in my next place. I wanted something cheaper. The second shortcoming of manufactured standing desks is size. It’s pretty easy to find what they call “workstations”, which have a surface of about two feet squared. My 27″ monitor by itself requires nearly that much space, and I wanted surface area for writing, a second computer, coffee, etc, yet full-size tables seemed pretty hard to find. Lame surface size is related to my third problem with existing standing desks, which is the paltry storage underneath. I wanted lots of it, and commercially produced standing desks seemed, at best, to dedicate vertical storage to a printer (BOOO PRINTERS).

So I needed something fairly cheap, fairly big, and with a lot of storage underneath. A bit of trawling turned up this hack, which made a desk by combining a few different kinds of Ikea bookshelves. Unfortunately, that desk was too big for my space (I have about 66″ of horizontal space to deal with, and that setup requries a minimum of 73″). But it made me think I could do something similar using IKEA bookshelves.

Here’s the finished product:

And here are the details:

  • 3x BILLY bookcase – Two of these bookcases serve as the ends of the desk. Since I knew I’d have a bunch of additional space underneath, I bought a third, which is just slid underneath for extra storage.
  • 1x VIKA AMON table top – They didn’t have this in the same wood tone of my BILLY bookcases, so I got bright red instead.
  • 1x BILLY wall shelf – I needed something to raise my monitor and laptop up to eye level, and this gives me some nice desktop storage to boot. I couldn’t find something that spanned the full width of the table top, so I just centered this one, and used the extra space for speakers.

Total cost for these pieces was, as of yesterday, about $230+tax.

One of the big bonuses of using bookshelves as table legs is that I don’t need to worry about stability (like I would with regular table legs). The only fasteners I used were the four drywall screws I drove up through the bookshelves to keep the table top from sliding, and the two I drove down through the wall shelf to keep it in place.

If you’re looking to do something like this yourself, make sure you think carefully about height. I chose this combination in large part because the resulting table height (about 43″) works for me: in bare feet, standing on my anti-fatigue mat, my elbows are at almost exactly a 90 degree angle while typing. I’m between 6’3″ and 6’4″, so your ideal desk height may vary.

2011

A bunch of stuff happened in 2011.

Like 2010, 2011 was a year of transitions for me: in my relationship with academia, in the way I earn a living, in the way I present myself as a citizen-builder of the internet. Being a parent is the biggest transition of all, forcing me to put into perspective the ways I spend my energy and the ways in which I define myself and what has value to me. (This transition has been overwhelmingly a Good Thing.) Continuing to strive for the right balance in these areas will, I’m sure, be a hallmark of my 2012. (Thankfully, I have no plans to have a child or get married in 2012. A man needs a year off from major life events!)

Happy new year!

Moving my photo site to a new URL and server

This post is pretty much just a note to self (I tend to have to relearn how to write Apache rewrites every time I use them), but I thought it might be useful to others as well.

A few months ago I set up a Twitpic-esque WordPress site for hosting my mobile photos. Since then, the shared hosting space where the sites lives has been filling up, so I don’t have much storage left, and I’ve also gotten a sweet new domain name. So this morning I took a few minutes to move the existing WordPress site (http://boonebgorges.com/photos/, part of a WP network at boonebgorges.com) and to https://boone.gorg.es/photos/, on another server. Here’s how I did it:

  • Use the WP export tool (Dashboard > Tools > Export) to get an XML of the old site data (on boonebgorges.com/photos)
  • Create a new, empty site (boone.gorg.es/photos)
  • Import the content of the old site (Dashboard > Tools > Import > WordPress)
  • Move my custom theme (and its parent theme) to the new server, and activate it for the new site
  • To make sure that old links to boonebgorges.com/photos/* are redirected properly, put the following in .htaccess on the old server:
    [code]
    # These two lines have to be somewhere near the top of your .htaccess
    RewriteEngine On
    RewriteBase /

    # Redirect old photo URLs
    RewriteCond %{HTTP_HOST} ^boonebgorges.com$ [NC]
    RewriteCond %{REQUEST_URI} photos/*
    RewriteRule ^.*$ https://boone.gorg.es%{REQUEST_URI} [R=301,L]
    [/code]

Because the main purpose of this site is to post from my mobile phone, I also had to change the settings in my WordPress Android app. It doesn’t look like this app allows you to change the URL of an existing site, so I just deleted the one I already had on the phone and added the new one, being sure to enable XML-RPC access first, at Dashboard > Settings > Writing.

Do something about SOPA

Hey you! Do something about SOPA and PROTECT IP..

The Stop Online Privacy Act (and its cousin in the Senate, the PROTECT IP Act) are inching closer to passage. Time is running short for you to do what you can to stymie this legislation, which could very well destroy the open internet as we know it. (Don’t know about SOPA? Get a nice overview in this short video, or check out Jeff Sayre’s helpful bibliography of resources about the bill.)

Why you should care about this

If you are reading my blog, you likely fall into one of a few camps, each of which has a vested interest in preventing the passage of SOPA and PROTECTIP:

  • If you are a developer, user, or advocate of free and open source software, you have several reasons to be concerned about the proposed legislation.

    For one thing, the small-to-medium sized web organizations that are most likely to be targets of SOPA’s blacklisting protocols make up the bulk of the clientele for many web developers I know. These organizations generally do not have the visibility or high profile to put up a stink when and if they fall prey to overzealous “copyright” claims, nor do they have the deep pockets to fund the necessary legal defenses. The danger is especially great for websites that accept – or are built on – user-generated content, like many WordPress and BuddyPress sites; SOPA provides for the blacklisting of entire domains, based merely on the a few pieces of “offending” content, even if the content was not created or posted by the domain owners. Over time, these threats and constraints are bound to make the development of these kinds of sites far less feasible and attractive, resulting in less work for developers – and less development on the open source projects that are largely subsidized by this kind of work.

    On a deeper level, those who are interested in the philosophical underpinnings of free software – the rights of the user – should be terrified by the prospect of media corporations gaining what amounts to veto power over our most fecund channels for the exercise of free expression. Free software lives and dies alongside a free internet. When one level of our internet infrastructure (DNS) is under the control of a self-interested few, it makes “freedom” at higher levels of abstraction – like the level of the user-facing software – into an illusion.

  • If you are an educator or an instructional technologist, especially one who endorses the spirit of open educational movements like (the OG) edupunk and ds106, you should be flipping out about SOPA.

    At an institutional level, thoughtful folks in higher ed and edtech have been fighting for years against a FERPA-fueled obsession with privacy and closedness. They’ve made strides. Platforms that foster learning in open spaces – stuff like institutional blog and wiki installations – have become increasingly commonplace, demonstrating to the powers that be that, for one thing, the legal dangers are not so great, and for another, whatever legal concerns there may be are far outweighed by the pedagogical benefits to be reaped from the open nature of the systems. The threats put into place by SOPA are likely to undo much of this work, by tipping the scales back in the direction of fear-driven policy written by CYA-focused university lawyers. Advocates of open education, and the platforms that support it, should be keen not to let their efforts go to waste.

    At the level of the individual student, the case is more profound. The most promising thread in the story of higher ed and the internet – the thread running through Gardner Campbell’s Bags of Gold and Jim Groom’s a domain of one’s own – is, in my understanding, founded on notions about student power and agency. Users of the internet are not, and should not be, passive actors and consumers of content. Instead, they should take control of their (digital) selves, becoming active participants in the construction of the web, the web’s content, and their own avatars. SOPA and its ilk are an endorsement of the opposite idea: the “ownership” of creative content on the internet is heavily weighted toward media companies, which is to say that you are allowed to be in control of your digital self until it causes a problem for a suit at MPAA or RIAA. The entire remix/mashup culture of ds106 is impossible in such a scenario. If you think that this culture, and the ideology of student personhood that underscores the culture, is worth saving, you should be fighting SOPA tooth and nail.

What can you do? Write a blog post. Join or support the Electronic Frontier Foundation. Most importantly, if you are an American, contact your representatives in Congress. The Stop American Censorship site makes this easy, and gives you all the talking points you’ll need. (“This bill is a job killer!”)

Do it now!