WordPress 自带的 Twenty Fifteen 主题(2015 年首发,仍在 WP 默认四大主题里)默认在首页与归档页输出全文,对任何想要做 SEO 与降低跳出率的站长都是个问题:列表页内容重复度极高、用户首屏看不到几篇文章、Google 容易把列表页与正文页判定为内部重复内容。本文详细讲清把 Twenty Fifteen 改成摘要展示的多种实现方式(修改主题文件、代码片段过滤器、子主题、插件方案),覆盖摘要长度自定义、阅读更多链接样式、首图保留与摘要英文连字符号尾部 […] 替换等实战细节,并扩展到自定义字段摘要、SEO 评估与索引去重。
为什么默认全文输出对 SEO 不友好
列表页与正文页内容重叠度
Twenty Fifteen 默认在 index.php 与 archive.php 通过 get_template_part('content', get_post_format()) 加载 content.php,content.php 里的内容输出走 the_content() 函数——这是输出文章正文全部内容的函数。结果就是首页第一屏只能放一篇文章,归档页前几屏也是少数几篇全文堆砌,列表页与正文页文字内容重合率超过 90%。
Google 的 SpamBrain 与 Helpful Content 算法对内部重复内容的容忍度比 2018 年前低很多。同站内多个 URL 输出相同段落,会让 Google 抽样后挑一个 URL 索引,其它 URL 进入「Crawled but not indexed」状态。这种内部重复在数据上的表现就是「站点收录率持续下滑、爬虫预算被浪费在重复页面」。
跳出率与首屏可消费内容
列表页是用户决策入口(看到摘要选择是否点进正文)。全文输出意味着用户在列表页就看完文章,没有点击行为,反而拉低站点的总浏览深度。摘要列表的转化率(列表 → 详情页点击)平均比全文列表高 60-120%,对依赖广告位 / 站内推荐的博客至关重要。
方案一:修改主题文件(最基础但有升级风险)
改主页与归档
编辑 wp-content/themes/twentyfifteen/index.php 与 wp-content/themes/twentyfifteen/archive.php,找到这一行:
get_template_part( 'content', get_post_format() );替换为:
get_template_part( 'content-search', get_post_format() );原理:WordPress 的 get_template_part 函数按文件名加载模板片段。content.php 是默认输出全文的模板,content-search.php 是搜索结果用的摘要模板,它内部用 the_excerpt() 而不是 the_content()。这一改动等于把列表页的渲染指针从「全文模板」转向「摘要模板」。
搜索页保持原状(如果想区分)
由于第一步把 content-search.php 占用了「主页/归档/搜索」三种用途,三者展示一致。如果你希望搜索结果用更精简的摘要而主页/归档用稍长的摘要,需要复制 content-search.php 一份重命名为 content-excerpt.php,把第一步的替换改为 content-excerpt。
改摘要字数
WordPress 的默认摘要长度是 55 个英文单词,对中文展示偏短(约 80-100 个汉字,到不了 2 行半)。修改方式有两种:
临时改法(不推荐):编辑 wp-includes/formatting.php 找到:
$excerpt_length = apply_filters( 'excerpt_length', 55 );把 55 改成你想要的字数(比如中文 200 字)。这种改法每次 WordPress 升级都会被覆盖。
推荐改法:在主题的 functions.php 里加 filter:
function custom_excerpt_length( $length ) {
return 80; // 中文站建议 80-150 个词,英文站 30-50
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );优先级 999 确保你的过滤器在主题或其它插件之后执行。
这种方案的最大问题:升级被覆盖
主题文件直接编辑后,下次 WordPress 自动更新 Twenty Fifteen 主题(大版本更新时偶有发生)会把你的改动覆盖掉。所以这种方案只适合「明确不再升级 Twenty Fifteen」的项目。
方案二:子主题(Child Theme)— 强烈推荐
子主题是 WordPress 官方的覆盖机制
子主题的核心思想:把要改的文件复制到子主题目录,WordPress 加载时优先用子主题的同名文件。父主题升级不影响子主题。
创建子主题的最小结构
wp-content/themes/twentyfifteen-child/
├── style.css
├── functions.php
├── index.php # 复制并修改
└── archive.php # 复制并修改style.css 必须的注释头
/*
Theme Name: Twenty Fifteen Child
Template: twentyfifteen
Version: 1.0
*/Template 字段必须严格等于父主题目录名,不然 WP 后台主题列表不识别。
functions.php 加载父主题样式
<?php
add_action( 'wp_enqueue_scripts', 'twentyfifteen_child_styles' );
function twentyfifteen_child_styles() {
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
wp_enqueue_style( 'child-style', get_stylesheet_uri(), array('parent-style') );
}
function custom_excerpt_length( $length ) {
return 80;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );复制 index.php 与 archive.php 进行修改
把父主题的 index.php 与 archive.php 整体复制到子主题目录,然后做方案一第一步的替换。后续父主题升级,你的子主题文件不动。
启用子主题
WP 后台 - 外观 - 主题,启用 Twenty Fifteen Child。所有改动立即生效。
方案三:纯 functions.php 钩子(不改任何模板文件)
有些场景不便建子主题(比如客户委托的运营帐号没有 FTP 权限),可以用 the_content 钩子在主页/归档自动截断:
function trim_content_for_lists( $content ) {
if ( ( is_home() || is_archive() || is_search() ) && ! is_singular() ) {
$content = wp_trim_words( strip_tags( $content ), 80, '…<a href="' . get_permalink() . '">阅读全文>></a>' );
}
return $content;
}
add_filter( 'the_content', 'trim_content_for_lists' );这个钩子的好处是模板代码不动,只在列表上下文才截断。wp_trim_words() 是 WP 内置函数,按词数(中文按字符数)截断。第三个参数是结尾文本,可以自定义"阅读全文"链接样式。
缺点:strip_tags 会丢掉所有 HTML 标签包括首图。如果你想保留首图配文章预览,需要更复杂的处理(见方案四)。
方案四:保留首图 + 摘要的最佳实践
SEO 视角下"图 + 摘要 + 阅读更多"组合的列表页转化率最高。完整实现:
function smart_excerpt_with_thumbnail( $content ) {
if ( ! ( is_home() || is_archive() || is_search() ) || is_singular() ) {
return $content;
}
global $post;
// 提取首图
$thumbnail = '';
if ( has_post_thumbnail( $post->ID ) ) {
$thumbnail = '<a href="' . get_permalink() . '" class="post-thumbnail-link">'
. get_the_post_thumbnail( $post->ID, 'medium', array('loading' => 'lazy') )
. '</a>';
} else {
// 从正文里抓第一张 img
if ( preg_match( '/<img[^>]+>/i', $content, $matches ) ) {
$thumbnail = '<a href="' . get_permalink() . '">' . $matches[0] . '</a>';
}
}
// 生成摘要文本
$text = wp_trim_words(
strip_shortcodes( strip_tags( $content ) ),
80,
'…'
);
return $thumbnail . '<p>' . $text . ' <a href="' . get_permalink() . '" class="read-more">阅读全文>></a></p>';
}
add_filter( 'the_content', 'smart_excerpt_with_thumbnail', 10 );这段代码做了几件值得讲的事:
- has_post_thumbnail 优先取特色图(最权威),没有则正文里抓首张 img。
- get_the_post_thumbnail 输出符合 WP 标准的 img 标签,自动带 srcset 与 size 属性。
- loading="lazy" 让首屏外的图懒加载,对 LCP 友好。
- strip_shortcodes 在 strip_tags 之前调用,避免短代码留下半截字符。
方案五:手动 excerpt 字段(最优 SEO)
WordPress 文章编辑页有一个"摘要"字段(默认隐藏,需要在右上角"显示选项"勾选)。每篇文章手动填写一段摘要,WP 会优先用这个字段而不是自动截断。
为什么手动 excerpt 更好
三个理由:
- SEO 价值最高:手动 excerpt 通常会同时填进 meta description,让搜索引擎抓到精炼的页面摘要,CTR 比自动截断高 20-40%。
- 避免截断在不合适的位置:自动截断可能停在「但是」「然而」这种半句,读者读到一半莫名其妙。
- 兼容多平台分发:摘要字段也是 RSS、社交媒体卡片、邮件订阅的标准来源。
用代码强制要求每篇填 excerpt
团队博客可以在保存文章前校验:
function require_excerpt_on_publish( $data, $postarr ) {
if ( $data['post_status'] === 'publish' && $data['post_type'] === 'post' && empty( $data['post_excerpt'] ) ) {
wp_die( '请填写文章摘要后再发布。' );
}
return $data;
}
add_filter( 'wp_insert_post_data', 'require_excerpt_on_publish', 10, 2 );摘要尾部 [...] 的替换
WordPress 自动摘要默认尾部是 […] 字符,用户看不出这是「省略」还是「错误」。改写:
function modify_excerpt_more( $more ) {
return '…<a class="read-more" href="' . get_permalink() . '">阅读全文>></a>';
}
add_filter( 'excerpt_more', 'modify_excerpt_more' );注意 excerpt_more 只对自动生成的摘要生效,手动填写的摘要不会被这个钩子改写。
更专业的 More 标签精确控制
WP 文章编辑器里可以用 <!--more--> 标签精确指定文章在哪一段截断进入摘要。这种用法对长文最友好——你可以让前两段(导言)作为摘要,从第三段开始才是正文。
调用方式不变(仍然是 the_content),但需要在主题列表上下文里加 More 链接处理:
add_filter( 'the_content_more_link', function( $more_link, $more_link_text ) {
return ' <a href="' . get_permalink() . '#more" class="more-link">阅读全文>></a>';
}, 10, 2 );插件方案
如果不想写代码,有几个成熟插件:
- Advanced Excerpt:摘要长度、保留 HTML 标签、阅读更多文案、是否结束在完整词等都有可视化设置。
- Excerpt Editor:专注摘要字段编辑界面增强。
- Display Posts:通过短代码 [display-posts excerpt="true" image_size="medium"] 在任意页面手动嵌入摘要列表。
插件方案的代价是多一份外部依赖、可能与其它插件冲突、性能稍差。对于小博客够用,对中大型站点不如自己写子主题代码可控。
SEO 角度的进阶配置
列表页 noindex 减少索引浪费
即便改成摘要,列表页本身仍是「重复内容索引」的潜在源头。如果列表页对站内搜索价值不大(多数博客是这种情况),可以让列表页 noindex 而 follow,让爬虫顺着链接走但不收录列表页本身。Yoast SEO 与 Rank Math 都有这个开关。手写代码:
function noindex_archive_lists() {
if ( is_home() || is_archive() || is_paged() ) {
echo '<meta name="robots" content="noindex,follow">';
}
}
add_action( 'wp_head', 'noindex_archive_lists' );注意:首页(is_home)通常不该 noindex,是品牌词主要落地页。要单独排除:
if ( ( is_archive() || is_paged() ) && ! is_home() ) { ... }每篇摘要的 schema.org 标记
列表页生成的卡片可以加 itemtype="https://schema.org/BlogPosting",让 SERP 富片更友好:
<article itemscope itemtype="https://schema.org/BlogPosting">
<a href="..." itemprop="url">
<img src="..." itemprop="image">
</a>
<h2 itemprop="headline">...</h2>
<p itemprop="description">摘要文本...</p>
<time itemprop="datePublished" datetime="...">...</time>
</article>分页列表的 canonical 与 prev/next
归档页第 2、3 页(example.com/page/2/、page/3/)的 canonical 应指向自身而不是首页(这是 WordPress 默认行为已经正确)。可以额外加 rel="prev" / rel="next" 链接(WordPress 5.x 移除了这个自动注入,需要手动加回去):
function add_paginate_link_tags() {
global $wp_query;
if ( !is_home() && !is_archive() ) return;
$current = max( 1, get_query_var('paged') );
$total = $wp_query->max_num_pages;
if ( $current > 1 ) echo '<link rel="prev" href="' . get_pagenum_link( $current - 1 ) . '">';
if ( $current < $total ) echo '<link rel="next" href="' . get_pagenum_link( $current + 1 ) . '">';
}
add_action( 'wp_head', 'add_paginate_link_tags' );样式调整:让摘要列表看起来更专业
子主题的 style.css 加:
.entry-summary, .entry-content {
font-size: 16px;
line-height: 1.7;
color: #333;
}
.read-more {
display: inline-block;
margin-top: 10px;
padding: 6px 14px;
background: #4a90e2;
color: white;
border-radius: 4px;
text-decoration: none;
transition: background 0.2s;
}
.read-more:hover {
background: #357abd;
}
.post-thumbnail-link img {
width: 100%;
height: auto;
border-radius: 4px;
}
@media (min-width: 768px) {
.post-thumbnail-link {
float: left;
margin-right: 20px;
max-width: 240px;
}
}性能影响评估
改成摘要后页面体积变化:单文章 5000 字 + 3 张图,全文模式约 80KB;摘要模式(80 字 + 1 张缩略图)约 15KB。10 篇列表页就能省下 600KB+ 流量。
LCP 指标变化:全文模式因为要加载多张正文图,LCP 通常 3-5 秒;摘要模式 LCP 1.5-2.5 秒,对核心 Web Vitals 评分提升明显。
常见故障
故障 1:改完之后摘要还是全文
三个排查:浏览器缓存(强制刷新或换无痕窗口);WP 缓存插件(W3 Total Cache、WP Rocket 等)需要手动清缓存;OPcache 可能缓存了 PHP 旧字节码(重启 PHP-FPM)。
故障 2:摘要里出现奇怪的字符 […]
是 […] 字符的 HTML 实体编码。在主题 functions.php 里用 excerpt_more 钩子覆盖即可,本文已有示例。
故障 3:手动 excerpt 不生效
多数情况是 the_excerpt() 没被调用(你的列表模板还在用 the_content())。检查方案一第一步是否真的把 content 替换成了 content-search 或 content-excerpt。
故障 4:摘要字数被截断到 0
excerpt_length 钩子如果返回 0 或负数,会输出空摘要。检查 functions.php 是否有冲突的 filter(特别是某些插件)覆盖了你的设置。优先级数字大(999)会在小数字后执行,确保最后赢的是你的代码。
故障 5:分页列表页第 2 页之后摘要变成全文
少数主题在分页时不走 index.php 而是走 paged.php 或自定义模板。把方案一的替换在所有相关模板(index.php、archive.php、author.php、search.php、tag.php、category.php)都做一遍。
故障 6:升级 WordPress 后所有改动消失
说明你修改的是 wp-includes/formatting.php 或父主题文件,被升级覆盖。改用方案二(子主题)+ 方案四(functions.php 钩子)的组合,不动任何 WordPress 核心或父主题文件。
故障 7:摘要保留了一半 HTML 标签变形
wp_trim_words 在保留 HTML 时不智能(可能把 <p> 截断为 <p)。如果一定要保留 HTML,先用 force_balance_tags() 函数补全:
$text = force_balance_tags( $trimmed_html );常见问题解答
子主题与直接改父主题有什么区别?
子主题的改动不会被父主题升级覆盖。子主题与父主题的同名文件,WordPress 优先加载子主题的。这是 WP 官方推荐的主题定制方式。直接改父主题升级一次就丢一次。
摘要长度该设多少?
中文站点 80-150 个字符(约 2-3 行),英文站点 30-50 个词。具体取决于列表页设计:宽屏带特色图的列表 80 字够用;窄屏纯文本列表可以 150 字。
手动 excerpt 与自动 excerpt 哪个更好?
手动 excerpt 更好,但每篇都要填工作量大。建议组合策略:核心文章手动填,长尾文章用自动截断兜底。可以再加一段代码让没填手动 excerpt 的文章用前 N 字符自动生成。
列表页改摘要后跳出率反而上升了?
少数情况会发生。原因:摘要质量太差(尾部突然截断、没有钩子让用户想点击)。检查摘要是否在合理位置截断、是否有清晰的"阅读全文"CTA、首图是否有吸引力。改进点而不是回退到全文。
RSS 输出要不要也改成摘要?
视读者群定。如果你希望读者尽可能在 RSS 阅读器里看完不必回访站点,用全文 RSS;如果你希望 RSS 引流回站,用摘要 RSS。WP 后台-设置-阅读 里有切换开关。
列表页 noindex 会不会让站点被惩罚?
不会。列表页 noindex 是行业标准做法(多数 SEO 插件默认勾选)。你只是告诉 Google「这些页面不想被索引」,不影响内容页的索引与排名,反而会让爬虫预算集中在内容页上。
为什么 wp_trim_words 中文截断不准?
wp_trim_words 默认按空格分词,对没有空格的中文文本会把整段当成一个词,截断不出来。WordPress 5.x 起默认对中文做了 mb_strimwidth 处理,但部分老版本仍有问题。如果遇到不准,手动调用 mb_substr:
$text = mb_substr( strip_tags($content), 0, 80, 'UTF-8' );Twenty Fifteen 是不是已经过时了?
Twenty Fifteen 仍能在 WP 6.x 上正常运行,但已不是主推主题。WP 当前推荐 Twenty Twenty-Four 这类基于 Block Editor / FSE(Full Site Editing)的现代主题。如果是新站建议直接选现代主题,列表页摘要在 FSE 主题里可以可视化配置无需改代码。
能否让某些文章保持全文输出而其它走摘要?
可以。在 the_content 钩子里用 has_category 或自定义字段判断:
if ( get_post_meta( $post->ID, '_force_full_content', true ) ) {
return $content; // 不截断
}编辑文章时通过自定义字段设置 _force_full_content=1 即可。
修改主题 PHP 后白屏怎么办?
说明 PHP 语法错误。在 wp-config.php 加 define('WP_DEBUG', true); 与 define('WP_DEBUG_DISPLAY', true); 让错误信息显示在页面上。或者通过 FTP 把改动文件回滚到改动前版本。修复后立刻关闭 WP_DEBUG 避免线上暴露错误细节。
感谢博主提供,解决了我一直想解决的问题