Act now to stop Internet censorship legislation in the United States

Right now, the United States Congress is holding hearings on legislation that will have disastrous effects on free speech and the Internet. This video gives a good overview:

One of the reasons that I help make WordPress is because of my deeply held conviction that free speech is the most powerful and beneficial tool humans have ever had at their disposal. The Internet is a grand experiment that not only makes communications fast — it embraces freedom by design. This legislation is a low level attack against the system of trust upon which the Internet is based. It’s an attack on freedom of speech and on economic freedom. It’s corporate cynicism of the worst kind.

Act now, and be sure that your legislators know you oppose this legislation.

Translating WordPress Plugins and Themes: Don’t Get Clever

When you use the WordPress translation functions to make your plugin or theme translatable, you pass in a text domain as a second parameter, like so:

<?php _e( 'Some Text String', 'my-plugin-name' ); ?>

This text domain is just a unique string (usually your plugin’s WordPress.org repository slug). Well, many plugin developers see code like this:

<?php _e( 'Another Text String', 'my-plugin-name' ); ?>
<?php _e( 'Yet Another Text String', 'my-plugin-name' ); ?>
<?php _e( 'Gosh, So Many Text Strings!', 'my-plugin-name' ); ?>

And they think to themselves “hm, I sure am typing the 'my-plugin-name' string a lot. I’ll apply the DRY (Don’t Repeat Yourself) principle and throw that string into a variable or a constant!”

Stop! You’re being too clever! That won’t work!*

See, PHP isn’t the only thing that needs to parse out your translatable strings. GNU gettext also needs to parse out the strings in order to provide your blank translation file to your translators. GNU gettext is not a PHP parser. It can’t read variables or constants. It only reads strings. So your text domain strings needs to stay hardcoded as actual quoted strings. 'my-plugin-name'.

Happy coding!

* Well, it won’t break your plugin, but it could make it harder to be used with automated translation tools. And trust me, you don’t want to be manually managing your translation files… we have a better solution coming.

That’s a lot of shortcodes

I did a scan of the WordPress plugin directory today, and found the following shortcodes in use. The list is non-exhaustive, as some shortcodes are specified with variables. This is just the list of basic quoted string shortcodes that I found. There was some discussion about programmatically extracting these from plugins and publishing a directory, so prospective plugin authors know whether the shortcode they want to use might conflict with another plugin. Or, even better, they can offer compatibility between similar plugins.

Continue reading

Speaking at WordCamp SF 2011

My sessions for WordCamp San Francisco 2011 have been confirmed. This post is a quick teaser. Please let me know if you have any questions on what will be covered, or if you have any suggestions:

Scaling, Servers, and Deploys — Oh My!

Alternate title: First Thing, Second Thing, and Oxford Commas — Em Dash! :-)

If you manage professional WordPress-powered sites, this is going to be an invaluable presentation for you. If you’re a cowboy coder, this presentation is a mandatory WordPress-ordered intervention. (And if you don’t know what cowboy coding is, you probably do it, and don’t even know you need help.)

I’ve worked with a lot of WordPress installations for professional sites in my client work. They inevitably fall short in some way. What is usually the case is that the people in charge of running the installation feel that instead of them having control of the environment, they are merely present in the environment. Deployments that were meant to be scalable are often somewhat less so, in practice. Tell me if this conversation sounds familiar:

“What happens if we outgrow one server?”
“We’ll just add another one!”

That’s easy to say as a hypothetical. But what if you actually had to do it? What if a couple hundred thousand unexpected page views started coming your way and your boss/client tells you “Go ahead and add that second server we’ve been talking about… how many minutes is that going to take?” Did you think “no sweat,” or did your heart start racing just imagining the scenario?

I’m going to disclose the secret sauce. I’ll let you in on everything I’ve learned in the last seven years about how to code and architect WordPress-powered sites, how to scale up a single server, how to manage multiple servers, and how to deploy code in a way that is both responsive and prudent.

Topics will include:

  • Apache
  • nginx
  • Memcached
  • MySQL
  • APC
  • NFS
  • rsync
  • Git
  • Puppet
  • Capistrano

And more. At the end you’ll feel confident that you can run professional, fast, scalable WordPress installations that will make your job easier and your clients or boss happy.

Security Showdown

Instead of my battle-worn and (even to me) rather droll talk on WordPress security, I’m going to be doing an interactive panel with Brad Williams and Jon Cave. We’ll do live security reviews of some plugins that have been submitted ahead of time. This way, you can see WordPress security practices in action! There will be prizes and everything. Should be a bunch of fun.

WordPress local dev tips: DB & plugins

Running a WordPress site on your local machine is a great way to do development. I’ve taken advantage of this to do development while on flights (and yes, I realize that in about 5 years it’s going to seem positively quaint that there used to be flights without Internet access).

