Category Archives: wordpress

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.

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.)

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!

New WordPress plugin: Add User Autocomplete

Add User Autocomplete

Add User Autocomplete

Site admins on a WordPress Network can add existing network members to their site on the Dashboard > Users > Add New panel. But the interface requires that one know either the email address or the username of the user in question. My new plugin, Add User Autocomplete, makes the Add Existing User workflow a bit easier, by adding autocomplete/autosuggest to the Email Address/Username field. Just start typing, and the plugin will return matching users; arrow down or click on the intended user to add her to the Add User list.

A few additional bonuses provided by the plugin, aside from autocomplete:

  • In addition to return email address and username matches, the plugin also checks against the display_name and user_url fields. So if my username is ‘admin’, and my email address is ‘bgorges@boonebgorges.com’, but my display name around the site is ‘Boone Gorges’, you’ll be able to find me by searching on ‘Boone’.
  • You can add many users to a blog at once. Search for one user, select and hit Return, and then search for another.
  • Prettier success messages. When you submit the Add New User page, your success message will give you a list of the users invited, instead of a generic “Invitations have been sent” type message.

Add User Autocomplete requires WP 3.1 and JavaScript. The plugin was developed for the CUNY Academic Commons. Check out the plugin at wordpress.org or follow its development at Github.

New BuddyPress plugin: BP Better Directories

BP Better Directories

BP Better Directories

BP Better Directories is a new BuddyPress plugin that will turn your (kinda boring) member directories into something a lot slicker. Site admins select which fields they’d like to be filterable in member directories. Site visitors can then use a nice AJAX interface for narrowing search results.

This plugin is being developed for the CUNY Academic Commons, and is in early beta. Don’t use on a live site. There’s also a pretty good chance that the technique I’m using in the guts of the plugin won’t scale all that well without proper caching. You have been warned! (Also, it requires at least BP 1.5.1.)

Download the plugin or follow its development on Github.

Done with Apple

In my 2010 year-in-review post I made a passing mention to my decision not to buy any more Apple products. Most people who know me can probably guess the reasons behind the decision, but recently I’ve had some discussions that made me think that it’s worth a blog post to spell them out.

First is my ongoing project to move away from proprietary software in general. All things being equal, it’s better to use software whose source code I can view and modify; even if, in fact, I never do these things, the fact that I could is a kind of safeguard against a number of frequent aspects of closed-source software: data lock-in, data rot, restrictions on hardware compatibility, secret surveillance, etc. As the operating system is in many ways the foundation of all other tasks I do on a computer, so it is of fundamental importance to use an open OS.

Second. I believe in the Web as an open platform for communication and expression, and Apple is increasingly anti-web.

You often hear hoopla about how digital technologies can radically democratize and transform x (fill in your favorite x: scholarship, education, publication, politics, etc). The success or failure of these transformations is tied up with the Web’s openness as a platform: open standards like TCP/IP, enablers of decentralization like distributed DNS, free software like Linux and Apache to run servers. Putting any of these technical details under the control of a single agent, especially a corporate agent that answers only to shareholders, threatens to limit free expression and disenfranchise vulnerable groups of potential users. If a robust, widely-used, open Web is important to the future of equality and democracy, and if such a Web can only be defended by keeping out proprietary interests, then it’s important to fight against interference from those interests.

I take it as fairly obvious that Apple (and not only Apple, though they seem to be the trendsetters) is anti-Web. Consider their distribution models. iTunes makes it so that you have to buy apps, music, and movies through an application, rather than through web pages. Know that annoying “feature” where, when you click on an iPhone app link on the web, you get a page informing you that you’ve clicked on an iTunes link, whereupon iTunes proceeds to open? That’s anti-web. The increasing focus on “apps” is a more troubling anti-web move. As was nicely illustrated by an article I read a while back (can’t find the link), you can spend a whole day doing stuff on an iPad – using Twitter, Facebook, WordPress, Yelp, email, Google Maps, etc – without ever viewing a web page (though they all use web services that use HTTP as a transport). In this way, Apple is doing an end run around the web.

The nature of the end run is particularly troubling. Apple is the arbiter of the software that runs on its devices (completely, in the case of iThings; increasingly, in the case of the AppStorified Mac). This creates unnecessary bottlenecks when it comes to bugfix or security releases. It creates a single point of failure for apps and therefore for devices; if Apple goes under tomorrow (or, more likely, changes their mind completely about whatever they please), how will you continue to update your apps? Worst, it puts Apple in the position of policing for content, which, whether driven by a well-intentioned desire to avoid offensive content or by a malevolent puritanism, is a Bad Thing.

Anyway, all of these points have been made over and over again, by many different people. My own bottom line: I believe in the value of the open web to such an extent that I’ve devoted my career to it. Thus, it feels wrong to keep using, and indirectly encouraging the use of, technologies like Apple’s. That goes especially for iOS and its devices, the area where I think the threat to the web is worst. But it extends to the Mac as well. Even if you maintain that the Mac will never merge into iOS (a position I find disingenuous), there’s no question that spending money on Mac hardware is a way of indirectly feeding the beast. Next time I buy a laptop, I’ll be sad not to be getting a pretty MacBook, but, on balance, I feel more comfortable giving my money to a hardware manufacturer that’s less pernicious.

For what it’s worth, I don’t think that mine is a decision that everyone must, or even should, make. Using Apple products brings pleasure to a lot of people, even people who largely share my ideologies about the free web. It’s perfectly legitimate to decide that the benefits you get from using those products outweigh the downsides. But, for me, it’s past the tipping point, which is why I’m done buying Apple products.

It’s here – BuddyPress 1.5!!

It’s finally here! After many, many months of bug squashing, refactoring, and general bloodsweatntears, BuddyPress 1.5 has been released!

This long development cycle has been frustrating in some ways and extremely rewarding in others. On balance, I’m quite proud of the work that’s been done, and quite pleased to have worked so closely and so well with John, Paul, and all the other contributors to BuddyPress. My sincere thanks to all the users and developers who have been supportive during this dev cycle.

Most importantly, BuddyPress 1.5 itself kicks ass. The bp-default theme has seen some serious improvements, some much-needed features have been added, and the codebase has been overhauled in terms of additional internal APIs, documentation, style, and so on. If you’ve done development with BuddyPress in the past, do yourself a favor and check out BP 1.5 – you are in for an extremely pleasant surprise.

Here’s to 1.6 and beyond!