Typecho首页分类页文章摘要截取:excerpt与more标签自定义字数实战

Typecho 默认在首页和分类页输出全文,篇幅冗长还拖慢加载。本文给出两种摘要方案:把 content 调用换成 excerpt,或在写文章时插入 more 标签,自由控制摘要字数和截断位置,让列表页清爽起来。

张文保 更新 14 分钟阅读 2,190 阅读

引言:为什么我把这个细节单独写一篇

我是保哥,这个博客本身就是 Typecho 搭的。首页和分类页要不要显示文章全文,是 Typecho 站长第一周就会遇到、但很多人三年后还没完全搞清楚的问题。默认主题(比如官方的 default、Mirages、Handsome)行为不一致——有的全文输出,有的只输出 <!--more--> 之前的部分,导致换主题之后首页要么变得超长加载缓慢,要么摘要被无脑截断把关键信息切没了。

这一篇我把 Typecho 1.2.x 版本下,首页/分类页/标签页/搜索页文章内容截取的所有可用方法、它们的差异、以及对 SEO 与用户体验的影响全部讲清楚。所有代码我都在 Typecho 1.2.1 + PHP 8.1 环境下跑过。

一、先弄清楚 Typecho 的两个核心方法:content 与 excerpt

Typecho 在文章列表(首页/分类页/标签页)上输出文章正文,可选的核心方法只有两个:$this->content()$this->excerpt()。它们的区别是大部分新手没搞清楚的:

  • $this->content('阅读剩余部分...'):默认输出全文;只有当文章里写了 <!--more--> 标签时,才会在该标签处截断,并把参数字符串作为「阅读全文」链接的文字显示。
  • $this->excerpt(N, '...')强制截取前 N 个字符,不管文章里有没有 <!--more-->。N 默认是 100,第二个参数是省略号文字。

关键差异content 会保留 HTML 标签和图片、excerpt 会把 HTML 全部剥掉变成纯文本。这意味着——

  • 想让首页保留排版(图片、标题、加粗):用 content + <!--more-->
  • 想让首页是纯文本摘要、统一长度:用 excerpt

二、最常见改法:把 content 替换成 excerpt

打开你当前主题目录下的 index.php(一般在 /usr/themes/你的主题/index.php),找到这一行:

<?php $this->content('阅读剩余部分...'); ?>

替换成:

<?php $this->excerpt(); ?>

这是默认的 100 字纯文本摘要。如果觉得太短,加参数:

<?php $this->excerpt(200, '...'); ?>

200 个字符,结尾用「...」。对中文来说,Typecho 的 excerpt 按字符数(mb_strimwidth 风格)计算,一个中文字符 = 1,长度直观

注意改完之后别忘了 archive.phpcategory.phptag.phpsearch.php 也都要改,否则只改了首页,分类页还是全文。我一般直接全局搜索 $this->content 替换。

三、用 <!--more--> 标签精确控制截断点

如果你想保留首页排版(图片 + 排版样式),又想自己决定每篇文章在哪里截断,正确做法是保留 $this->content() 不动,在写文章的时候手动插 <!--more-->

比如这样:

这是文章引言,用来吸引读者点开。

第二段继续讲背景。

<!--more-->

这部分只在文章详情页出现,首页看不到。

首页只显示 <!--more--> 之前的两段,并自动加一个「阅读剩余部分...」的链接。这种方法的好处

  • 排版完全由你控制,图片、列表、代码块都能保留。
  • 每篇文章可以有不同的摘要长度——长文章截多点,短文章不截。
  • 对 SEO 友好:首页输出的是真实的文章开头,不是被机器截断的半句话。

Typecho 官方文档(docs.typecho.org)也是推荐这种写法的。

四、自定义截取函数:超越内置 excerpt 的限制

内置 excerpt 有两个让人不爽的地方:

  1. 会剥掉所有 HTML,包括你想保留的图片和加粗。
  2. 不智能——刚好截到一个英文单词中间也照样切。

如果你想要「保留图片但限制段数」或者「按句号截断」的效果,需要在 functions.php 里写自定义函数。我常用的一个:

<?php
function theme_smart_excerpt($content, $maxLen = 200, $suffix = '...') {
    // 保留 img 和 br,去掉其他标签
    $allowed = '<img><br><strong><em>';
    $text = strip_tags($content, $allowed);
    // 把多余空白合并
    $text = preg_replace('/\s+/', ' ', $text);
    // 按字符截断
    if (mb_strlen($text, 'UTF-8') > $maxLen) {
        $text = mb_substr($text, 0, $maxLen, 'UTF-8') . $suffix;
    }
    return $text;
}

index.php 里这样调用:

<?php echo theme_smart_excerpt($this->content, 200); ?>

注意是 $this->content属性,原始内容),不是 $this->content()(方法,会输出 HTML)。这一字之差是 Typecho 模板里最容易踩的坑之一。

五、不同页面用不同截取策略:模板分支

实际项目里,我经常希望首页用 200 字摘要,分类页用 150 字,标签页只显示标题不显示摘要。Typecho 的 archive.php 默认会处理所有归档页面,可以这样写分支:

<?php if ($this->is('index')): ?>
    <?php $this->excerpt(200, '...'); ?>
<?php elseif ($this->is('category')): ?>
    <?php $this->excerpt(150, '...'); ?>
<?php elseif ($this->is('tag')): ?>
    <!-- 标签页不输出摘要 -->
<?php else: ?>
    <?php $this->excerpt(120, '...'); ?>
<?php endif; ?>

