Rethinking template tags in plugins

Some plugins offer their own template tags that the blogger can add to their theme where they’d like to display it. Some may even be loaded with an array of arguments to further customize the options. We’ll stick to a simple myplugin_related_posts() template tag as an example throughout.

Usually, these plugins can’t or aren’t willing to take advantage of hooks, such as appending information to the post content, or widgets. That’s okay, especially so when they also offer those alternatives, but also include a theme template tag.

I want to rethink this process. Some bloggers are weary of modifying templates, some plugins’ instructions are plain dangerous, and some bloggers would love to take advantage of a plugin, but it doesn’t allow much flexibility with its output.

Take this as an example:

// Add this to your theme
myplugin_related_posts();

But, what happens when myplugin is deactivated? That function suddenly no longer exists, and the blog blows up. Of course, most plugin authors realize this, and encourage this instead:

// Add this to your theme
if ( function_exists( 'myplugin_related_posts' ) )
    myplugin_related_posts();

Not bad, but clunky. How can we do this better?

Using Hooks for Template Tags

Dion Hulse blew my mind away when he mentioned this method to me a few months ago. Sure, all developers use hooks on a regular basis, but the ingenuity of using a hook as a template tag was too good to resist.

As an example:

// Add this to your theme
do_action( 'myplugin_related_posts' );

Wow, how cool is that? Look ma, clean code! And no fatal errors! Now all the plugin author needs to do is add their existing template tag to that action:

add_action( 'myplugin_related_posts', 'myplugin_related_posts' );

And, if the plugin author doesn’t provide that, then you can do it yourself in your theme’s functions.php, right next to perhaps other filters and actions that modify or add to the hundreds of template tags built into WordPress.

What’s to stop you from adding arguments?

// Add this to your theme
do_action( 'myplugin_related_posts', array( 'count' => 5 ) );

Or, what’s to stop you from removing, replacing, or adding additional callbacks to the same hook?

If the template tag returns a result and needs to be echoed, you can attach the tag to a filter instead:

echo apply_filters( 'myplugin_get_related_posts', '' );

There are a handful of reasons why I really like this method:

One, it requires no effort for the plugin author to passively support this, as most template tags can already be used as callbacks. To actively support this, they can include an add_action call in their plugin, for the times the hook exists.

They don’t need to require the use of a hook, of course — the widget, template tag, hook, etc., all can be supplied, and the user can choose what to use.

Two, administrators can do this themselves by tying the template tag to a hook on their own. They may need their own wrapper function to support more complex tags, but it’s generally worth it.

Three, if the hook doesn’t exist in the theme, then the plugin’s add_action doesn’t do anything. The converse is that if the callback doesn’t exist, then the action hook doesn’t do anything. No fatal errors.

Four, it encourages plugins and themes to play nice with each other through clean, flexible, and robust methods.

Of course, the template-tag-as-a-callback method is only for those situations where the tag needs to be placed in a particular spot. There’s nothing stopping you from taking the template tag provided by the author and simply leveraging the existing hooks system to append the HTML to the post using the the_content filter.

Leverage the WordPress plugin API and reap the benefits.

Some thoughts on WordPress security and the recent shared hosting attacks

After being a guest on the ExplicitWeb podcast, recorded this afternoon, I noticed that I had been asked on Twitter to talk about what my thoughts were on the current hacks on WordPress and other PHP sites. We didn’t dive into security, instead talking about WordPress 3.0, the development process, and how to contribute, but I wanted to address this very valid question, and in more than 140 characters.

As of this writing, there are no known exploits of WordPress 2.9.2. The viruses going around on various shared hosts appear to be indiscriminately targeting any and all PHP files, and there is no indication that the payload is being delivered through WordPress. Indeed, there are some accounts that are not running WordPress but their PHP files are still being infected.

WordPress is incredibly secure, and we also take security very seriously. E-mail security@wordpress.org if you believe you have discovered a vulnerability. All indications are that these are server and hosting configuration issues. Network Solutions admitted the hacks infecting their users were their fault, while GoDaddy is demonstrating arrogant cluelessness.

WordPress is incredibly popular and used by millions, and thus is an obvious and very public target. But I wish to emphasize that there is a huge difference between a hack exploiting WordPress, and a hack targeting WordPress. Many bloggers are grouping both types of attacks as “WordPress hacks,” even though none are exploiting WordPress directly, and that other PHP applications are being infected — WordPress just happens to be the most widely used.

The difference is significant. A hacker can infiltrate a server and target WordPress files or the database without exploiting WordPress itself. This is quite common because WordPress is so commonly used. A hacker exploiting WordPress means that they are using a bug or vulnerability in WordPress as the attack vector. This is quite rare, especially in more recent versions of WordPress. When a vulnerability is discovered, it is fixed quickly and an update is released. Keep up to date and always ensure you are using the latest and greatest version of WordPress, currently 2.9.2.

