Getting the bloginfo correctly

A previous version of this site ran on an WordPress MS install.

As with most WordPress sites we use plugins to enhance WordPress, including Donncha O Caoimh‘s excellent WordPress MU Domain Mapping plugin. As the name implies, the domain mapping plugin allows us to use top level domains for each site rather than being stuck with sub-domains.

Taking care with plugins

Many plugins are tested for the single site version of WordPress only. I don’t have a problem with this as most plugins are released under the GPL and free in terms of both speech and beer. If I’m not paying for software, it’s up to me to test it in the fringe environment of WordPress MS.

Now that WordPress is WordPress MS is WordPress, more developers may test in both environments but they certainly can’t be expected to test with all manner of combinations of plugins.

The standout problem

One of the standout problems when using plugins with WordPress MS is when they define a constant for the plugin’s url as the script starts executing, the PHP code may look similar to:

<?php

  define('PLUGIN_DIR', get_bloginfo('url') . "/wp-content/plugins/peters-plugin");

  function plugin_js_css(){
    wp_enqueue_script('plugin-js', PLUGIN_DIR . '/script.js');
    wp_enqueue_style('plugin-css', PLUGIN_DIR . '/style.css');
  }

  add_action('init', 'plugin_js_css');

?>

The above stands equally for themes mapping the stylesheet directory at the start of execution:

<?php

  define('THEME_DIR', get_bloginfo('stylesheet_directory') );

  function theme_js_css(){
    wp_enqueue_script('theme-js', THEME_DIR . '/script.js');
    wp_enqueue_style('theme-css', THEME_DIR . '/style.css');
  }

  add_action('init', 'theme_js_css');

?>

The get_bloginfo and bloginfo functions return information about your blog and your theme settings including the site’s home page, the theme’s directory (as in the second code sample above) or the stylesheet url. bloginfo outputs the requested information to your HTML, get_bloginfo returns it for use in your PHP.

Outside of code samples, bloginfo and get_bloginfo are interchangeable throughout this article.

The problems occur when a subsequently loaded plugin needs to change something retrieved from bloginfo. In this site’s case, Domain Mapping changes all URLs obtained through bloginfo, but it could be a plugin that simply changes the stylesheet url to a subdomain to speed up page load.

In a recent case, a plugin – let’s call it Disqus – was defining a constant in this manner. As result an XSS error was occurring when attempting to use Facebook Connect. Replacing the constant with a bloginfo call fixed the problem.

The improved code for the first sample above is:

<?php

  function plugin_js_css(){
    wp_enqueue_script('plugin-js', get_bloginfo('url') . '/wp-content/plugins/peters-plugin/script.js');
    wp_enqueue_style('plugin-css', Pget_bloginfo('url') . '/wp-content/plugins/peters-plugin/style.css');
  }

  add_action('init', 'plugin_js_css');

?>

bloginfo doesn’t hit the database everytime

I presume the developers set their own constants because they’d like to avoid hitting the database repeatedly to receive the same information.

Having run some tests on my local install of WordPress, I can assure you this is not the case. Running bloginfo('stylesheet_directory') triggers a db call on the first occurrence, the information is then cached for subsequent calls.

I realise I sound incredibly fussy and that I’m suggesting we protect against edge cases on our edge cases. You’re right, and it’s not the first time, but as developers it’s the edge cases that we’re employed to avoid.