Single-Letter Posts? A Confluence of Mistakes

There is a rare problem that shows up with some WordPress themes. Switch to them and, suddenly, every post shows up as just the first letter. And the fun part is that, with some of the themes, it only happens to some sites. Everyone else is fine, but you get single-letter posts.

ffdigital asked about it in a WordPress support forum a few months ago. Simba ran into it with the theme “Cellar Heat” and asked about it on the theme’s site. When Smashing Magazine released “Smashing Theme”, the problem came up. None of these discussions produced a solution.

The problem arises when a theme names a variable $pages. WordPress itself uses this same variable name in a global context, and it gets confused if the theme stomps the value. With some themes, only certain sites would stomp the variable, so only those would have problems. With “Cellar Heat”, for example, everything is fine if you only have posts, but no pages. Add a page and everything drops to one letter. Get rid of it and everything comes back. It’s a WordPress magic trick.

The problem was again discussed at eXtra For Every Publisher and finally a fix was proposed. The proposed solution was fairly straight-forward. Look in your theme files and find wherever $pages is used and unset the variable after the theme is done with it. Its simple and works, but somewhat misses the point.

The real mistake is that the theme developers are using the name $pages in the first place! Theme designers know not to use $post, but they need to avoid all of the WordPress global variables.

Now to be fair to the designers, it would be easier to avoid WordPress’s global variables if:

  • there was a comprehensive list of them;
  • they had better naming conventions; and/or
  • there were fewer of them.

I hate to pick on WordPress for documentation, as their developer docs are pretty damn good, but a simple rundown of the variables is sorely needed.

The naming convention issue is a historical one. Namespaces are a relatively recent addition to PHP and, in the absence of namespaces, the WordPress team did not establish a prefix-based naming system for their globals as they added them. Had they done so, collisions would be less of an issue, as few developers would accidentally choose, say, $wp_global_loop_pages. Unfortunately, this problem is not easily resolved due to the many hundreds of themes and plugins that rely on the existing names.

The proliferation of global variables (there are over 100!) is an issue for another post all its own.

There is actually one last twist to this story. The post truncation problem depends on a small bug in WordPress when post-specific globals are being set in “the loop.” The call to the_post should initialize all post/page specific globals to sane values. In the case of posts that are not subdivided into subpages, the variable $pages is not initialized properly. WordPress assumes that $pages is an array and just sets the zeroth element to be the content of the post. If $pages is a string instead of an array, you get single-character posts.

So, the single-letter posts really happen because

  1. theme developers use the name $pages which collides with a WordPress loop variable
  2. and they don’t clean up (i.e. unset) after they are done,
  3. both of which they probably could have avoided if there were a canonical list of reserved variables,
  4. or if those reserved variables has less generic names,
  5. and all of this is only a problem because WordPress fails to properly initialize one of those variables in the loop.

At least it is a complicated bug.

Related Posts

Leave a Reply

HostMonster for Great Unlimited Web Hosting Hundreds of template and themes from $35