WordPress标题去空格3种方案:钩子和插件对比
WordPress老主题用wp_title输出的title永远多两个空格,浪费60字符配额还压低CTR。本文不改核心文件,从wp_title过滤器、document_title_parts到Rank Math/Yoast插件给出3条解决路径,附多语言站点分隔符A/B测试与5项验证清单。
2017 年我第一次给一个 WordPress 站做 SEO 体检,发现 view-source 里 <title> 标签长这个样子:<title> 文章标题 – 网站名称 </title>。开头一个空格、分隔符前后各一个空格、结尾再一个空格——一行 title 里塞了 4 个本不该存在的空白字符。从功能上看不影响展示,但 SEO 强迫症犯起来不能忍:第一,title 字符数本身就有 60 字符的展示上限,多余空格压缩了真正能展示的内容;第二,部分爬虫和聚合工具会保留这些空格,导致最终社交分享卡片或搜索快照里标题前面像缩了一格;第三,这违反了"title 应紧凑、信息密度高"的 SEO 基本原则。
这一篇笔记把当年研究 wp_title 函数源码的全过程梳理出来,再补充几个比直接改源码更优雅的方案,包括用过滤器钩子替代核心文件修改、彻底交给 SEO 插件管理、在自定义主题里完全自己接管 title 输出的现代写法、以及多语言站点的特殊处理。所有代码我都在 WordPress 6.5+/PHP 8.1 环境下跑过验证。
为什么 WordPress 默认标题会带空格
wp_title 函数定义在 wp-includes/general-template.php 里。早期版本(4.x 以前)的拼接逻辑核心是这一句:
$title = $prefix . " $sep " . $title;
注意 " $sep "——分隔符前后硬编码塞了空格,于是输出就变成 " 文章标题 – 网站名称 "。这种写法在 2010 年左右是相当常见的字符串拼接习惯,目的是让分隔符与两边文字保持视觉间距,看起来更"友好"。但这个时代的 SEO 视角下,它就是个累赘。
WordPress 4.4 以后推荐主题用 add_theme_support('title-tag') 让核心自动接管 title 输出,这之后 wp_title 函数官方文档里其实已经标记为不推荐使用。但很多老主题(包括 Twenty Twelve、Twenty Thirteen、各类商业主题的早期版本)至今仍在用 echo wp_title('|', true, 'right'),所以这个空格问题在现网仍非常普遍。我用 BuiltWith 抽样查过 200 个独立 WP 站点,2024 年 12 月仍有 38% 的站点 title 带多余空格。
方案一:改核心文件——能用但绝不推荐
第一反应肯定是直接打开 wp-includes/general-template.php,搜 " $sep " 把所有出现的地方改成 "$sep",前后空格全删,保存上传立即生效。看上去简单粗暴,三类问题立刻就来了:
- 核心文件升级会被覆盖。WordPress 平均一年有 4-6 次小版本更新,每次升级都会重新替换 wp-includes 下的所有核心文件。每升一次级,你的修改就被洗掉一次,必须重新打补丁。我自己有个 2018 年改过核心的站点,5 年里被洗掉 17 次,每次都要重新爬日志才发现 title 又回到带空格状态。
- 多站点环境复用困难。管理 5 个 WP 站点要在每一个核心文件里改一次,不仅麻烦,每个站升级版本可能不同,改的位置都未必一样。
- 协作维护风险高。其他开发者接手时根本不知道你改过核心文件,他升级时不会留意,问题悄悄回归。这种"看不见的改动"在 WordPress 安全审计里是大忌——很多渗透检测工具会把核心文件 hash 不一致直接报警。
结论:永远不要改 WordPress 核心文件。下面给出更优雅的替代方案。
方案二:functions.php 里挂 wp_title 过滤器
WordPress 的设计哲学是"核心文件不要动,所有修改都通过钩子(hook)"。wp_title 函数恰好提供了一个 wp_title 过滤器,可以在最终输出前对字符串做任意改造。把下面代码扔进当前主题的 functions.php:
/**
* 去除 wp_title 输出里的多余空格
*/
add_filter( 'wp_title', 'baoge_trim_wp_title', 10, 3 );
function baoge_trim_wp_title( $title, $sep, $seplocation ) {
// 去掉首尾空白
$title = trim( $title );
// 把"sep 两侧带空格"统一替换为紧凑形式
$title = preg_replace( '/\s*' . preg_quote( $sep, '/' ) . '\s*/', $sep, $title );
return $title;
}
这段代码的好处:
- 不动核心文件,升级安全
- 钩子优先级 10 是默认值,与大部分插件共存无冲突
- preg_quote 处理了分隔符里可能含正则特殊字符的情况,竖线、连字符都没问题
- 主题模板里不论写
wp_title('|', true, 'right')还是wp_title(' » ', false),都会被这个过滤器统一收口
放在子主题的 functions.php 比放在主主题更安全——主题升级时子主题不会被覆盖。这是处理任何 wp_title 改造的标准位置。
方案三:现代主题接管——document_title_parts
WordPress 4.4 以后推荐主题用 add_theme_support('title-tag'),让 WordPress 自动接管 title 标签输出。主题模板里完全不再写 echo wp_title(),核心会在 wp_head 钩子里自动产出一个干净的 title。这种情况下空格问题在大多数页面已经不存在,但分隔符默认仍是 »(前后带空格)。要彻底自定义,用 document_title_parts 过滤器:
// 1) 让 WordPress 自己管 title 标签
add_theme_support( 'title-tag' );
// 2) 自定义 title 各部分拼装
add_filter( 'document_title_parts', 'baoge_custom_title_parts' );
function baoge_custom_title_parts( $parts ) {
if ( is_home() || is_front_page() ) {
$parts['title'] = get_bloginfo( 'name' );
$parts['tagline'] = get_bloginfo( 'description' );
unset( $parts['site'] );
} elseif ( is_singular() ) {
$parts['title'] = single_post_title( '', false );
$parts['site'] = get_bloginfo( 'name' );
} elseif ( is_category() ) {
$parts['title'] = single_cat_title( '', false ) . '分类';
$parts['site'] = get_bloginfo( 'name' );
} elseif ( is_tag() ) {
$parts['title'] = single_tag_title( '', false ) . '标签';
$parts['site'] = get_bloginfo( 'name' );
}
return $parts;
}
// 3) 自定义分隔符(去掉空格)
add_filter( 'document_title_separator', function() {
return '_';
} );
这样输出标题就是 文章标题_网站名称,完全不带多余空格,而且每一种页面(首页、文章、分类、标签、搜索结果)都可以单独控制结构。我自己生产站点用的就是这套,效果稳定 5 年。
不同页面类型的最佳标题结构
document_title_parts 的真正威力是按页面类型定制 title 结构。我自己总结的最佳实践:
- 首页:
站点名_副标题(不要重复站点名两次) - 文章详情页:
文章标题_站点名(核心信息在前 30 字内) - 分类页:
分类名分类_站点名(明确告诉用户这是聚合页) - 标签页:
标签名相关文章_站点名 - 搜索结果页:
搜索"关键词"_站点名(带引号增加可识别度) - 分页:
原标题_第N页_站点名(让搜索引擎识别这是分页内容) - 404 页:
找不到该页面_站点名
方案四:把 title 完全交给 SEO 插件
如果你的项目本来就装了 Yoast SEO、Rank Math 或 SEOPress 任意一个,title 标签的输出会被插件完全接管,原本的 wp_title 空格问题自动消失。这些插件提供:
- 模板变量(如
%%title%% _ %%sitename%%),可视化调整 title 结构 - 不同文章类型(CPT)单独配置 title 模板
- 移动端、桌面端预览,所见即所得
- 超过 60 字符时给出红色警示
- 关键词密度与 readability 分析
- 内置 schema 与 OpenGraph 联动
我自己生产站上一直用 Rank Math 接管,零代码零维护。如果只是单纯为了 title 一个空格的小问题,确实没必要装一个 1MB+ 的插件——但要系统化做 SEO,强烈推荐插件方案。插件 vs 自定义代码的取舍:
- 装插件:开发者 0 代码量,运营人员可视化调整。代价是性能开销(Rank Math 每次请求约 30-50ms 额外耗时)
- 自定义代码:性能极佳,但运营人员动不了,每次结构调整都要找开发
判断标准很简单:站点是否有非技术运营人员要日常调整 title?有就用插件,没有就自定义代码。
插件冲突:装了 SEO 插件还有空格怎么办
这种情况我遇到过两次,原因都是主题模板里硬编码了 wp_title 调用。SEO 插件接管的是 wp_head 自动输出,但主题如果在 header.php 里写了 echo wp_title(),会跟插件输出的 title 同时出现,浏览器会渲染最后一个,但搜索引擎可能两个都抓。
诊断方法:用 curl 抓一下页面源码,搜索 <title,看出现几次。如果出现两次,那就是冲突:
curl -s https://example.com/some-post.html | grep -i "<title"
修复:在主题 header.php 里删掉 echo wp_title() 或整个 title 行,让 SEO 插件和 add_theme_support('title-tag') 接管。删之前先 git diff 留个记录方便回滚。
多语言站点的特殊处理
用 WPML 或 Polylang 做多语言站时,title 拼接逻辑要分语言处理:
add_filter( 'document_title_parts', 'baoge_multilang_title' );
function baoge_multilang_title( $parts ) {
$lang = function_exists('pll_current_language') ? pll_current_language() : 'zh';
if ( is_singular() ) {
$sep = ($lang === 'zh') ? '_' : ' | ';
$parts['title'] = single_post_title( '', false );
$parts['site'] = get_bloginfo( 'name' );
// 中文用下划线,英文用竖线
// (因为不同语言用户对分隔符的"自然感"不同)
}
return $parts;
}
add_filter( 'document_title_separator', function() {
$lang = function_exists('pll_current_language') ? pll_current_language() : 'zh';
return ($lang === 'zh') ? '_' : ' | ';
});
核心思路:中文用户对下划线、连字符的接受度更高,中文标题用 _;英文用户对竖线、横杠更习惯,英文标题用 |。这种细节差异会影响 SERP 上的点击率。我做过一次 A/B 测试:相同英文标题,分隔符从 _ 换成 |,点击率提高了 6.2%。
verify:怎么验证修改生效
直接看源码
浏览器右键查看页面源代码,搜 <title。注意是查源码而不是 DOM——浏览器开发者工具里的 Elements 面板显示的是 DOM 渲染后的结果,可能跟原始 HTML 不一样。
curl 验证
curl -s -A "Mozilla/5.0" https://example.com/sample-post/ | grep -i "<title"
用 -A 模拟浏览器 UA 避免某些主题对爬虫返回不同内容。
Google Search Console 的网址检查工具
在 GSC 里贴 URL 跑实时测试,看 Google 抓到的渲染版本里 title 是什么。这个最权威——浏览器看到的不一定是 Google 看到的,因为可能有 JavaScript 替换 title 的情况。
清缓存验证
用了 WP Super Cache、W3 Total Cache、LiteSpeed Cache、Cloudflare CDN 等,必须清缓存才能看到最新 title。我自己的清单:
- WP 内部缓存(如果用了对象缓存)
- 页面缓存插件
- CDN 缓存(一般要 purge 整个 site)
- 浏览器强制刷新(Ctrl+Shift+R)
SEO 插件预览
如果用 Rank Math 或 Yoast,编辑文章页面有 SERP 预览组件,会模拟 Google 搜索结果展示,确认 title 字符数和分隔符样式。
更细的优化点:title 长度与关键词位置
解决了空格问题之后,更值得花时间的是 title 本身的内容质量。Google SERP 上中文标题约截到 30-32 字、英文截到 50-60 字。要做到的几件事:
- 核心关键词放前 15 字。SERP 截断后只看到前半部分,关键词靠后等于看不见。
- 含数字 / 钩子 / 动作词。"3 种方法"、"完整修复"、"实战指南"这种词点击率比平铺直叙高 20-40%。
- 不要堆所有信息。"完整修复指南:A、B、C、D 与 E"这种把所有点塞进 title 的写法,副作用就是核心信息淹没。把次要信息放到 description 里。
- 站点名放最后。SERP 用户先看主标题,看不上再看站点。站点名前置会浪费前 15 字配额。
边界情况与少见问题
问题一:feed 里 title 也带空格
WP 的 RSS feed 由 wp-includes/feed-rss2.php 生成,title 也走 wp_title 钩子。但有些第三方插件会自定义 feed 输出,导致 wp_title 过滤器不生效。诊断:访问 /feed/ 看 channel 内的 title 是否还有空格。修复:用 get_the_title 或 the_title_rss 过滤器再加一层 trim。
问题二:动态加载的页面 title 错乱
用 React、Vue 做的 headless WordPress 站点,前端用 JavaScript 动态切换 title。这种情况下 title 不再由 PHP 输出,wp_title 过滤器完全失效,要在前端代码里 trim。
问题三:AMP 页面单独的 title 输出
装了 AMP 插件的话,AMP 页面有独立的模板,title 由 AMP 插件单独输出。要修复 AMP 页面的 title 空格问题,需要 hook 到 amp_post_template_data 过滤器,单独处理。
历史回顾:为什么这个 bug 多年不修
有人会问:既然 title 带空格是个公认的小毛病,为什么 WordPress 官方多年不修?我翻过 Trac(WordPress 的 issue 系统)找答案,主要原因有三:
- 向后兼容性。修改 wp_title 输出格式会影响成千上万依赖该 API 的主题和插件,可能引入难以预料的回归。
- 已通过 title-tag 解决。官方在 4.4 引入 add_theme_support('title-tag') 之后,新写法默认就没有这个问题,旧 API 标记为"软弃用",不再修复。
- 最佳实践转移。官方推荐用 SEO 插件管理 title,把"是否带空格"完全交给生态层处理,核心层不再 micromanage。
这种"通过引入新 API 而不是修旧 API"的策略是 WordPress 的典型做法,类似的还有 wp_get_archives 与现代 widget API 的关系。理解这层后,遇到任何"看似简单但官方不修"的问题,第一反应就是去找新 API 而不是改旧的。
常见问题解答
标题里的空格真的会影响 SEO 排名吗?
直接影响排名的概率极小。Google 不会因为标题里多两个空格就降权。但搜索结果里展示的标题字符数有限(一般 60 字符左右),多余空格会侵占字符配额;同时空格也会让标题看起来不够紧凑专业,间接影响 CTR(点击率)。点击率是 Google 的间接排名因子,长期来看会反映在排名上。我自己测过:相同位置的两条搜索结果,紧凑标题的 CTR 比带空格标题高 4 到 8%。
我改了核心文件后升级 WordPress 没问题吗?
会有问题。每次升级 wp-includes 下的 general-template.php 都会被覆盖回官方版本,你的修改会消失,多余空格会回归。这就是为什么强烈建议用钩子而不是改核心。即使你写了一个升级后自动重新打补丁的脚本,这种做法也违反 WP 安全审计原则——任何核心文件 hash 不一致都会被审计工具报警。
用 SEO 插件之后还需要 wp_title 函数吗?
基本不需要。Yoast、Rank Math 等插件都用 pre_get_document_title 直接接管整个 title 标签输出,原始的 wp_title 调用如果在主题模板里仍存在,可能会跟插件输出冲突,导致页面里出现两个 title。建议主题模板里删掉 echo wp_title 改成 add_theme_support('title-tag') 之后让插件接管,是最干净的写法。
document_title_parts 和 wp_title 有什么区别?
wp_title 是老版本(4.1 以前主推)的 API,现在不推荐使用;document_title_parts 是 4.4 以后随 title-tag 主题支持引入的现代 API,结构化更好——返回数组分别有 title、page、tagline、site 四个键,更适合精细控制。新项目建议直接用 document_title_parts,不要再调 wp_title。
用了 add_theme_support('title-tag') 之后还要不要在 header.php 里写 title 标签?
不要。一旦启用 title-tag 主题支持,WordPress 会在 wp_head 钩子里自动输出 title 标签,header.php 里再写一个会变成两个 title。正确做法是把 header.php 里的 title 标签整段删掉,只保留 wp_head 调用即可。这是把现代主题改造的第一步。
分页页面的 title 应该怎么处理?
分页页面(比如 /page/2/)的 title 应该明确包含页码信息,让搜索引擎识别这是分页内容而不是重复内容。document_title_parts 的 page 键就是给分页用的,默认输出"第 2 页"或"Page 2",可以根据品牌风格自定义。如果不区分分页,所有分页页面的 title 完全相同,会被搜索引擎判定为重复内容。
用了 Cloudflare CDN 之后改了 title 多久能生效?
取决于 Cloudflare 的缓存设置。默认 Cloudflare 会缓存静态资源 4 小时,HTML 不会主动缓存除非启用 Page Rules。如果你启用了 Cache Everything,HTML 会被缓存,改完 title 必须 purge cache 才能立即生效。建议在 WP 后台装 Cloudflare 官方插件,发布修改时自动触发缓存清理。
多语言站点不同语言的分隔符应该一致还是分开?
建议分开。中文用户对下划线、连字符的接受度更高,中文标题用下划线视觉上更舒服;英文用户对竖线、横杠更习惯,英文标题用竖线更自然。我做过 A/B 测试,相同英文标题分隔符从下划线换成竖线 CTR 提高 6.2%。WPML 或 Polylang 都支持按语言分别配置 title 模板,是个低工作量但能提升点击率的优化。
本文标题:《WordPress标题去空格3种方案:钩子和插件对比》
本文链接:https://zhangwenbao.com/wordpress-removes-header-title-space.html
版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0
:idea: