咳咳,各位,欢迎来到今天的“WordPress标题炼金术”讲座!我是你们的向导,今天咱们要一起扒开 wp_get_document_title()
这个小家伙的外衣,看看它到底是如何把各种零碎的信息,变成我们浏览器标签页上那闪闪发光的页面标题的。
准备好了吗?Let’s dive in!
1. 标题的诞生:wp_get_document_title()
的真面目
首先,让我们来看看 wp_get_document_title()
的庐山真面目。这个函数存在于 WordPress 的 wp-includes/general-template.php
文件中。它的主要职责就是根据当前页面的上下文环境,构建一个合适的 HTML 文档标题。
function wp_get_document_title() {
/**
* Filters the parts used to build the document title.
*
* @since 4.4.0
*
* @param string[] $title_array Array of strings used to put together the document title.
*/
$title_array = apply_filters( 'document_title_parts', _wp_document_title_parts() );
/**
* Filters the separator used between the document title parts.
*
* @since 4.4.0
*
* @param string $sep Document title separator.
*/
$title = implode( apply_filters( 'document_title_separator', _wp_document_title_separator() ), $title_array );
/**
* Filters the document title.
*
* @since 4.4.0
*
* @param string $title The document title.
* @param string[] $title_array Array of strings used to put together the document title.
*/
return apply_filters( 'document_title', $title, $title_array );
}
瞧见没?这个函数本身并没有多少“硬编码”,它主要依赖于三个过滤器:
document_title_parts
: 这个过滤器负责提供标题的各个组成部分(比如文章标题、站点名称等等)。document_title_separator
: 这个过滤器负责定义标题各个部分之间的分隔符(比如 " – " 或 "|")。document_title
: 这个过滤器允许你对最终生成的完整标题进行最后的修改。
这种设计简直太妙了!它赋予了我们极大的灵活性,可以根据自己的需求定制页面的标题。
2. 标题零件的制造者:_wp_document_title_parts()
wp_get_document_title()
本身只是个组装工,真正负责提供标题零件的是 _wp_document_title_parts()
函数。这个函数才是真正的标题“侦探”,它会根据当前的页面类型,搜集各种信息,然后把它们整理成一个标题零件数组。
function _wp_document_title_parts() {
global $wp_query, $wp_locale;
$title = array();
/*
* The order in which these are added is important.
*
* They will be output in the order:
* 1. Site name.
* 2. Page description.
* 3. Page/post title.
*/
if ( is_front_page() ) {
if ( is_home() ) {
// If purely home, the front page is a blog, so use the site title.
$title['title'] = get_bloginfo( 'name', 'display' );
} else {
// Front page is a page.
$title['title'] = get_the_title();
}
} elseif ( is_home() ) {
// If the front page is a page, the blog is the "home".
$title['title'] = single_post_title( '', false );
} elseif ( is_singular() ) {
/*
* Singular Post View.
*
* is_single() or is_page() or attachment page.
*/
$title['title'] = single_post_title( '', false );
} elseif ( is_category() ) {
$title['title'] = single_cat_title( '', false );
} elseif ( is_tag() ) {
$title['title'] = single_tag_title( '', false );
} elseif ( is_tax() ) {
$term = get_queried_object();
if ( $term ) {
$title['title'] = $term->name;
}
} elseif ( is_author() ) {
$author = get_queried_object();
if ( $author ) {
$title['title'] = $author->display_name;
}
} elseif ( is_post_type_archive() ) {
$title['title'] = post_type_archive_title( '', false );
} elseif ( is_date() ) {
/*
* Yearly archive: 2016
* Monthly archive: March, 2016
* Daily archive: March 8, 2016
*/
if ( is_year() ) {
$title['title'] = get_the_date( _x( 'Y', 'yearly archives date format' ) );
} elseif ( is_month() ) {
$title['title'] = get_the_date( _x( 'F, Y', 'monthly archives date format' ) );
} elseif ( is_day() ) {
$title['title'] = get_the_date( _x( 'F j, Y', 'daily archives date format' ) );
}
} elseif ( is_search() ) {
/* translators: %s: search query. */
$title['title'] = sprintf( __( 'Search Results for “%s”' ), get_search_query() );
} elseif ( is_404() ) {
$title['title'] = __( 'Page Not Found' );
} else {
$title['title'] = get_bloginfo( 'name' );
}
$title['site'] = get_bloginfo( 'name', 'display' );
if ( ( is_home() || is_front_page() ) && ( $description = get_bloginfo( 'description', 'display' ) ) ) {
$title['description'] = $description;
}
return $title;
}
这个函数利用了 WordPress 的各种条件判断函数(比如 is_front_page()
, is_singular()
, is_category()
等等),来确定当前页面的类型。然后,它会根据页面类型,调用相应的函数来获取标题信息。
get_bloginfo()
: 用于获取站点信息,比如站点名称和描述。single_post_title()
: 用于获取文章或页面的标题。single_cat_title()
: 用于获取分类目录的标题。single_tag_title()
: 用于获取标签的标题。get_the_date()
: 用于获取日期存档页面的日期。get_search_query()
: 用于获取搜索关键词。
它将获取到的信息存入 $title
数组中,数组的键名包括 title
(页面内容标题), site
(站点名称), description
(站点描述)。
3. 分隔符的秘密:_wp_document_title_separator()
接下来,我们来看看分隔符。_wp_document_title_separator()
函数非常简单,它只是返回一个默认的分隔符。
function _wp_document_title_separator() {
/**
* Filters the document title separator string.
*
* @since 4.4.0
*
* @param string $sep Document title separator.
*/
return apply_filters( 'document_title_default_separator', ' » ' );
}
默认情况下,分隔符是 »
(也就是 » 符号)。 当然,你可以使用 document_title_default_separator
过滤器来修改它。
4. 组装与润色:从零件到完整标题
现在,我们已经有了标题的各个组成部分,也有了分隔符。wp_get_document_title()
函数会使用 implode()
函数,将这些零件组装成一个完整的标题字符串。
$title = implode( apply_filters( 'document_title_separator', _wp_document_title_separator() ), $title_array );
在这里,apply_filters( 'document_title_separator', _wp_document_title_separator() )
允许我们通过 document_title_separator
过滤器修改分隔符,然后再将修改后的分隔符传递给 implode()
函数。
最后,wp_get_document_title()
函数会使用 document_title
过滤器,允许我们对最终生成的标题进行最后的润色。
return apply_filters( 'document_title', $title, $title_array );
5. 实战演练:自定义页面标题
理论讲了这么多,不如来点实际的。假设我们想在所有文章页面的标题后面,都加上一个 " – Powered by My Awesome Theme" 的后缀。我们可以这样做:
add_filter( 'document_title_parts', 'my_awesome_theme_document_title_parts' );
function my_awesome_theme_document_title_parts( $title ) {
if ( is_singular( 'post' ) ) {
$title['powered_by'] = 'Powered by My Awesome Theme';
}
return $title;
}
add_filter( 'document_title_separator', 'my_awesome_theme_document_title_separator' );
function my_awesome_theme_document_title_separator( $sep ) {
return '|'; // 更改分隔符为 |
}
这段代码首先使用 document_title_parts
过滤器,向标题零件数组中添加了一个新的元素 powered_by
。 然后使用 document_title_separator
过滤器,更改了分隔符为竖线 |
。
再举个例子,假设我们想在所有分类目录页面的标题前面,加上 "Category: " 的前缀。我们可以这样做:
add_filter( 'document_title', 'my_awesome_theme_document_title' );
function my_awesome_theme_document_title( $title ) {
if ( is_category() ) {
$title = 'Category: ' . $title;
}
return $title;
}
这段代码直接使用 document_title
过滤器,修改了最终生成的标题字符串。
6. 总结:标题炼金术的精髓
让我们来总结一下,wp_get_document_title()
函数的精髓在于:
- 灵活性: 它通过过滤器机制,赋予了我们极大的灵活性,可以根据自己的需求定制页面的标题。
- 可扩展性: 我们可以通过添加新的过滤器,来扩展
wp_get_document_title()
函数的功能。 - 模块化: 标题的各个组成部分都是独立的,我们可以单独修改它们。
7. 常见问题与解答
-
Q: 为什么我的页面标题没有生效?
A: 请检查你的主题是否使用了
wp_head()
函数,以及是否正确地调用了wp_get_document_title()
函数。 另外,检查你添加的过滤器是否正确,以及是否有其他插件或主题覆盖了你的设置。 -
Q: 如何禁用 WordPress 的默认标题生成?
A: 你可以移除
wp_head()
函数中的wp_enqueue_scripts
动作,或者使用一个空的标题字符串覆盖默认标题。 但是,不建议这样做,因为它可能会影响 SEO。 -
Q: 如何针对不同的文章类型,设置不同的标题格式?
A: 你可以使用
is_singular()
函数,根据文章类型进行条件判断,然后设置不同的标题格式。
8. 深入探索:一些高级技巧
-
使用 transients 缓存标题: 对于一些计算量较大的标题,可以使用 transients 缓存结果,以提高性能。
-
利用 Yoast SEO 等插件: 这些插件通常提供了更高级的标题管理功能,可以让你更方便地控制页面标题。
-
考虑 SEO 因素: 在设置页面标题时,要考虑 SEO 因素,选择合适的关键词,并确保标题的长度适中。
9. 代码示例:不同场景下的标题定制
为了让大家更直观地理解,我再提供一些代码示例,展示如何在不同的场景下定制页面标题。
场景 | 代码示例 |
---|---|
在首页显示站点名称和描述,并使用 " – " 分隔符 | php php |
// 首页标题
add_filter( ‘document_title_parts’, ‘my_custom_home_title’ );
function my_custom_home_title( $title ) {
if ( is_front_page() && is_home() ) {
$title[‘title’] = ‘Welcome to My Awesome Website!’;
$title[‘description’] = ‘The best place on the internet.’;
}
return $title;
}
// 分类目录标题
add_filter( ‘document_title_parts’, ‘my_custom_category_title’ );
function my_custom_category_title( $title ) {
if ( is_category() ) {
$title[‘title’] = ‘Browsing Category: ‘ . single_cat_title( ”, false );
}
return $title;
}
// 文章页标题
add_filter( ‘document_title_parts’, ‘my_custom_post_title’ );
function my_custom_post_title( $title ) {
if ( is_singular( ‘post’ ) ) {
$