My WordPress bash functions

Since my MacBook Pro arrived less than three weeks ago, there are a few applications I’ve yet to close: a browser (Chrome primary, Firefox secondary), an editor (TextMate, and some TextWrangler), and Terminal. I’ve found that as a developer, Terminal is where it’s at.

Here’s a quick rundown of my bash functions file so far. Some of these functions were borrowed from or inspired by fellow core developers Peter Westwood and Ryan Boren, and others just came out of a need or a shortcut. They’re all relatively simplistic, but they’re a window into how I work.

In particular, the way I interact with patches has evolved quite a bit when I switched over to Mac. To think I believed the CLI would slow me down after dealing with TortiseSVN! (Thankfully, I haven’t had to merge too many patches that no longer apply cleanly.)

Downloading and Applying Patches from Trac

# Apply a Trac patch.
trac_patch() {
	curl "$1?format=raw" | patch -p0
}
# Apply a Trac patch on a clean repo.
clean_patch() {
	svn cleanup
	svn revert -R *
	svn up
	curl "$1?format=raw" | patch -p0
}
alias tp=trac_patch
alias ctp=clean_patch
# usage
tp http://core.trac.wordpress.org/attachment/ticket/13237/alot.patch

I don’t use the clean_patch command much, mainly because I have a good idea of the status of my repository when I’m applying a patch. This one in particular was actually inspired by Automattic’s Barry Abrahamson, who warned me at WordCamp SF that Jane Wells can break anything.

(Necessary backstory: Jane was set up with a local WordPress install on her new MacBook Pro, and thus a simple command that cleans up a mess and applies a patch is exactly what she would need. No more commit-it-and-let’s-see-how-it-looks come 3.1.)

trac_patch came from Peter, here. Of course, trac_patch on steroids would be this python script from Nikolay.

SVN: Files Modified

mod(){
	svn stat --ignore-externals | grep '^[^?X]'
}

This one gives me a quick look at core files I’ve modified. svn diff sometimes produces too much output for me to easily ensure I’m not about to commit cruft in another file, so this is a nifty sanity check.

I otherwise haven’t come up with anything else to shorten svn commands. They’re pretty short as it is (and baked into the back of my eyes).

Grepping through Core

jsgrep() { # search development scripts
find . \( -name "*.dev.js" -print \)  | xargs grep -n "$1"
}
cssgrep() { # search development css files
find . \( -name "*.dev.css" -print \)  | xargs grep -n "$1"
}
phpgrep() { # search php files
find . \( -name "*.php" -print \)  | xargs grep -n "$1"
}
wpgrep() { # search php files and development scripts/styles
find . \( -name "*.php" -print -or -name "*.dev.js" -or -name "*.dev.css" -print \)  | xargs grep -n "$1"
}
# usage
wpgrep 'function the_content'

Also inspired by Peter, these commands are quite awesome for finding what you need when you need it.

Script Compression

min() {
java -jar ~/downloads/scripts/yuicompressor-2.4.2/build/yuicompressor-2.4.2.jar -v --type $1 -o wp-admin/$1/$2.$1 wp-admin/$1/$2.dev.$1
}
# usage (I've run these two more than I care to count)
min js nav-menu
min css nav-menu

We use the YUI Compressor for scripts and styles. After toying with a few variations, I came up with the above. Originally inspired by Ryan in a comment on Trac, I traded off some functionality for less paths to traverse. I still have a variation that allows me to specify any two files, however, for the rare instance when I’m not compressing core scripts.

Opening Files Fast

o(){
open $1 -a textmate.app
}
# usage
o wp-config.php

Since I find myself in Terminal so often, I often find I want to open files from there. My o command operates exactly like TextMate’s mate command, but o is shorter, and I can also change it to another application if I move to another one.

That command helps, but I’m not sure what I’d do without these commands:

# Shortcuts for opening WP files insanely fast.
wpinc(){
	o wp-includes/$1.php
}
wpa(){
	o wp-admin/$1.php
}
wpai(){
	o wp-admin/includes/$1.php
}
wpcss(){
	o wp-admin/css/$1.dev.css
}
wpjs(){
	o wp-admin/js/$1.dev.js
}
wptt(){
	o wp-content/themes/twentyten/$1.*
}

Usage:

wpi post # wp-includes/post.php
wpai schema # wp-admin/includes/schema.php
wptt style # wp-content/themes/twentyten/style.css
wptt functions # wp-content/themes/twentyten/functions.php
wpjs nav-menu # wp-admin/css/nav-menu.dev.js

These evolved from a weakness of the o command — it was slow for traversing the same paths over and over. I knew what the file was called and where it existed, and I just wanted to open the file now.

So there you have it. Are there any functions you use that can speed up a WordPress or web development workflow?

In WordPress, prefix everything

