Math Jazz — Mathias Bynens’s shizzle, y’all



Note: This site might seem inactive… That’s because it is. Don’t worry though, I’m still coding webpages and stuff! If you’re interested, I suggest you get a translator and head over to Qiwi; or you could just check the latest site we’ve been working on: Apotheek Goethals – Debrabandere. Enjoy!

WordPress: How to enable HTML in post titles

WordPress doesn’t allow you to embed HTML in your posts’s titles. In fact, this is not a WordPress problem, it’s more a lack of usability in Kubrick, the default WP theme. So, unless you’re following Anne’s A header should not be a link, stupid! logic, there is no way to embed code in your posts’s titles without breaking the title attributes of a certain amount of links, thus making your pages invalid.

See the big header above this text? Notice those small dots under HTML? That’s right — this post’s title contains an acronym element. Now, hover your mouse over the header, and check the tooltip that shows up. Indeed, I don’t want no <a href="/blah/foo" title="Permanent link: How to enable <acronym title="HyperText Markup Language">HTML</acronym> in post titles">link</a>–evil to happen to you, my dear visitor.

Can we get to the point or what?

Here’s an excerpt from the current Kubrick index.php template file.

  <?php while (have_posts()) : the_post(); ?>
    
   <div class="post" id="post-<?php the_ID(); ?>">
    <h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"><?php the_title(); ?></a></h2>
    <small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small>
    
    <div class="entry">
     <?php the_content('Read the rest of this entry &raquo;'); ?>
    </div>
  
    <p class="postmetadata">Posted in <?php the_category(', ') ?> <strong>|</strong> <?php edit_post_link('Edit','','<strong>|</strong>'); ?>  <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?></p>
   </div>
 
  <?php endwhile; ?>

Obviously, this code displays the posts that match the queries specified by the user. We can enable HTML in post titles by replacing this with something among the lines of the following:

  <?php
  while (have_posts()) : the_post();
  $mj_title = get_the_title();
  $mj_title_stripped = strip_tags($mj_title);
  ?>

   <div class="post" id="post-<?php the_ID(); ?>">
    <h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php echo $mj_title_stripped; ?>"><?php echo $mj_title; ?></a></h2>
    <small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small>

    <div class="entry">
     <?php the_content('Read the rest of this entry &raquo;'); ?>
    </div>

    <p class="postmetadata">Posted in <?php the_category(', ') ?> <strong>|</strong> <?php edit_post_link('Edit','','<strong>|</strong>'); ?>  <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?></p>
   </div>

  <?php endwhile; ?>

Note how we avoid to use the the_title() function, by echoing the appropriate variable instead. That way, we gain much more control over how post titles are displayed depending on their context.

Note: You might have to make similar changes to your other post templates as well, ’cause right now only pages displayed using the index.php template won’t be messed up. :) Here are the files that should be edited when you’re using the default theme: archive.php, search.php, single.php, and of course index.php)

I hope this helps you, Frenzie, and I certainly hope this article is of use for other people as well.

Filed under PHP, XHTML, WordPress · May 15th, 2005

Comments (16)

