Dynamically Replace <title> after WordPress/Theme/Plugins generate <head>?

OK I have been doing lots of digging and trying to come up with the best solution and really would like some insight and help on this issue.

The problem: I have a WordPress/Theme/Plugin combo set for my site that works great. Between WordPress, the Theme, and plugins such as SEO plugins, there is LOTS of things going on in the title generation for the site.

Read More

I have a template page that I want to be able to change the title on dynamically. I don’t want to mess with the whole site, just this template page so it will display :dynamic item name +” Item Details” for the titles . I would like to possibly also replace the meta description as well, but I should be able to use the same method as the title so let’s focus on for now.

Example Page: http://www.ddmsrealm.com/dungeons-and-dragons-database/item-info/?ddoRareItemID=2507&ddoQuestID=352&ddoSeriesID=39 – This has a generic page title.

There is a function in the template page that gets and builds the header. After this is where I would probably need to put in code to replace the tag in the already generated .

So the question is how to change it?

Can you replace a generated tag with just PHP after the ? Could this be done with a function? This change is for SEO so I do not think a Javascript will work due to search engines not executing JavaScript. Would custom fields be the solution?

I want to affect just this template. I need it for SEO. And I don’t think I can do this at the Theme or Plugin level since I just want to modify this one page, the rest generate just fine.

Thanks a ton for your help and insight.

Related posts

Leave a Reply

4 comments

  1. Try to hook into the wp_title filter before you call get_header().

    <?php 
    add_filter( 'wp_title', 'my_tpl_wp_title', 100 );
    function my_tpl_wp_title($title) {
        $title = 'My new cool title';
    
        return $title;
    }
    ?>
    

    Edit:) I see the Yoast plugin did in fact tamper with my solution:)

    Luckily it’s an easy fix. The Yoast wp_title hook has a priority of 15 so simply set a higher number on your wp_title function. See my updated answer.

    Yoast title filter for reference

    add_filter( 'wp_title', array( $this, 'title' ), 15, 3 );
    
  2. If you happen to be using the Yoast SEO plugin like me, this is what ultimately worked for me.

    function change_yoast_page_titles($title)
    {
      global $pagename;
      $new_title=$title;
      if ($pagename=='widget')
      {
        global $widget_name;
        if (isset($widget_name))
            $new_title=$widget_name." | ".get_bloginfo('name'); 
      }
      return $new_title;
    }
    
    add_filter('wpseo_title','change_yoast_page_titles',100);
    

    Credit goes here: Overriding Yoast SEO Plugin Page Title and META Description

  3. Here is the final working code for this question. The above responses were a great help in getting this code very close. Since this was passing the information between pages/scripts a global variable was needed.

    $ddmsrealmitemname = $row_rsMainItemListing['Name'];
    
    add_filter( 'wp_title', 'my_ddmseo_wp_title', 100);
    function my_ddmseo_wp_title($title) {
        global $ddmsrealmitemname;
        $title = "{$ddmsrealmitemname} | Item Details | Dungeons and Dragons Online";
        return $title;
    }
    

    This script now scans the current items that has been selected in the recordset and passes that on over riding the SEO plugin title generation.

    This seemed to work well and was done for SEO reasons but it appears that Google is still not indexing these pages. Regardless, this is a nice little trick to overide default title generation on dynamic page items.

  4. How document title is generated has changed since WordPress v4.4.0. Now wp_get_document_title dictates how title is generated:

    /**
     * Displays title tag with content.
     *
     * @ignore
     * @since 4.1.0
     * @since 4.4.0 Improved title output replaced `wp_title()`.
     * @access private
     */
    function _wp_render_title_tag() {
        if ( ! current_theme_supports( 'title-tag' ) ) {
            return;
        }
    
        echo '<title>' . wp_get_document_title() . '</title>' . "n";
    }
    

    Here is the code from v5.4.2. Here are the filters you can use to manipulate title tag:

    function wp_get_document_title() {
        /**
        * Filters the document title before it is generated.
        *
        * Passing a non-empty value will short-circuit wp_get_document_title(),
        * returning that value instead.
        *
        * @since 4.4.0
        *
        * @param string $title The document title. Default empty string.
        */
        $title = apply_filters( 'pre_get_document_title', '' );
        if ( ! empty( $title ) ) {
            return $title;
        }
        // --- snipped ---
        /**
        * Filters the separator for the document title.
        *
        * @since 4.4.0
        *
        * @param string $sep Document title separator. Default '-'.
        */
        $sep = apply_filters( 'document_title_separator', '-' );
    
        /**
        * Filters the parts of the document title.
        *
        * @since 4.4.0
        *
        * @param array $title {
        *     The document title parts.
        *
        *     @type string $title   Title of the viewed page.
        *     @type string $page    Optional. Page number if paginated.
        *     @type string $tagline Optional. Site description when on home page.
        *     @type string $site    Optional. Site title when not on home page.
        * }
        */
        $title = apply_filters( 'document_title_parts', $title );
        // --- snipped ---
        return $title;
    }
    

    So here are two ways you can do it.

    First one uses pre_get_document_title filter which short-circuits the title generation and hence more performant if you are not going make changes on current title:

    function custom_document_title( $title ) {
        return 'Here is the new title';
    }
    add_filter( 'pre_get_document_title', 'custom_document_title', 10 );
    

    Second way uses document_title_separator and document_title_parts hooks for the title and the title seperator that are executed later in the function, after title is generated using functions like single_term_title or post_type_archive_title depending on the page and about to be outputted:

    // Custom function should return a string
    function custom_seperator( $sep ) {
       return '>';
    }
    add_filter( 'document_title_separator', 'custom_seperator', 10 );
    
    // Custom function should return an array
    function custom_html_title( $title ) {
       return array(
         'title' => 'Custom Title',
         'site'  => 'Custom Site'
        );
    }
    add_filter( 'document_title_parts', 'custom_html_title', 10 );