A WordPress Plugin for Title Case Capitalization

I’ve written a WordPress plugin that will convert the page title and post title to ‘title case’ capitalization. Title case is also often referred to as “initial caps”, “init caps”, or “headline style”. Title case means that the first letter of each word is capitalized, except for certain small words, such as articles, coordinating conjunctions, and short prepositions.

This may be useful if you’re trying to give the titles on your site a consistent appearance, but it’s no substitute for writing a good title. There are way too many exceptions and rules to make a simple script behave correctly all of the time.

The plugin is smart enough to not capitalize the following:

  • Coordinating conjunctions (and, but, or, nor, for)
  • Prepositions of four or fewer letters (with, to, for, at, and so on) (limited)
  • Articles (a, an, the) unless the article is the first word in the title

But the plugin isn’t perfect. It won’t capitalize an article that is the last word in the title. It fails on subordinating conjunctions. It conservatively de-capitalizes only some of the prepositions, hopefully reducing the chance of incorrect behavior. For example, it leaves ‘over’ caps, because ‘over’ can be an adverb, an adjective, a noun, or a verb (caps) or a preposition (not caps), and determining how a word is being used in a title is really beyond the scope of a humble plugin.

The plugin requires you to edit it for certain product names, like ‘iPod’, and cool-people names, like “Olivia d’Abo” or “Jimmy McNulty”. It’s not savvy enough to know that acronyms, like ‘HTML’, are caps unless they’re used in particular ways, such as in the case of “Using the .html Suffix”, unless you tell it. That said, editing the plugin for these particular words is very easy.

Even with all these limitations, it beats using CSS to {text-transform: capitalize} the titles or just applying ucwords() to the entire thing. But I’m guessing that dissatisfaction with one or both of those two methods is what brought you to this page in the first place.

On the upside, it capitalizes any word following a semicolon or a colon, e.g.: “Apollo: A Retrospective Analysis”. It also capitalizes any word immediately preceded by a double or single quote, but only if you haven’t bypassed WordPress’s fancy quotes feature.

How it works

The plugin first finds all words that begin with a double or single quote and adds a space behind the quote. It capitalizes all of the words in the title with ucwords, then selectively de-capitalizes some of the words using preg_replace. It then uses str_ireplace, a case-insensitive string replace function, to correct the odd capitalization of certain other words. Finally, it removes the spaces behind the quotes.

The code

<?php

function ardamis_titlecase($title) {
		$title = preg_replace("/&#8220;/", '&#8220; ', $title); // find double quotes and add a space behind each instance
 		$title = preg_replace("/&#8216;/", '&#8216; ', $title); // find single quotes and add a space behind each instance
		$title = preg_replace("/(?<=(?<!:|;)\W)(A|An|And|At|But|By|Else|For|From|If|In|Into|Nor|Of|On|Or|The|To|With)(?=\W)/e", 
'strtolower("$1")', ucwords($title));  // de-capitalize certain words unless they follow a colon or semicolon
		$specialwords = array("iPod", "iMovie", "iTunes", "iPhone", " HTML", ".html", " PHP", ".php"); // form a list of specially treated words
		$title = str_ireplace($specialwords, $specialwords, $title); // replace the specially treated words
		$title = preg_replace("/&#8220; /", '&#8220;', $title); // remove the space behind double quotes
		$title = preg_replace("/&#8216; /", '&#8216;', $title); // remove the space behind single quotes

		return $title;
}

add_filter('wp_title', 'ardamis_titlecase');
add_filter('the_title', 'ardamis_titlecase');

?>

Download

Download the Title Case Capitalization WordPress plugin

Further customization

The plugin won’t alter words written in all caps or CamelCase. You could use ucwords(strtolower($title)) to convert the entire $title to lowercase before applying ‘ucwords’. This may fix instances where someone has typed in a bunch of titles with the caps lock key on. But you’ll then have to compensate for words that should be all caps, like ‘HTML’, ‘NBC’, or ‘WoW’, in $specialwords.

An alternative using a ‘foreach’ loop

It’s possible to do something similar using a foreach loop. This isn’t as graceful, in my opinion, but I suppose it’s possible that someone may find it works better.

<?php

function ardamis_titlecase($title) {
	$donotcap = array('a','an','and','at','but','by','else','for','from','if','in','into','nor','of','on','or','the','to','with'); 
	// Split the string into separate words 
	$words = explode(' ', $title); 
	foreach ($words as $key => $word) { 
		// Capitalize all but the $donotcap words and the first word in the title
		if ($key == 0 || !in_array($word, $donotcap)) $words[$key] = ucwords($word); 
		if (preg_match("/^&#8220;/", $word))
			$words[$key] = '&#8220;' . ucwords(substr($word, 7));
		elseif (preg_match("/^&#8216;/", $word))
			$words[$key] = '&#8216;' . ucwords(substr($word, 7));
	} 
	// Join the words back into a string 
	$newtitle = implode(' ', $words); 
	return $newtitle; 
}

add_filter('wp_title', 'ardamis_titlecase');
add_filter('the_title', 'ardamis_titlecase');

?>

Credits

