我的网站使用了 AeroCore 主题。我发现两个问题:日期归档页和站内搜索页被谷歌收录了,这些页面对用户没有用; 分类页、标签页和作者页的分页标题完全一样,谷歌可能觉得这些页面是重复的。
为了解决问题,我在子主题 functions.php 中添加了几段 PHP 代码。这段代码有两个部分: 第一部分给日期归档页和搜索页加上禁止收录标签;第二部分给分页标题和描述加上页码。这个方法让网站的 SEO 变好了。
1. 不让谷歌收录日期归档页和搜索页
日期归档页按时间列出文章,不同日期可能显示差不多的文章列表;站内搜索页根据用户输入生成结果。 这两个页面都没有特别的价值,会浪费谷歌的抓取时间,也会拉低网站的整体质量。
完整代码
add_action( 'wp_head', function() {
global $wp_query;
if ( $wp_query->is_date ) {
echo '<meta name="robots" content="noindex,nofollow">' . "\n";
}
if ( $wp_query->is_search ) {
echo '<meta name="robots" content="noindex,nofollow">' . "\n";
}
}, 99 );
代码做了什么
代码会检查当前页面是不是日期归档页或者搜索页。如果是,它就在页面头部加一个标签,告诉谷歌不要收录这个页面。 标签内容就是 noindex,nofollow。noindex 表示不要收录,nofollow 表示不要跟着页面上的链接走。
这个操作不会影响用户正常访问,用户还是能看到这些页面。但它对谷歌 SEO 有帮助:谷歌会把这些页面从索引里去掉, 网站的整体质量信号会更好。用户在谷歌搜索时,也不会再看到这些没用的页面。
2. 给分页标题和描述加上页码
分类页、标签页和作者页可能有很多页。比如一个分类有 10 页文章,之前每一页的标题都一样,描述也一样, 谷歌分不清第 2 页和第 3 页,用户也可能点错。代码会给每个分页加上页码,只处理多页情况,只有一页时什么都不改。
完整代码
add_action('template_redirect', function () {
if (is_admin() || wp_doing_ajax() || (defined('REST_REQUEST') && REST_REQUEST)) {
return;
}
if (!(is_category() || is_tag() || is_author())) {
return;
}
$paged = max(1, (int) get_query_var('paged'));
global $wp_query;
$max_pages = empty($wp_query->max_num_pages) ? 0 : (int) $wp_query->max_num_pages;
if ($max_pages < 2) {
return;
}
$site_name = get_bloginfo('name');
$a_name = '';
if (is_author()) {
$author = get_queried_object();
$a_name = $author ? $author->display_name : '';
}
// 拿到当前归档的原始标题(分类名/标签名/作者名)
$base = single_cat_title('', false);
if (is_tag()) {
$base = single_tag_title('', false);
}
if (is_author()) {
$base = get_queried_object()->display_name ?? '';
}
// ⬇️ 关键:在 ob_start 回调里统一处理标题和描述
ob_start(function ($html) use ($site_name, $paged, $a_name, $base) {
// ---- 改写 <title> ----
$html = preg_replace_callback('/<title>(.*?)<\/title>/is', function ($m) use ($site_name, $paged, $a_name, $base) {
if ($a_name !== '') {
return '<title>' . $a_name . '的文章 - 第' . $paged . '页 - ' . $site_name . '</title>';
}
return '<title>' . $base . ' - 第' . $paged . '页 - ' . $site_name . '</title>';
}, $html, 1);
// ---- 改写 <meta name="description"> ----
$html = preg_replace_callback(
'#<meta\s+name=["\']description["\']\s+content=["\'](.*?)["\']\s*/?>#is',
function ($m) use ($paged, $a_name, $base) {
$orig = $m[1] ?? '';
if ($a_name !== '') {
$new = '这是作者' . $a_name . '的文章第' . $paged . '页,' . $orig;
} else {
$new = '这是' . $base . '第' . $paged . '页,' . $orig;
}
return '<meta name="description" content="' . $new . '">';
},
$html, 1
);
return $html; // ⬅️ 必须返回修改后的内容
});
}, PHP_INT_MAX - 1);
代码做了什么
- 拿到当前归档标题:通过
single_cat_title()、single_tag_title()或作者名获取原始标题,存到$base变量。 - 在
ob_start回调里统一处理:所有对标题和描述的修改都放在回调函数内部,最后用return $html;把修改后的内容送回缓冲区。 - 改写标题:分类/标签页在原标题后加上“第 X 页”,作者页显示“作者名 的文章 – 第X页 – 站名”。
- 改写描述:在原有描述前增加“这是 XXX 第 X 页,”的前缀。
用户看到标题里的页码就明白自己在哪一页,谷歌也能区分不同分页。关键词位置没有变, 分类名字还是在标题前面,页码在中间,站名在最后,这样对 SEO 友好。
兼容性说明
💡 兼容性说明: 代码运行在翻译插件之前,先改中文页面,英文页面由翻译插件自动处理。 主链接标签没有被改动,SEO 插件可以继续正常工作。这个方案很安全。