I recently read a tutorial on digwp.com, a site run by Chris Coyier and Jeff Starr, and noticed that the functions were called rather generic names, such as custom_css_hooks, save_custom_css, and insert_custom_css.

I sent a message to Chris via Twitter: “It’d be nice to see digwp.com prefix functions used in tutorials. Promote best practices instead of condoning bad behavior?” He replied, asking for more information. When I began to write an email to him, I found that there was actually rather little that has been written on the subject, besides two lines in a large Codex page on writing a plugin. I could have sworn I’ve seen other blog posts, but I couldn’t find one — so here is an attempt.

It’s a simple concept. Anything you create in the global namespace has the potential to conflict with a theme, another plugin (including one you wrote), and WordPress core itself. Thus, prefix everything with a unique-enough character set. For example, all functions I write always start with “nacin_”, and I make sure that my functions are unique across all of my plugins. Even when I send a code snippet over the wp-hackers mailing list, I use nacin_ or myplugin_.

I would recommend the same to digwp.com — use digwp_ as a prefix, and try for them to be unique across all tutorials (within reason, of course). It promotes best practices and prevents accidentally teaching bad behavior. Their goal is to be a resource for plugin developers — many tutorials supply code snippets with the intent that they are studied, reused, and refactored. If two developers use code from a tutorial and decline to rename the functions, their plugins will be incompatible with each other.

Functions are only the beginning. One trick is to use a class to encapsulate your functions as class methods instead. When initializing your class, if you wish to assign it to a global variable, make sure that is unique too. Here are some examples:

function nacin_custom_css_meta_box() {
   // ...
}
function nacin_custom_css_save() {
  // ...
}

Using a class, a preferred method by many (myself included):

class nacin_custom_css {
    function init() {
        // ...
    }
    function save() {
        // ...
    }
}
$nacin_custom_css = new nacin_custom_css();

Clearly, the class method is very clean. You can name methods after after hooks and action verbs, working within that namespace as if it is a blank slate (because it is). Classes are very helpful in WordPress plugins even if you are not using object-oriented concepts.

At one plugin competition (I would say it was WordCamp NYC 2009, but I can’t find a link) referenced by Ozh Richard in the comments, multiple plugins by the same author could not even be run on the same blog, since they conflicted with each other. Don’t do that. If you have the same function in two different plugins, consider wrapping both in a function_exists check, that way both plugins can use whichever is defined first. Some do that with every function or class they define, just as a precaution. Fatal core errors from redefinition of functions will take a blog down real quick.

Prefix Everything

With custom post types getting super-charged in WordPress 3.0, along with better support for custom taxonomies, more plugins are going to be creating strings that sit alongside one another in the database. If they conflict, the results can be quite unexpected.

So, here’s a thought — prefix everything. Instead of creating an “event” or “twitter” post type, create “nacin_event” or “nacin_twitter” instead. Same with taxonomies. Meta box identifiers. Widget identifiers. Slugs on menu pages and subpages. Any callback or identifier you need to use, make sure you have it properly namespaced.

(Edit:) In the comments, Dougal Campbell also brought up namespacing options (and a related proposal). Though I neglected it in my laundry list, that is also very important. Same goes for transients, as well as metadata for users, posts, comments, and networks. You can also take advantage of serialization in these cases, and store arrays of options together, instead of polluting the options table (and increasing queries in some cases).

This all applies to themes, too — Twenty Ten uses the twentyten_ prefix throughout, for both functions it uses, and action hooks it adds in the theme. We also wrap most in a function_exists check, but that’s actually to allow those functions to be replaced by a child theme.

Use Common Sense

Above all, just make sure you avoid things that look too generic. Google recently released a plugin that prefixed every function throughout, except one — the callback tied to the activation hook. The function name? install(). I died a little that day.

Of course, if every other plugin author is properly prefixing their functions, then that function won’t conflict with any of them. I would leave the lack of a prefix to core — only some of our functions use the wp_ prefix. And, of course, avoid the wp_ prefix.

This isn’t just theoretical. We broke a plugin in 3.0, as a plugin was defining a function called get_admin_url(), which we added. That’s way too generic a name to assume we won’t add one like it — we’re at 4,000 functions and counting in WordPress. (I sent them an email and they said they would release an update — we try to play nice too. We’ve also renamed a function we had introduced, because it conflicted with a BuddyPress function.)

Another plugin is the Publish2 plugin, which uses publish2_ and p2_ interchangeably. Normally that might be fine, but there’s also the wildly popular P2 theme from Automattic, and the theme also uses p2_. I’m not aware of a naming conflict yet between them, but on the safe side, I sent a message to the Publish2 plugin developer giving him a heads up and suggesting that he standardize on publish2_.

In some ways, it’s about future-proofing. The bigger picture is that your plugin should do one thing and do it well, and allow other plugins to work with it side by side. When you’re a small fish in a big ecosystem, realize you’re not alone and play nice with others.