Saber 酱的抱枕

Fly me to the moon

08/13
2024
软件

修改 WordPress 的 canonical 链接

我刚才发现文章页面的源码里有个 canonical 链接,例如:

<link rel="canonical" href="https://saber.love/xxxxx.html" />

我搜索了下这个东西,说是“规范 URL”,作用是当一个页面可能有多个 URL 时,指定一个 canonical URL,让搜索引擎只收录这一个网址。
因为如果多个 URL 里的内容相同,可能会导致搜索结果的排名受到影响,因此需要指定一个唯一的 canonical URL。

本站文章页面确实可能存在多种网址,其中一种是直达某条评论的网址,格式如下:

https://saber.love/xxxxx.html/comment-page-1#comment-15114

从网页右下角的“近期评论”里会进入这种网址,直达某条评论。

这种网址里面的内容和文章页面的内容其实是一样的,只是起到了个定位的作用。但是此时 canonical URL 会受到影响,变成直达评论区的定位链接:

https://saber.love/xxxxx.html/comment-page-1#comments

我只想要 https://saber.love/xxxxx.html ,不要后面的部分。

生成 canonical URL 的代码在 wp-includes/link-template.php 里:

这里的代码得从下往上看,rel_canonical() 在最后输出了 HTML 标签,但 URL 是 wp_get_canonical_url() 生成的,其在最后调用了 get_canonical_url 钩子。

因此在主题的 functions.php 里对 get_canonical_url 钩子添加一个动作即可,我截断了 .html 后面的部分:

// 修改 rel="canonical" 的 URL,截断 .html 后面的部分,只保留文章的固定连链接
function sub_canonical_url ( $url ){
$position = strpos($url, '.html');

// 检查 .html 是否存在
if ($position !== false) {
    // 只保留 .html 之前的部分
    $url = substr($url, 0, $position + 5); // +5 是为了包含 .html
}

return $url;
}
add_filter( 'get_canonical_url', 'sub_canonical_url', '', 1);

这样就解决了问题。


因为我对 WordPress 一头雾水,所以搜了下这种方法的原理:
使用 add_filter 可以对指定的钩子添加自定义函数,之后当 WordPress 执行 apply_filters(钩子) 时,会运行这个钩子上所有的函数。

add_filter 的文档
apply_filters 的文档

此外,还有 add_actiondo_action,它们与 filters 的使用场景不同。

add_filter 是为指定钩子添加自定义函数,而 add_action 其实是事件绑定,当 WordPress 触发某些事件时执行附加操作,如:

// 在 head 标签里添加自定义内容
add_action('wp_head', 'add_javascript');
// 在保存文章时执行操作
add_action('save_post', 'clear_zal_cache');
// 在 footer 标签里添加自定义内容
add_action( 'wp_footer', 'my_deregister_scripts' );

当 WordPress 执行 do_action(钩子) 时,会运行所有由 add_action 添加的动作。

修改 WordPress 的 canonical 链接