Today, I’d like to tackle two common issues when running a WordPress site locally:

  1. Handling differing database connection details
  2. Handling plugins that can’t or shouldn’t run on a localhost

My assumptions:

  • You have your site in a Git repository
  • You have a working LAMP/MAMP/WAMP/whatever setup.
  • You already know how to do a mysqldump and import that dump to your local machine

Database connection details

Your database user and password are (or should) be different on your localhost than they are on your production environment. One way to handle this is to have wp-config.php not be in version control and have everyone make their own. Boo. Stop taking things out of version control. Another solution I’ve seen is that people modify the wp-config.php and just try to be really careful not to commit their local changes. Again, boo.

Here’s how to do it. Open up your wp-config.php file.

if ( file_exists( dirname( __FILE__ ) . '/local-config.php' ) ) {
  include( dirname( __FILE__ ) . '/local-config.php' );
  define( 'WP_LOCAL_DEV', true ); // We'll talk about this later
} else {
  define( 'DB_NAME',     'production_db'       );
  define( 'DB_USER',     'production_user'     );
  define( 'DB_PASSWORD', 'production_password' );
  define( 'DB_HOST',     'production_db_host'  );
}

Ignore the WP_LOCAL_DEV define… I’ll explain that later.

Now open up your .gitignore file.

/dir-that-contains-wp-config/local-config.php

There. Now you can just create a local-config.php file and put your DB_* defines in there. And thanks to the .gitignore addition, you won’t have to worry about accidentally committing your local config.

But what if you want to override other defines locally? Well, just modify them in wp-config.php like so:

if ( !defined( 'SCRIPT_DEBUG' ) )
  define( 'SCRIPT_DEBUG', false );

And make sure they’re after the local-config.php block. Now you can override these defines as well.

Plugins that are production-only

I’m a big fan of VaultPress from Automattic. But this is not something you want to run on your localhost. Other backup plugins probably fall into this category of “production-only.”

The bad way to do this is to remember to disable this plugin after you import a DB snapshot to your localhost. Boo. Remember WP_LOCAL_DEV that we set earlier? Let’s use it.

I’ve written a quick “must-use” plugin to handle conditional plugin disabling. Get it here, and put it in the mu-plugins directory (create it in your WP content directory if you don’t already have one).

The part you modify is at the bottom:

new CWS_Disable_Plugins_When_Local_Dev( array( 'vaultpress.php' ) );

I’ve jump-started you by putting vaultpress.php in there. Add plugin filenames to that array as necessary. Don’t forget that most plugins are in a subdirectory, so they’ll be in the form plugin-name/plugin-name.php.

Now those plugins won’t be active when doing local dev (based on the presence of local-config.php).

How to write a WordPress plugin that I’ll use

I tend to be very fastidious about the WordPress plugins that I’ll install. I’ll often write my own simple version of a plugin rather than install one from someone else that does a bunch of stuff I don’t need. Here is my philosophy behind writing WordPress plugins, best witnessed through the plugins I’ve written lately, like Markdown on Save, Login Logo, Monitor Pages, and WP Help.

Fewer features as a feature

There are diminishing returns as you add features. That is, the more you add, the more likely you’re adding something that X % of your plugin’s users won’t ever use. Stick to the basics. I’ll often release a “0.1″ version of my plugin with really obvious features missing. When I get a flurry of “You should add Y!” messages, that validates my assumption that Y is necessary. Start with the smallest version that gets the core job done. Iterate as needed.

Code the hell out of it

The best part of starting small is that you can code the hell out of the plugin. Do it right. Make each line of code beautiful. Make sure you’re using WordPress APIs properly, and while you’re at it, add i18n support (WP Help 0.2 shipped with support for Bulgarian, German, Spanish, Mexican Spanish, Macedonian, Dutch, Brazilian Portuguese, and Russian!)

Reduce UI

If you can do without UI, don’t make it. Make every bit of UI prove its necessity. As an example, look at my Login Logo plugin. It has zero UI. It looks for the presence of a file named login-logo.png in the wp-content directory. The rest is “magic.” It measures the image, generates appropriate CSS, and gives you an instantly and easily customized login screen. The plugin is invisible. It’s completely out of sight, and out of mind. Finally, UI screens are generally where plugin authors make security mistakes. By skipping them, you make it much more likely that your plugin is secure.

Code it for the future

