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 “headline style”, and incorrectly as “initial caps” or “init caps”. 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. The first and last words in the title are always capitalized.
This plugin 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 the word 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”, should be all 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 PHP’s 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 fancy WordPress 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
This is what the code looks like. It should be pretty easy to follow what’s happening.
<?php function ardamis_titlecase($title) { $title = preg_replace("/“/", '“ ', $title); // find double quotes and add a space behind each instance $title = preg_replace("/‘/", '‘ ', $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("/“ /", '“', $title); // remove the space behind double quotes $title = preg_replace("/‘ /", '‘', $title); // remove the space behind single quotes return $title; } add_filter('wp_title', 'ardamis_titlecase'); add_filter('the_title', 'ardamis_titlecase'); ?>
Download
Download the plugin, upload it to your site, and activate it.
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("/^“/", $word)) $words[$key] = '“' . ucwords(substr($word, 7)); elseif (preg_match("/^‘/", $word)) $words[$key] = '‘' . 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.
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!
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.
Great, thank you ardamis!
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.
Yes, the plugin will correctly capitalize only the first letter of a contraction.
Pingback: links for 2007-10-09
You can do the same thing in your style sheet with text-transform:uppercase;
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.
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?
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.
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.
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.
Thanks!
In case this isn’t a possibility for someone, I did this using CSS with, say:
Then, when you author, remember to wrap what you don’t want uppercased:
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.
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.
Does this plug-in work with WordPress 2.7?
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.
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!
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.
Thanks for the help
Hello, can you make this plugin work for description too? thanks
Pingback: Automatically Title Case WordPress Post Title - Software Download and Review
Pingback: Customizing the Title Case Plugin | Editing Wordpress
Thanks. Your plugin is very helpful.
Great plugin. Thanks for making it. I use it on a bunch of my websites.
Are you ever going to update this plugin? Just asking…