Dynamic page titles in WordPress using title_tag

This article is a follow on from Dynamic page titles in WordPress, where we used wp_title in order to display custom page titles. Since title_tag was introduced in WordPress 4.1, it is now best practice to use this instead of wp_title, which will at some stage be deprecated.

We’ll look at removing wp_title from page titles (through the header’s title tag), and also through dynamically created page titles (for example in h1 / h2 tags on your page).

Adding theme support for title tags

The first step to removing wp_title from the title tag in your WordPress header is by adding theme support in your functions.php file, and then removing the title tag from your header as it is automatically generated. You may also want to add your original custom title code as a fall-back in case the theme you are using does not support title_tag. Here is an example of what the code in your functions.php file should look like:

add_action( 'after_setup_theme', 'yourtheme_setup' );

function yourtheme_setup() {
  add_theme_support( 'title-tag' );
}

/* The below code is a fall-back incase your theme does not support title_tag */
if ( ! function_exists( '_wp_render_title_tag' ) ) :

   function yourtheme_render_title() {
   ?>

   <title>
   // add the original code between your title tags here
   </title>
   <?php
   }
   add_action( 'wp_head', 'yourtheme_render_title' );

endif;

The result you will see will depend on other plugins you are using that also modify the title tag, for example the Yoast SEO plugin. I’ll look at a solution both without plugins, and with Yoast SEO activated.

Customising dynamic titles without Yoast SEO installed

With Yoast SEO not activated, we need to create a custom function (custom_theme_titles) in functions.php. In it, we need to modify the title output by modifying document_title_parts through a filter. In the below example I am modifying the ‘title’ and ‘site’, both parameters within document_title_parts. In order to get the information I need, I am using get_bloginfo() to retrieve the site description and name. In the case of category pages I’m using get_the_category() to retrieve the relevant category, and then pulling out the name as a string with cat_name. I’ve unset $titleparts[‘site’] as leaving it set added my site title to the end of the title, which I didn’t want.

The result of the below code is a page title of ‘Page Name | Sitename – Tagline’ (and just ‘Sitename – Tagline’ on the front-page) that dynamically fills the title tag on every page (including a custom 404 page title, and custom category page titles).

function custom_theme_titles( $titleparts ) {
   if ( is_front_page() ) {
    	$pagetitle = $titleparts['title'];  
        $titleparts['title'] = $pagetitle;
        unset( $titleparts['site'] );
    }
    elseif ( is_404() ) {
    	$pagetitle = "404";
    	$sep = " | ";
        $name = get_bloginfo( 'name', 'display' );
        $sep2 = " - ";
        $desc = get_bloginfo( 'description', 'display' );
        $titleparts['title'] = $pagetitle.$sep.$name.$sep2.$desc;
        unset( $titleparts['site'] );
    }
    elseif (is_category() ) {	
		$category = get_the_category();
		$catName = $category[0]->cat_name;		
		$pagetitle = "Blog - ".$catName." archives";		
    	$sep = " | ";
        $name = get_bloginfo( 'name', 'display' );
        $sep2 = " - ";
        $desc = get_bloginfo( 'description', 'display' );
        $titleparts['title'] = $pagetitle.$sep.$name.$sep2.$desc;
        unset( $titleparts['site'] );
    }   
    else {
  		$pagetitle = $titleparts['title'];
        $sep = " | ";
        $name = get_bloginfo( 'name', 'display' );
        $sep2 = " - ";
        $desc = get_bloginfo( 'description', 'display' );
        $titleparts['title'] = $pagetitle.$sep.$name.$sep2.$desc;
        unset( $titleparts['site'] );   
    }

    return $titleparts;
}
add_filter( 'document_title_parts', 'custom_theme_titles', PHP_INT_MAX );

Customising dynamic titles with Yoast SEO installed

The code snippet to modify titles when Yoast SEO is installed seems a lot simpler, as they have their own filter for the title – wpseo_title. The first step is to define a function that is later passed through the wpseo_filter. First, we set a few variables – a separator, the site name and the site tagline/description. We can then modify the output for different pages, for example returning just the page title (in the default format of ‘Sitename – Tagline’) on the front page (not adding this may result in a duplicate title), custom page title format throughout the site, and also custom individual pages such as a 404 page.

function custom_theme_titles_yoast( $title ) {
    $sep = '|';
    $name = get_bloginfo( 'name' );
    $desc = get_bloginfo( 'description', 'display' );

    if( is_front_page() ) {
        $pagetitle = $title;
        return "{$pagetitle}";
    }
     elseif( is_404() ) {
        $pagetitle = "404";
        return "{$pagetitle} {$sep} {$name} - {$desc}"; 
    }
    else {
        $pagetitle = $title;   
        return "{$pagetitle} {$sep} {$name} - {$desc}";
    }
}
add_filter( 'wpseo_title', 'custom_theme_titles_yoast', PHP_INT_MAX );

If you change the SEO title on any individual page through the Yoast SEO box in the page/post editor, this will alter the title in the title tag for that page (specifically, it will only alter the $title variable in the above code snippet).

Custom on-page titles

Displaying page titles on pages is not too dissimilar to the process shown in the previous article on dynamic page titles, but with a slight change for the wp_title() calls, to use get_the_title() instead. Get_the_title doesn’t work for archive pages as by default it pulls the title of the first post as the page title, so you’ll need separate if statements to cover any archive pages you might use. This code would then go within your header.php file, or wherever you are dynamically adding on-page titles.

<div class="page-title">
			
   <h1> 
	<?php
	if (is_search()) {
		echo "Blog";
	}
	elseif (is_404()) {
		echo "404";
	}
	elseif (is_category()) {
		$category = get_the_category();
		$catName = $category[0]->cat_name;
		$archive_name = "- ".$catName." archives";
		echo "Blog ".$archive_name;
	}
	else {
		echo get_the_title();
	} 
	?>
			 	
   </h1>

</div>

The result should be clean, custom dynamic page titles on your WordPress site, regardless of whether you have Yoast SEO activated or not.

By Karen Attfield

Happiness Engineer

1 comment

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.