Don’t use deprecated APIs. Plan features in future-forward ways. Implement it in such a way that a site that is using the plugin doesn’t break if the plugin suddenly goes away. One example of this is my Markdown on Save plugin, which offers per-post Markdown formatting. First, I decided that for performance reasons, I wanted to parse Markdown then the post was updated, not on display. The obvious place to store the generated HTML was in the post_content_filtered column that WordPress provides (but does not use). But then I considered what would happen if someone deactivated the plugin or deleted the plugin. The code that accessed post_content_filtered would not work. Their blog would spit out raw Markdown. And any exports they made would export raw Markdown. What if they were exporting to WordPress.com which doesn’t support Markdown? So I decided to store the Markdown in post_content_filtered, and store the generated HTML in post_content. When you edit a Markdown-formatted post, it swaps in the Markdown, so you can edit that. But if you deactivated the plugin, it would fall back to the HTML. So you can feel free to use this plugin and know that if one day you wake up and you hate Markdown, all you have to do is deactivate the plugin and all of your posts are back to HTML.

Secure it

Writing secure WordPress plugins isn’t hard. It just takes awareness. Take the time to do your research and code a plugin that will be an asset to its users, not a liability.

Developing on WordPress using Git

WordPress uses Subversion (SVN) for revision management. Before Subversion, it used CVS. Right now, Git is a hot option in the SCM category. It offers really nice features such as decentralization, speed, fast and cheap local branching, better merging, more offline capabilities, staging of commits, and lots more. It’s premature to talk about moving WordPress core and plugins to another SCM system — we have a lot invested with Subversion and Trac. But be of good cheer. You can have your Git and commit to Subversion too! Here’s how I do it.

First, tools. You’ll need Git, obviously. But you’ll also need git-svn-diff, a Bash script that generates Subversion-compatible diffs.

Download git-svn-diff, put it somewhere in your path, and make it executable. Like this:

curl -L http://rkj.me/a1 > /usr/local/bin/git-svn-diff
sudo chmod +x /usr/local/bin/git-svn-diff

Next, to enable you to do git svn-diff instead of git-svn-diff, edit ~/.gitconfig and add this:

[alias]
	svn-diff = !git-svn-diff

This next step is going to take a while. You’re going to pull down WordPress’ SVN history using Git’s SVN support.

git svn clone -t tags -b branches -T trunk http://core.svn.wordpress.org/

You might want to let that run overnight. Really. It’s going to go through each changeset.

Once you’re done, you should be in the Git master branch, which corresponds to WordPress SVN’s trunk. WordPress’ branches are in remotes/{name}

To pull in the latest changes from SVN, use git svn rebase. Important rule: never modify the SVN branches (remotes/{name}). Instead, create a new topic branch.

For example, say that I’m going to work on a ticket for trunk. I’d create a new branch from remotes/trunk like this:

git checkout -b ticket-12345 remotes/trunk

That will create a new local Git branch called ticket-12345 based on SVN’s trunk, and then check it out (i.e. switch to it).

If you’re working on a WordPress SVN branch, you can do something like this:

git checkout -b ticket-12345 remotes/3.1

Do your work in the branch you created. You can make multiple local Git commits if you want, to break up your work into smaller chunks that make sense to you.

When you’re ready to submit your patch, use git-svn-diff to produce it.

git svn-diff > ~/12345.diff

If you have commit access, you can commit to Subversion from this topic branch. But be careful! First you should do git svn rebase to bring your patch up to date. Next, you should squash your local git commits, otherwise each one of them will be individually committed to SVN (hello, flood). So rebase your commits into one commit, like so:

git rebase -i remotes/trunk

Use “reword” on the first commit. Use “fixup” on the subsequent ones. That will roll the commits up into one. You’ll then be prompted to enter your amended commit message for that commit amalgam.

Ready? You can now commit to SVN using:

git svn dcommit

Git knows which remote SVN branch it came from when you checked out your topic branch. You can verify which one it is attached to by doing:

git svn info

A few tips:

Create a .gitignore file. This lists files or directories that you want Git to ignore. First, you want Git to ignore the .gitignore file itself! Next, you want Git to ignore your local wp-config.php Finally, you want to ignore any additional plugins, must-use plugins, themes, uploads, etc. Just do a git status and add anything that you don’t want to commit to WordPress or put in your patches.

I hope you found this helpful! Let me know if you have any questions.

Just you and your thoughts

In 2007, I wrote this about the job of software:

That’s when I know WordPress is doing its job: when people aren’t even aware they’re using it because they’re so busy using it!

I cited that more as a direction, than a goal. If the job of software is to get out of the way, it never completely reaches it — it just gets closer and closer. Sort of how dividing a number in half an infinite number of times never quite gets you to zero.

Today, in 2011, I took this screenshot of the Distraction-Free Writing interface for the upcoming WordPress 3.2:

screenshot of WordPress Distraction Free Writing interface. A title, and a body.

How’s that for getting out of your way?

2010 in review

The stats helper monkeys at WordPress.com mulled over how this blog did in 2010, and here’s a high level summary of its overall blog health:

Healthy blog!