$this->is() 支持 indexcategorytagsearcharchivesingle 等参数,是 Typecho 模板的核心 API 之一。

六、SEO 视角:摘要长度怎么选才合理

这一节是这篇文章和其他「Typecho 摘要教程」最大的区别——摘要不是越长越好,也不是越短越好。我从 SEO 实战的角度给几个经验值:

  • 首页摘要 150-250 字符:足够让读者判断是否点击,又不会让首页变成「多篇文章拼起来的长页」导致主题分散。
  • 分类页摘要 100-180 字符:分类页本身已经有分类导航语义,文章列表的每一条是「索引」而不是「内容」。
  • 标签页可以更短甚至不显示:标签页主要是聚合作用,输出过多正文反而稀释主题相关性。
  • 避免在列表页输出全文:搜索引擎会判定首页/分类页与详情页内容高度重复,可能影响详情页排名(即所谓的「站内重复内容」问题)。

如果你已经用 content + <!--more--> 但有的文章忘记加标签,可以在 index.php 里做兜底:

<?php
$content = $this->content;
if (strpos($content, '<!--more-->') === false) {
    // 没有 more 标签,强制截 200 字
    echo theme_smart_excerpt($content, 200);
} else {
    $this->content('阅读剩余部分...');
}
?>

七、修改后必须验证的三件事

改完模板别急着关掉编辑器,至少验证以下三处

7.1 首页源代码长度

浏览器右键「查看网页源代码」,搜索一下首页 HTML 体积。改之前可能 200KB,改成摘要后应该降到 50-80KB。首屏字节数直接影响 LCP(Largest Contentful Paint)指标

7.2 分页是否正常

首页第二页、第三页的 URL(一般是 /page/2//page/3/)打开看摘要逻辑是否一致。

7.3 RSS 输出

Typecho 的 RSS(/feed/)通常输出全文或前 N 条全文,这个跟首页摘要无关;但很多 RSS 订阅工具(如 Feedly)会显示 excerpt,建议同时检查 archive.php 的 RSS 分支。

八、保哥的边界提示

  • 本文针对 Typecho 1.2.x,1.1 老版本部分 API 行为略有差异,比如 excerpt 的中文字符计算曾经按字节算过。
  • 第三方主题(Handsome、Joe 等)通常已经做了完善的摘要逻辑,主题设置里就有「首页摘要字数」选项,不需要改代码——改代码反而会被主题更新覆盖。
  • Markdown 文章中的 <!--more--> 必须独占一行,前后都加空行,否则解析器可能不识别。
  • excerpt 不会保留代码块格式,如果你的博客主要写技术文章,强烈推荐 content + <!--more--> 方案,不要用 excerpt。

九、FAQ:高频问题集中回答

Q1:改了 index.php 但首页还是显示全文,是不是没生效?

几种可能:(1)你改的不是当前启用主题的 index.php——确认下后台「外观」里启用的是哪个主题;(2)页面缓存——如果你装了 TpCache 或类似缓存插件,去插件设置里清一次缓存;(3)改的位置不对——index.php 里可能有多个 $this->content() 调用(比如循环外的某个特殊位置),全局搜一下确保都改了。

Q2:excerpt 输出的内容里有奇怪的乱码或半个字符怎么办?

这是 PHP 的 mb_* 扩展没启用导致的。检查 php.inimbstring 是否开启,并确保 default_charset = UTF-8。Typecho 内部大量依赖 mbstring,没开启会出各种诡异字符问题。

Q3:能不能让首页显示文章封面图 + 摘要?

可以。Typecho 没有内置「特色图」概念,但可以读取文章里第一张图:

<?php
preg_match('/<img[^>]+src=["\'](.*?)["\']/', $this->content, $m);
$cover = $m[1] ?? '/usr/themes/你的主题/img/default.jpg';
?>
<img src="<?php echo $cover; ?>" alt="<?php $this->title(); ?>">
<?php $this->excerpt(180, '...'); ?>

更优雅的做法是用 Typecho 的 fields(自定义字段)功能,给每篇文章手动指定一个 cover 字段。

Q4:从 WordPress 迁过来的博主,excerpt 用法是不是一样?

概念一样,写法不同。WordPress 是 the_excerpt(),Typecho 是 $this->excerpt();WordPress 默认按词数截(55 个英文单词),Typecho 按字符数截(默认 100)。中文站点 Typecho 的字符数计算更直观。

十、总结:摘要策略的三档建议

根据我自己运营技术博客的经验,给三档方案,按你的精力选:

  • 省力档$this->excerpt(200, '...'),全局替换,5 分钟搞定,效果中规中矩。
  • 平衡档:保留 $this->content(),写文章时手动插 <!--more-->,每篇文章定制截断点,效果最好但要求你写每篇文章都记得加标签。
  • 完美档:自定义 theme_smart_excerpt 函数 + 兜底逻辑(第六节代码),首页保留图片和加粗、限制字符数、有 more 标签则按 more 截、没有则按字数截。

我自己用的是「完美档」,代码就放在 functions.php 里,一次写好用三年。Typecho 的好处之一就是模板系统简单直接,所有控制都在 PHP 文件里,没有黑盒,改一行立刻见效——这也是我从 WordPress 转过来之后再没换过的核心原因。

如果你的主题改完之后效果不对,欢迎评论区贴 index.php 关键片段,我帮你看看问题出在哪。

分享到
标签
版权声明

本文标题:《Typecho首页分类页文章摘要截取:excerpt与more标签自定义字数实战》

本文链接:https://zhangwenbao.com/typecho-home-page-category-page-interception-content-article.html

版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交