Better way to display title meta tag

To display title meta tag in WordPress, we can use wp_title function. But it’s not enough if you want your theme SEO friendly. In TwentyTen, TwentyEleven and Underscores (_s) themes, WordPress team has tried to solve the SEO issue by using the following code:

<title>< ?php
/*
 * Print the <title> tag based on what is being viewed.
 */
global $page, $paged;

wp_title( '|', true, 'right' );

// Add the blog name.
bloginfo( 'name' );

// Add the blog description for the home/front page.
$site_description = get_bloginfo( 'description', 'display' );
if ( $site_description && ( is_home() || is_front_page() ) )
    echo " | $site_description";

// Add a page number if necessary:
if ( $paged >= 2 || $page >= 2 )
    echo ' | ' . sprintf( __( 'Page %s', '_s' ), max( $paged, $page ) );

?></title>

What it does is formatting the title tag as:

  • For homepage or front page: Site name – Site description
  • For other pages: Page title – Site name (and maybe) – Paged

It’s ok if we just accept it. But when we go into the code, we’ll see it’s not very good:

  1. Code is long and make header.php file complicated
  2. There’re 2 parts in the code above: one for the current page title, which is echoed by wp_title and one for the site name and description. The not-cool part is this code echoes the additional info (site name and site description) directly
  3. Because of the 2nd reason, it’s hard to make the SEO plugins to re-format title meta tag. I’ve looked into the code of popular SEO plugins such as WordPress Plugin By Yoast and WordPress All-In-One SEO and see both using output buffering to change the page title (Yoast uses in force mode while AIO SEO plugin always does), which may make you out of memory and get “Header sent” error.

So, how to make the code better?

The natural way is using wp_title function , of course. But as I said, it’s not enough. So, we’ll use a filter to change the output of this function.

First step: just use this piece of code in your header.php file:

<title>< ?php wp_title( '|', true, 'right' ); ?></title>

You can change the separator (|), and its location (right). The 2nd parameter allows you to echo (true) the title or not (false). For more documentation, please read here.

Second step: using the wp_title filter. This filter accepts 3 parameters: title, separator and its location. Here’s my code that use the filter:

add_filter( 'wp_title', 'rw_title', 10, 3 );

function rw_title( $title, $sep, $seplocation )
{
    global $page, $paged;

    // Don't affect in feeds.
    if ( is_feed() )
        return $title;

    // Add the blog name
    if ( 'right' == $seplocation )
        $title .= get_bloginfo( 'name' );
    else
        $title = get_bloginfo( 'name' ) . $title;

    // Add the blog description for the home/front page.
    $site_description = get_bloginfo( 'description', 'display' );
    if ( $site_description && ( is_home() || is_front_page() ) )
        $title .= " {$sep} {$site_description}";

    // Add a page number if necessary:
    if ( $paged >= 2 || $page >= 2 )
        $title .= " {$sep} " . sprintf( __( 'Page %s', 'dbt' ), max( $paged, $page ) );

    return $title;
}

You can see most of the code is similar to the code used by TwentyEleven, so it’s not hard to understand. The cool part of this code is that it can handle both left and right position of the separator, e.g. if you write this in header.php, it still works well:

<title>< ?php wp_title( '-', true, 'left' ); ?></title>

(your title format will be Site name – Page title).

This way, you can control your title meta tag for better SEO score, without any plugins!

I highly recommend this method to theme frameworks. It helps not only make the code cleaner, but also allows users to filter the output (using higher priority). That’s the way WordPress users always do!

19 Comments

  1. Thanks for the excellent writeup. I just switched from All in One SEO to Yoast SEO and had to update my theme to the new recommended format to work with the title rewrites.

    Saved me hours of hacking.

    Reply
  2. I’m very new at wordpress, so forgive the dumb question. Where do I put the add-filter code? In the theme-functions php?

    Reply
  3. Hi!
    I would like to ask, if i want to use this tag “” but i don’t want my site name to be appeared behind the title, what should i do? As wordpress codex told me the file path to edit it is at (wp-includes/general-template.php). But i’m not sure which line should i edit. I tried to edit different line, but failed to do so as i’m not good in php reading.

    Reply
      • Hi Rilwis,
        Thank you for prompt reply!
        I have no idea which file that you saying. Can you please tell me clearer? I tried to removed the lines as you told in general-template.php but it doesn’t work. Maybe i have deleted wrong code at a wrong file. Can you please specify the file path and file name as well? Thank you! =)

        Reply
        • No, not in “general-template.php”, but in my code in the post content.

          Please use hook as I explained in the post to change post title, don’t change WordPress core file.

  4. Very nice. And clean! Quick question, I’m using your code example exactly as is above. I have a “blog” category with all of my blogs posts assigned to it and I would like to remove the site title from them. Basically I would like the title tag to just display the post name. I tried a few different things like if (In_category but I couldn’t get it to work. Any ideas?

    Reply
  5. Just a heads up that this conflicts with the RSS feed title resulting in a double name as the title of the RSS feed.

    For example the RSS Feed has a title of MysiteMysite rather than just Mysite

    :)

    Reply

Leave a Reply