Listed below are the responses for this entry.

  1. Frenzie:
    This commenter’s Gravatar

    Well, you spared me some time as I would have written a tag-stripper myself (true, little work, but still.) :)

    Comment posted on May 15th, 2005 @ 2:06 pm
  2. Frenzie:
    This commenter’s Gravatar

    To which I should add, I was more thinking like the_title('stripped').

    Comment posted on May 15th, 2005 @ 4:31 pm
  3. Mathias:
    This commenter’s Gravatar

    To which I should add, I was more thinking like the_title('stripped').

    Frenzie, that’s the way to go for the WordPress dev team if you ask me. Something like replacing the current the_title() function in wp-includes/template-functions-post.php with this one:

    function the_title($before = '', $after = '', $echo = true, $strip = false) {
     $title = get_the_title();
     if ( strlen($title) > 0 ) {
      $title = apply_filters(’the_title’, $before . $title . $after, $before, $after);
      if ($strip)
       $title = strip_tags($title);
      if ($echo)
       echo $title;
      else
       return $title;
     }
    }

    You could then use the_title('', '', true, true); to echo the stripped version of the post title.

    Following up on that recent link of yours, I think I’ll file this as a WP bug. Something like this should definitely be built-in supported by WordPress.

    Comment posted on May 15th, 2005 @ 4:52 pm
  4. Anne:
    This commenter’s Gravatar

    Still, using ACRONYM for HTML seems totally backwards and you might have better not marked it up at all. I’m also wondering what this has to do with the header should not be a link logic.

    The problem is mostly the TITLE element I guess. That’s why I’m storing two fields at the moment. One that is parsed everywhere as if it was application/xml (in the backend) and one that is parsed everywhere as if it was text/plain (again, in the backend).

    Comment posted on May 15th, 2005 @ 6:55 pm
  5. Oliver:
    This commenter’s Gravatar

    Wow nice trick. I’ve never had to have HTML tags in header links. I’ve never used the title for links. If it’s all going to be the same information, why bother have a title for a header link? Nice little trick though.

    Comment posted on May 15th, 2005 @ 8:21 pm
  6. Mathias:
    This commenter’s Gravatar

    Still, using ACRONYM for HTML seems totally backwards and you might have better not marked it up at all.

    Anne, nah. I in fact used to use ABBR exclusively, but I later allowed ACRONYM elements too, becaus of the distinction between abbreviations and acronyms.

    I’m also wondering what this has to do with the header should not be a link logic.

    Hmmm… Good point. Now that I come to think of it, this hasn’t got much to do with that. I must’ve been thinking post titles ? H2s ? links ? title attributes, but of course a link like <a href="/foo/bar">Permalink</a> could just as well have a title attribute with the post title embedded. Stupid.

    I’ve never used the title for links. If it’s all going to be the same information, why bother have a title for a header link?

    Very good point. However, this is not just a case of asking yourself why — the default WordPress theme is doing this, so the fact is thousands of sites are too! Everybody can choose not to use the title attribute for certain links (i.e. tweaking the WP template files a bit), but as long as it’s hardcoded, a lot of people won’t.

    Comment posted on May 16th, 2005 @ 9:07 am
  7. Frenzie:
    This commenter’s Gravatar

    Mathias, I just noticed wp_title, which seems to do the same thing. Makes me wonder if they shouldn’t work towards a more unified function for this stuff (expanding a bit on either one)… but as you are more familiar with the WordPress code and the bug system I leave that all to you. :)

    Comment posted on May 16th, 2005 @ 1:18 pm
  8. Mathias:
    This commenter’s Gravatar

    Mathias, I just noticed wp_title, which seems to do the same thing.

    I’m afraid that’s incorrect, Frenzie. Though the page on the codex states This tag can be used anywhere within a template, though is typically used in the <title> tag (sic) for the head of a Page, wp_title() doesn’t work inside The Loop. (On the main page, for example, it won’t return anything when used in the post loop.)

    Makes me wonder if they shouldn’t work towards a more unified function for this stuff (expanding a bit on either one)…

    I would agree, if the wp_title() function indeed worked inside The Loop, which it doesn’t. Now, I think it’s better to keep ‘em two functions separated: one for the TITLE element of a WP page, and another one for the post titles. These two purposes are just too different IMO.

    Comment posted on May 16th, 2005 @ 3:22 pm
  9. Frenzie:
    This commenter’s Gravatar

    No more or less different than for the post title and the title attribute in a link…

    Comment posted on May 16th, 2005 @ 10:40 pm
  10. Frenzie:
    This commenter’s Gravatar

    Checking my code, I noticed at least one further addition to your code was required (which amplifies the need for changes to the function handling this all).

    $title_stripped = str_replace('"', '&#34;', $title_stripped);

    Comment posted on May 18th, 2005 @ 10:10 am
  11. Kris:
    This commenter’s Gravatar

    Nice article. I just got in the problem as well as you can see. In this example it seems that WP adapts EM with htmlentities(). Anyway, strip the output of these nasty TITLE attributes!

    Comment posted on May 18th, 2005 @ 1:38 pm
  12. Mathias:
    This commenter’s Gravatar

    Checking my code, I noticed at least one further addition to your code was required (which amplifies the need for changes to the function handling this all).

    $title_stripped = str_replace('"', '&#34;', $title_stripped);

    In this case, required is a big word, since normally WordPress runs post titles through the wptexturize() filter at all times. (So, there will never be double quotes left in it after this process.) Because add_filter('single_post_title', 'wptexturize'); is hardcoded into WordPress (see wp-includes/default-filters.php), I could understand how the development team wouldn’t directly see this as an issue. Still, I think your addition is very welcome, and should be implemented.

    Comment posted on May 22nd, 2005 @ 5:42 pm
  13. Michael Heilemann:
    This commenter’s Gravatar

    Sorry, I skipped through most of this, not to be rude, but because I’m really tired from reboot7 and I’m about to go to bed :)

    Anyhoo, have you heard from the devs yet? Is anyone doing anything?

    (I’m subscribed by mail.)

    Comment posted on June 12th, 2005 @ 12:54 am
  14. Mathias:
    This commenter’s Gravatar

    I filed a bug ticket with a patch attached and all, but the devs don’t seem to notice. Perhaps you can hint Matt on this when you wake up? (I’d do that myself, but I’m quite sure you have much more influence than I do.)

    Comment posted on June 13th, 2005 @ 2:02 pm
  15. Bennett:
    This commenter’s Gravatar

    Great discussion. I hit this problem a couple of months ago when I started using WordPress. Initially I solved it by writing a simple template tag and using it in my theme. But I didn’t like having to edit the theme, so I wrote a plugin to do it all automatically. The trick is to use a filter, and buffer the output so the filter can tell where it is in the document and whether it needs to strip the tags.

    I suppose this is far too clunky for general use, yet it’s very instructive. The plugin and the details are on my site at Safe Title: a WordPress plugin.

    Comment posted on June 17th, 2005 @ 9:01 am
  16. Mathias:
    This commenter’s Gravatar

    Nice plugin, Bennett. However, as I wrote in my comments on your site, output buffering swallows, especially in combination with preg_match() and friends. Pretty heavy stuff for such little details as HTML inside a TITLE attribute :) Sledgehammer vs. peanut, as you put it.

    What I’m saying is, please, WordPress dev team, consider applying my friggin’ patch.

    Comment posted on June 17th, 2005 @ 2:04 pm

Trackbacks & Pingbacks (1)

Listed below are resources on the web that mention this article.

  1. Semicolon: Safe Title: a WordPress plugin:
    This commenter’s Gravatar

    Safe Title: a WordPress plugin
    Here’s an amusing hack to fix a niggling problem in the WordPress default theme. I came up with this soon after I started using WordPress, but I recently noticed that this small annoyance had generated a discussion on mathibus.com. My fully automatic solution is now ready for a waiting world.

    Trackback made on June 17th, 2005 @ 8:53 am