Tip: wp_cron() runs during init

Pro tip: wp_cron() runs during the init action at the default priority, i.e. 10. If you’d like things to be available during your cron tasks, make sure you initialize them earlier: the init action at priority 9 and less, or other actions that run before init — beware of these, since other things might not be available at that time.

Also, Core Control is a good plugin to test and debug cron tasks.

Reminder: Don’t Use the Short PHP Open Tag

Jetpack 2.0.1 was released last night, immediately followed by 2.0.2, which fixed a fatal error on some hosts, caused by a short PHP open tag. So here’s a reminder: never use the short form of the PHP opening tag:

<? _doing_it_wrong(); ?>

Always use the long form:

<?php _doing_it_right(); ?>

If your grep can do Perl regular expressions, you can search your entire codebase with a negative lookahead like this:

grep --include=*.php -rP '<\?(?!php|xml)' *

Joseph Scott has a simpler example that works without the -P flag. If you’re building WordPress themes, the Theme Check plugin will scan your theme for short tags automatically. Plugin Check will do the same thing for your plugins.

Stay safe.

WordPress E-mails in HTML

WordPress sends e-mails in plain/text by default, and you can change that using the wp_mail_content_type filter. However, if you change the content type to text/html for all your e-mails, you might break some messages that contain links, because WordPress puts <angle brackets> around links.

From the RFC2396:

Using <> angle brackets around each URI is especially recommended as a delimiting style for URI that contain whitespace.

If you’re going to change the content type for all your e-mails issued by WordPress, don’t forget to rewrite the default messages with proper markup. You can do that with various other filters, like retrieve_password_message.

Finally, if you’re going to send e-mails in HTML, please make sure they all respond well to narrow screens on mobile devices, and preferably contain a plain/text version of the same message.

WordPress Actions vs. Filters

If you’re still wondering about the difference between WordPress actions and WordPress filters, Michael Fields posted a very cool explanation in this forum thread called Actions vs. Filters. I think it’s the best explanation of actions and filters I have seen so far, well done Michael, and keep up the good work!

Let’s pretend that WordPress is a Mexican restaurant and we have ordered a taco as illustrated by the following code…

<?php $taco = 'chicken'; ?>

Hat tip to Philip for finding this little two-year old treasure in the forums. If you’re interested in a very detailed article about the internals of actions and filters, check out Gennady’s post called Inside WordPress Actions and Filters.

Has anyone else stumbled across interesting ways of describing WordPress functions and APIs? Feel free to share your links!

Don’t Be Shy to Use sprintf with WordPress

Don’t be shy to use the printf and sprintf functions with WordPress. It makes code much easier to read. Take a look at the following examples.

echo '<a href="' . get_permalink() . '" class="link">' . get_the_title() . '</a>';

It looks quite dirty and it’s very easy to miss a quote or double-quote. Here’s one that looks a lot cleaner and easier to read:

printf( '<a href="%s" class="link">%s</a>', get_permalink(), get_the_title() );

And here’s a slightly less clean, but more secure example:

printf( '<a href="%s" class="link">%s</a>', esc_url( get_permalink() ), esc_html( get_the_title() ) );

You might think escaping the permalink and the post title is not necessary, and you’re right. However, it’s considered best practice to escape as late as possible, which is often right before the output. Here’s a more complex example, taken from the Twenty Twelve theme:

$date = sprintf( '<a href="%1$s" title="%2$s" rel="bookmark"><time class="entry-date" datetime="%3$s" pubdate>%4$s</time></a>',
    esc_url( get_permalink() ),
    esc_attr( get_the_time() ),
    esc_attr( get_the_date( 'c' ) ),
    esc_html( get_the_date() )

It also makes use of argument swapping, which is very common when working with translation functions, mainly because RTL languages would need to swap things around. It’s also very convenient to read when there are two or more placeholders.

You can learn more about sprintf (with a bunch of cool examples) in this article, and about escaping and data validation right here.

Thanks for reading and have a great day!

Github’s Asking for my Password

“Why is Github asking me to input my username and password when I try to push changes to a repository I own?” I asked this myself a couple of times before I figured out I had cloned it the wrong way:

git clone https://github.com/kovshenin/publish.git .

As opposed to:

git clone git@github.com:kovshenin/publish.git .

Where the former will use the HTTP protocol, and thus require basic authentication (username and password), and the latter will use the SSH protocol, and will try to use my SSH key instead, for password-less authentication. The former will work, but you’ll have to keep entering your username and password every time. The latter is more secure.

Simple, but tricky. No, I don’t use a GUI for version control, and neither should you, trust me :)