18

Wordpress version 4.5.1

I'm trying to dynamically update page titles on a particular template. After lots of digging and learning about the wp_title() changes, I'm attempting to use document_title_parts. However, I can't get the filter to run at all.

I'm in a child theme, functions.php:

add_theme_support( 'title-tag' );
//add_filter("after_setup_theme", function(){ add_theme_support("title-tag"); });

add_filter( 'document_title_parts', function( $title )
{
    error_log('here');
    return $title;

}, 10, 1 );

I've tried both variations of adding theme support as shown above, but watching my log, nothing appears on page reload. That error_log was working with other functions (such as wp_title), so the error logging is working.

I've also tried pre_get_document_title, which does fire on page load, though I'm unable to get it to actually change the title.

So! I'm either using the filter wrong, didn't set up my theme correctly, or something else I'm unaware of. Any help would be greatly appreciated!

edit to add more detail

Attempting an init function, but that also isn't working: https://gist.github.com/anonymous/6db5af892a4cf4fb029655167d7002a4

Also, while I've removed any reference to <title> from header.php, the actual site title is still showing up in the source.

8
  • Why did you commented out this line //add_filter("after_setup_theme", function(){ add_theme_support("title-tag"); }); ? It is correct use of adding theme support.
    – Sumit
    Commented May 12, 2016 at 6:37
  • @Sumit I tried both the commented out version and the active version. Commented May 12, 2016 at 19:05
  • Maybe try adding add_theme_support() function in an init hook. Another thing is to ensure that you overwrite your header.php file to not have an html <title> tag.
    – Howdy_McGee
    Commented Jun 28, 2016 at 21:56
  • @Howdy_McGee Just tried that, still nothing. gist.github.com/anonymous/6db5af892a4cf4fb029655167d7002a4 Commented Jun 28, 2016 at 22:10
  • @hookedonwinter And you're sure that there's no <title> tags in your header.php? Maybe try replacing 10 with PHP_MAX_INT. Also, the passed parameter is an array instead of a string value.
    – Howdy_McGee
    Commented Jun 28, 2016 at 22:13

4 Answers 4

19
+50

I ran your filter in my development area. It didn't work. Then I switched off the Yoast SEO plugin, which I knew was also messing with the page title. Then it worked. So my suggestion would be another plugin is messing with it.

In the case of Yoast, it was a filter call to pre_get_document_title returning non empty. In that case wp_get_document_title is short circuited and the rest of the function, including the documents_title_parts filter, is not evaluated, as you can see from the first lines of code:

$title = apply_filters( 'pre_get_document_title', '' );
if ( ! empty( $title ) ) {
    return $title;
    }

So, I took your filter and changed the hook to pre_get_document_title. It didn't work. Then I changed the priority to a higher level than the same filter in Yoast. Then it worked. So, I don't know about your set-up, but I suggest you give this a try:

add_filter( 'pre_get_document_title', function( $title )
  {
    error_log('here');
    return $title;
  }, 999, 1 );
3
  • 1
    You got it! I found the same thing, and deactivated Yoast. I just reactivated and used your priority and it worked. THANK YOU! Commented Jul 1, 2016 at 16:55
  • A bit more on hooks here: wordpress.stackexchange.com/questions/109869/…
    – cjbj
    Commented Mar 22, 2017 at 11:23
  • From my site, the pre_get_document_title priority 15 is enough.
    – vee
    Commented Dec 26, 2018 at 7:45
8

After some experimenting I came to the following suggestion: could it be, that the <title> tag is "hard coded" inside your parent theme's header.php? If that is the case, you could try to remove the <title> tag from your child theme's header.php (copy your parent's header.php into your child theme folder) and then add the theme support back through the functions.php:

add_theme_support( 'title-tag' );

I'll try to explain what lead me to this suggestion: I tried as you and others suggested – but it turned out that I found two <title> tags in the source code. The first one had the standard title, the second one the modified title. But (of course) in the browser title bar I could only see the default title.

I then checked the header.php of the parent theme I used (twentyfourteen) and the <title> tag was indeed hard coded inside that template like this:

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

After I removed it, I added the following code to the child theme's functions.php and it worked:

/**
 * Theme support added
 */

function add_theme_support_child() {

    add_theme_support( 'title-tag' );

}

add_action( 'after_setup_theme', 'add_theme_support_child', 11 );


/**
 * Change the title of a page
 * 
 */

function change_title_for_a_template( $title ) {

// Check if current page template is 'template-homepage.php'
// if ( is_page_template( 'template-homepage.php' ) ) {

    // change title parts here
    $title['title'] = 'My Title'; 
    $title['tagline'] = 'My fancy tagline'; // optional
    $title['site'] = 'example.org'; //optional

// }

return $title; 

}

add_filter( 'document_title_parts', 'change_title_for_a_template', 10, 1 );

So it basically also worked before removing the <title> tag from the template – only that there were then two <title> tags of which the later was ignored. Could this be the same problem with your theme?

Since wp 4.4.0 however the <title> tag is created dynamically by the function _wp_render_title_tag() which basically calls another function wp_get_document_title() and wraps the html tags around the result. Long story short: if your theme's header.php is missing the <title> tag, chances are that you can override the title directly through pre_get_document_title or document_title_parts as described here:

1) change the title directly:

add_filter('pre_get_document_title', 'change_the_title');
function change_the_title() {
    return 'The expected title';
}

2) filtering the title parts:

add_filter('document_title_parts', 'filter_title_part');
function filter_title_part($title) {
    return array('a', 'b', 'c');
}
3

Having read your post from top to botom and bottom to top, you have in all probabilty a filter that is passing a title through the pre_get_document_title filter. The clue here the following statement:

I've also tried pre_get_document_title, which does fire on page load,

Looking at the soure code for wp_get_document_title(), we see the following code:

$title = apply_filters( 'pre_get_document_title', '' );
if ( ! empty( $title ) ) {
    return $title;
}

What this means is, whenever a non empty value is passes through the pre_get_document_title filter, the wp_get_document_title() function will return whatever value that was passed via the pre_get_document_title filter. It this case, the document_title_separator filter and the document_title_parts filter will never be executed as these only run after the pre_get_document_title filter.

Looking at what you said a bit further on:

...though I'm unable to get it to actually change the title.

you definitely have a pre_get_document_title filter with authority which is overriding your instance of the same filter, and because of this filter, the function return whatever is passed to it which results in your document_title_parts filter not being executed.

What you will need to do is is to use either grep or a good editor and search your entire wp-content folder for that pre_get_document_title filter. Once you located that filter, you can take it from there to remove that filter and replace it with your own

8
  • Thanks for the answer! Unfortunately, searching all of wp-content for document_title_parts or pre_get_document_title returns 0 results. I'm using SublimeText 2 to search all of wp-content... Commented Jun 30, 2016 at 13:46
  • This really beats me. It is really strange that one filter in a function fires correctly and the filter after that does not. Try clearing all caches and reinstal WordPress if you are sure it is not a plugin or your theme. What happens on a vanilla install with a bundled theme, what happens if you directly alter the parent theme. This is unfortunately as far as I can help with the info given. If you have any extra info, file an edit so we can assist you in solving this Commented Jul 1, 2016 at 5:35
  • @PieterGoosen When the first filter returns non empty the function is short circuited and the second filter is not evaluated.
    – cjbj
    Commented Jul 1, 2016 at 13:43
  • @cjbj yes, correct, that is what I said in my answer, the issue is what. As the OP said, he can't find a filter on pre_get_document_title, what would have totally explained why the second filter would not fire. This leaves the pre_get_document_title filter empty, which means the other two filters in the function must fire, but they don't. It leaves me to conclude a corrupt Wordpress core. Commented Jul 1, 2016 at 14:27
  • Except that I got that filter to work easily.
    – cjbj
    Commented Jul 1, 2016 at 14:32
2

If the parent theme does not declare support for title-tag you can do it like this in child theme

/**
 * Theme support should be added on `after_setup_theme`
 */
function add_theme_support_child() {

    add_theme_support( 'title-tag' );

}

add_action( 'after_setup_theme', 'add_theme_support_child', 11 );

Filter document_title_parts expected return type array, like this, be sure to change the if condition as per your requirements, or remove it completely to change the title throughout the site just for testing if it works.

/**
 * Change title of a page conditionally
 * 
 * @return $title - type array
 * $title['title'] - Page Title
 * $title['tagline'] - Site Tagline
 */
function change_title_for_a_template( $title ) {

    // Check if current page template is 'template-homepage.php'
    if ( is_page_template( 'template-homepage.php' ) ) {
        $title['title'] = 'Changed title for a template';
    }

    return $title;

}

add_filter( 'document_title_parts', 'change_title_for_a_template' );

Can you try thes two functions?

1
  • 1
    Thanks for the answer. I tried it, removing the if statement to make it more broad, and I added some error logging to see what's up. Here's the code.. Only add_theme_support_child is logged. Commented Jun 29, 2016 at 20:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.