Thanks to Chris for insight into the preg_replace code at http://us2.php.net/ucwords. Thanks to Thomas Rutter for insight into the foreach code at SitePoint Blogs » Title Case in PHP.

  • E-mail this story to a friend!
  • Facebook
  • Digg
  • StumbleUpon
  • del.icio.us
  • Google Bookmarks
  • Technorati
  • LinkedIn
  • Reddit
  • MySpace
  • Slashdot
  • SphereIt
  • Sphinn
  • Mixx

23 Responses to “A WordPress Plugin for Title Case Capitalization”

  1. Izahg says:

    Excellent function, but it does not capitalize words between quotes.

    Before: This car is ‘relatively cheap’ compared to others
    After: This Car Is ‘relatively Cheap’ Compared to Others

    Notice that ‘relatively’ stayed the same. Is there a way around that? Thanks!

  2. ardamis says:

    Thanks for pointing out this oversight. I’ve edited the plugin to correct this and edited the post to illustrate how that feature is implemented.

  3. Izahg says:

    Great, thank you ardamis!

  4. Hi,

    Does it handle contractions adequately? I’m so sick of headlines reading “Don’T”, “Won’T”, etc. that I’m about to manually remove the CSS capitalization from our stylesheet.

  5. ardamis says:

    Yes, the plugin will correctly capitalize only the first letter of a contraction.

  6. [...] A WordPress Plugin for Title Case Capitalization I wish it handled phrasal verbs, but you can’t get everything. (tags: Blog PHP Programming) [...]

  7. You can do the same thing in your style sheet with text-transform:uppercase;

  8. ardamis says:

    Actually, CSS is rather limited when it comes to capitalization.

    Suppose our heading is:

    A Plugin for the Masses

    This plugin will keep (or create) that capitalization by allowing certain small words to stay lowercase. CSS cannot do this; it’s an all or nothing situation. For example, CSS { text-transform: capitalize; } would capitalize every word, generating:

    A Plugin For The Masses

    while CSS { text-transform: uppercase; } would generate:

    A PLUGIN FOR THE MASSES

    This plugin is for people who care about capitalization enough to realize CSS isn’t capable of producing the desired results.

  9. clifton says:

    Hi, Ardamis. I dropped your plugin into the appropriate directory on my server and then tried to view my site again. After doing so, I found the following message had replaced my site: “Fatal error: Call to undefined function: str_ireplace() in /home/methaner/public_html/sicmagazine/wp-content/plugins/ardamis-titlecase.php on line 36″

    Well, I deactivated the plugin and the site returned to a working state.

    My question: am I retarded?

    Next question: do I need to paste code into some file in addition to installing/activating your plug-in?

    All I really want is to have control over how titles are displayed on my page. Is this really asking so much?

  10. ardamis says:

    You’re getting that error because your server isn’t using PHP5, and str_ireplace() is a PHP5 function. The best solution would be to ask your host to update PHP, but I’ll try to put together a version of the plugin for those people using PHP4 in the next few days.

  11. Oxonian says:

    Thanks for creating this plugin. Could you please indicate how to tweak the code so that the plugin will alter words written in all caps? I tried inserting the ‘ucwords(strtolower($title))’ command in various places, but I don’t know php and I couldn’t get the tweaked plugin to work.

  12. ardamis says:

    Oxonian, edit the plugin to replace

    ucwords($title)

    with

    ucwords(strtolower($title))

    Note the additional end parenthesis. When you make this change to the plugin, you’ll end up with 3 end parenthesis after $title.

    This will convert all words to lowercase, then apply the capitalization.

  13. Oxonian says:

    Thanks!

  14. Ray says:

    In case this isn’t a possibility for someone, I did this using CSS with, say:

    
    h2{
      text-transform: uppercase;
    }
    
    .lower{
      text-transform: lowercase !important;
    }
    

    Then, when you author, remember to wrap what you don’t want uppercased:

    
     <h2>A plugin <span class="lower">for the</span> masses</h2>
    

  15. burak says:

    thanks for the useful plugin. I need to capitalize whole the words in the title. How should I change the code? Thank you very much.

  16. ardamis says:

    If only a few words need special capitalization, just add them to the $specialwords array exactly as they should appear in the title (ALL CAPS, camelCase, etc.), and they won’t be changed by the plugin.

  17. Does this plug-in work with Wordpress 2.7?

  18. ardamis says:

    Yes, it works in WordPress 2.7. It would take some really serious changes to WordPress to break this plugin, so it should be safe for many revisions to come.

  19. Thanks for the plugin ardamis, but I’m having the same problem Clifton had with this error message: “Fatal error: Call to undefined function: str_ireplace() in /home/methaner/public_html/sicmagazine/wp-content/plugins/ardamis-titlecase.php on line 36″

    I double checked that my my server is on PHP5 and it is – PHP5.2.8 to be exact. Got any idea what’s up?
    Thanks!

  20. ardamis says:

    If you’re getting an error message “Call to undefined function: str_ireplace()”, leave a comment and I’ll email you a version of the plugin that uses a neat replacement function from PEAR’s PHP_Compat package.

  21. Duncan says:

    Hello, can you make this plugin work for description too? thanks

  22. [...] in WordPress plugin database, fortunately, they already had a nice plugin called Title Case and Title Case Capitalization plugins. Once activated, both plugins will automatically filter post titles as they are output and [...]

Leave a Reply

Wrap code snippets in <code></code> tags.