我刚才发现文章页面的源码里有个 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_action 和 do_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
添加的动作。