WordPress provides a nice little function for displaying the title of the current post: the_title(). This function gets used all over the place: in the site header, at the top of single posts and pages, in the loop, in the footer, etc. It is probably one of the most commonly used functions by theme developers, and sometimes plugin developers, depending on the plugin. What many developers don’t realize, however, is that there is actually a time that this function should not be used for retrieving and showing a post title, and that is in attributes.
I run into snippets like this a lot:
In general this is fine and displays perfectly fine most of the time. The problem is simple: when outputting the title of a post in an attribute, you should always use the_title_attribute(). The reason comes down to escaping.
Let’s look at the source for the two functions.
This one doesn’t show us what we need, since it just calls get_the_title(), so let’s also look at the source for that function:
This function is pretty simple, it retrieves the post object using get_post() and then, after passing it through a filter called the_title, returns $post->post_title.
The important part of this function (to properly illustrate this issue) is the applied filter: apply_filters( ‘the_title’, $title, $id );
This filter can be used by developers to modify the output of the title, perhaps to add extra HTML markup.
This function also uses get_the_title() to retrieve the title of the post, but the final data that is returned is different from the_title(), primarily in that it is escaped. What does this mean? It means that it is safe to use inside of element attributes. It also strips all tags.
Let’s look at an example.
Assume your $post->post_title is this:
When outputted with the_title(), this will remain completely unchanged and will display as:
But when you output this title through the_title_attribute(), you get this:
Notice that the span tags have been removed.
What if your title had quotation marks in it? Such as:
With the_title(), the title will be outputted as:
With the_title_attribute(), the title will be outputted as:
Notice how the quotation marks have been converted to entities?. This is called escaping and it ensures that attributes, such as title=”the title here”, don’t end up getting closed too early.
If we use the_title() inside of an attribute and the title has quotation marks, we will end up with broken markup.
Notice that the title attribute gets closed with the first ” around the word quotation. This results in completely broken markup that might look something like this:
In order to not break the markup, you should always use the_title_attribute() when showing the title of a post inside of an attribute. It’s a very appropriately named function.
The usage of the_title() in attribute tags has actually caused my huge headaches with Easy Digital Downloads. We use the the_title filter to add Schema.org micro data to products, which is excellent because the data is used by search engines to enhance search result entries with product data (price, rating, etc). The problem is that we get at least one support ticket every week from a user that has broken HTML markup (like that pictured above). The problem is prevalent enough that we are being forced to add an option to disable our schema.org micro data.
If you care about better compatibility with plugins, and simply doing the right thing, you should update any theme or plugin that uses the_title() incorrectly. Note, WordPress core itself has a similar problem as well, so it’s not just themes and plugins.