The Blog-Health-o-Meter™ reads Wow.

Crunchy numbers

Featured image

The Louvre Museum has 8.5 million visitors per year. This blog was viewed about 410,000 times in 2010. If it were an exhibit at The Louvre Museum, it would take 18 days for that many people to see it.

In 2010, there were 15 new posts, growing the total archive of this blog to 171 posts. There were 43 pictures uploaded, taking up a total of 330mb. That’s about 4 pictures per month.

The busiest day of the year was June 25th with 13,614 views. The most popular post that day was New in WordPress 2.9: Post Thumbnail Images.

Where did they come from?

The top referring sites in 2010 were codex.wordpress.org, wordpress.org, WordPress Dashboard, shexperience.com, and slashdot.org.

Some visitors came searching, mostly for wordpress post thumbnail, wordpress thumbnail, wordpress thumbnails, wordpress plugin tutorial, and post thumbnail wordpress.

Attractions in 2010

These are the posts and pages that got the most views in 2010.

1

New in WordPress 2.9: Post Thumbnail Images December 2009
521 comments and 26 Likes on WordPress.com

2

WP Tutorial: Your First WP Plugin March 2006
418 comments and 1 Like on WordPress.com,

3

Why WordPress Themes are Derivative of WordPress July 2010
182 comments and 17 Likes on WordPress.com

4

WordPress Error: You do not have sufficient permissions to access this page March 2006
226 comments

5

WordPress 2.0.3: Nonces June 2006
108 comments and 3 Likes on WordPress.com

Post Formats vs. Custom Post Types

Some people are confused about the Post Formats feature that will be made available to themes in WordPress 3.1, especially how it differs from Custom Post Types.

Custom Post Types

These were poorly named. Think: Custom Content Types. That is, non-post content. Examples: employees, products, attachments, menu items, pages, pets. If you want it to show up in your site’s main RSS feed, then it’s probably not a custom post type.

Post Formats

A Post Format is a formatting designation made to a post. For example, a post could be a short “aside,” or a Kottke.org-style link post, or a video post, or a photo gallery post. The data you input might be slightly different — video post should contain a video, an aside should probably not be very long, a link post should have a link. And the way that the post is displayed on the site might be very different — an aside will typically be displayed without a title, a link post may have the title point to the link. A video post may be wider, or have social sharing buttons auto-appended. But they’re all still posts. They still show up in your feed, and you still find them in the Posts section of the WordPress backend.

The important thing to note about Post Formats is that they are going to be a standardized convention. So any theme that supports Post Formats and follows the standard will display your posts in a way that makes sense. Before, themes had to set up category-based conventions, and these conventions weren’t shared by other themes. This is a better way of handling that, and it should make it even easier to switch between themes than before!

Themers should turn to the Post Formats page in the Codex for info on implementation. Note that we’re not yet in beta, so expect this page to change a bit.

WordPress Q & A: Week of September 27

Ricky asks:

Thanks for your time. I’m working on a site where I’d like members to be able to submit posts, but I’d like to be able to moderate them first before they go live.

Kinda similar to what WP can do for comments, I’d like to do for posts. Is that possible?

Certainly! What you want is to open up registration and make the default role for new users “Contributor” instead of “Subscriber.” Contributors can submit posts for review, but not publish them. They’ll show up as “pending review” in the backend, and will require an Editor or Administrator to publish them. There are even plugins available to facilitate posting from the front end, such as Gravity Forms ($39 and up, GPL).

Allan asks:

I have hit an incredibly frustrating hitch with WP, and that is getting a text file with the content of my posts. I need a single file I can load into page layout software. I know about Blog Booker and Blurb but would like more layout control than those services offer.

If you need this for a bunch of posts on an ongoing basis, I’d create a custom page template and just have it do query_posts('posts_per_page=9999'); (or however many posts you want), and then do a basic loop. Look at a simple theme for inspiration on the template tags… it all depends on how you need it formatted.

Import a Vox blog into WordPress (or almost anything else)

Six Apart is closing the doors on Vox, a blogging service they launched three and a half years ago. You have until September 30th to export your content from Vox, or you’ll lose access to it. Yikes!

They helpfully included a link to WordPress.com’s importer help page. WordPress.com has a Vox importer. What isn’t immediately obvious is that you can use WordPress.com as an intermediary on your way to a final destination. That is, you can import your Vox blog to a temporary WordPress.com blog, and then do an export from WordPress.com. Now you’ll have gold: a WordPress export file. You can take this file and import it into a standalone WordPress site, or a plethora of other blogging tools or services.

I recommend that everyone who has Vox content they want to save do this. Mark your WordPress.com blog as private if you don’t want that to be its final destination — just do it (and soon!) so that you have a copy of your site in a useful and portable format.