标题标签和document_title_parts的问题


12

Wordpress version 4.5.1

我正在尝试动态更新特定模板上的页面标题。经过大量的挖掘和了解wp_title()更改之后,我尝试使用document_title_parts。但是,我根本无法运行过滤器。

我的主题是儿童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 );

我已经尝试了两种添加主题支持的变体,如上所示,但是看着我的日志,页面重新加载没有任何显示。那error_log是与其他功能一起使用的(例如wp_title),因此错误日志记录正在工作。

我也尝试过pre_get_document_title,它确实会在页面加载时触发,尽管我无法获取它来实际更改标题。

所以!我使用的过滤器有误,未正确设置主题或其他我不知道的东西。任何帮助将不胜感激!

编辑以添加更多详细信息

尝试使用init函数,但也无法正常工作:https//gist.github.com/anonymous/6db5af892a4cf4fb029655167d7002a4

此外,虽然我已删除任何引用<title>header.php,现场实际标题仍然显示在源。


你为什么注释掉这一行//add_filter("after_setup_theme", function(){ add_theme_support("title-tag"); });?这是添加主题支持的正确用法。
Sumit

@Sumit我尝试了注释版本和活动版本。
hookedonwinter

也许尝试add_theme_support()init钩子中添加功能。另一件事是确保您覆盖header.php文件而没有 html <title>标记。
Howdy_McGee

@Howdy_McGee刚刚尝试过,仍然什么也没有。gist.github.com/anonymous/6db5af892a4cf4fb029655167d7002a4
hookedonwinter 2016年

@hookedonwinter您确定您的<title>标签中没有标签header.php吗?也许尝试更换10PHP_MAX_INT。另外,传递的参数是一个数组,而不是字符串值。
Howdy_McGee

Answers:


13

我在开发区域中运行了您的过滤器。没用 然后我关闭了Yoast SEO插件,我知道这也弄乱了页面标题。然后它起作用了。因此,我的建议是另一个插件将其弄乱。

在Yoast的情况下,这是对pre_get_document_title返回非空值的过滤器调用。在这种情况下,wp_get_document_title会发生短路documents_title_parts,并且不评估函数的其余部分(包括滤波器),如您从第一行代码中所看到的:

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

因此,我带上了您的过滤器,并将钩子更改为pre_get_document_title。没用 然后,我将优先级更改为比Yoast中相同过滤器更高的级别。然后它起作用了。因此,我不知道您的设置,但是我建议您尝试一下:

add_filter( 'pre_get_document_title', function( $title )
  {
    error_log('here');
    return $title;
  }, 999, 1 );

1
你说对了!我发现了同样的事情,并停用了Yoast。我只是重新激活并使用了您的优先级,它才起作用。谢谢!
hookedonwinter 2016年


在我的网站上,pre_get_document_title优先级15就足够了。
vee

7

经过一些试验后,我得出以下建议:可能是,该<title>标签在您的父主题的标签中是“硬编码的” header.php吗?如果是这种情况,您可以尝试<title>从子主题的标签中删除标签header.php(将父主题的标签复制header.php到子主题文件夹中),然后通过以下方式添加主题支持functions.php

add_theme_support( 'title-tag' );

我将尝试解释是什么导致了我提出这个建议:我按照您和其他人的建议进行了尝试-但事实证明,我在源代码中找到了两个<title>标签。第一个具有标准标题,第二个具有标准标题。但是(当然)在浏览器标题栏中,我只能看到默认标题。

然后,我检查了header.php我使用的父主题的主题(二十四),并且该<title>标签确实在该模板内进行了硬编码,如下所示:

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

删除它之后,我将以下代码添加到了子主题中,functions.php并且可以正常工作:

/**
 * 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 );

因此,在<title>从模板中删除标签之前,它基本上也可以工作-只是只有两个 <title>标签,后面的标签被忽略了。您的主题可能会遇到同样的问题吗?

从wp 4.4.0开始,该<title>标签是由该函数动态创建的,该函数_wp_render_title_tag()基本上会调用另一个函数wp_get_document_title(),并将html标签包装在结果周围。长话短说:如果你的主题header.php缺少<title>的标签,有机会,你可以直接通过覆盖标题pre_get_document_titledocument_title_parts描述这里

1)直接更改标题:

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

2)过滤标题部分:

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

3

从上至下,从下至上阅读您的帖子,您很有可能拥有一个正在通过该pre_get_document_title筛选器传递标题的筛选器。这里的线索如下声明:

我也尝试过pre_get_document_title,它会在页面加载时触发,

查看的纯代码wp_get_document_title(),我们看到以下代码:

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

这意味着,每当非空值通过pre_get_document_title过滤器时,该wp_get_document_title()函数将返回通过pre_get_document_title过滤器传递的任何值。在这种情况下,document_title_separator过滤器和document_title_parts过滤器将永远不会执行,因为它们仅在pre_get_document_title过滤器之后运行。

看一下您所说的内容:

...尽管我无法获得它来实际更改标题。

您肯定有一个pre_get_document_title具有权限的过滤器,该过滤器将覆盖同一过滤器的实例,并且由于该过滤器,该函数返回传递给它的所有内容,从而导致您的document_title_parts过滤器无法执行。

您需要做的是使用一个grep或优质的编辑器,然后在整个wp-content文件夹中搜索该pre_get_document_title过滤器。找到该过滤器后,您可以从那里取出该过滤器并将其替换为自己的过滤器


谢谢你的回答!不幸的是,搜索所有wp-content document_title_partspre_get_document_title返回0个结果。我正在使用SublimeText 2搜索所有wp内容...
hookedonwinter

这真的打败了我。真奇怪的是,函数中的一个过滤器可以正确启动,而此后的过滤器不能正常启动。如果您确定它不是插件或主题,请尝试清除所有缓存并重新安装WordPress。在具有捆绑主题的原始安装中会发生什么,如果直接更改父主题会发生什么。不幸的是,据我所提供的信息我可以提供帮助。如果您有任何其他信息,请进行编辑,以便我们协助您解决问题
Pieter Goosen

@PieterGoosen当第一个过滤器返回非空值时,函数短路,第二个过滤器不评估。
cjbj

@cjbj是的,正确,这就是我在回答中所说的,问题是什么。正如OP所说,他在上找不到过滤器pre_get_document_title,这完全可以解释为什么第二个过滤器不会触发。这使pre_get_document_title过滤器为空,这意味着该函数中的其他两个过滤器必须启动,但不能启动。它让我总结了一个腐败的Wordpress核心。
Pieter Goosen

除了我使该过滤器易于工作之外。
cjbj

2

如果父主题未声明对title-tag您的支持,则可以在子主题中这样做

/**
 * 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 );

document_title_parts像这样过滤预期的返回类型数组,请确保根据您的要求更改if条件,或完全删除它以更改整个站点的标题,仅用于测试其是否有效。

/**
 * 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' );

您可以尝试这两个功能吗?


感谢你的回答。我尝试了一下,删除了if语句以使其更广泛,并且添加了一些错误日志记录以查看发生了什么。这是代码。。仅add_theme_support_child记录。
hookedonwinter 2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.