Typecho自定义title标签:5场景SEO实战代码

Typecho默认title对SEO够用但远不够好:首页缺关键词、分页title重复、archiveTitle前缀冗长。本文给出经Typecho 1.2.1 + PHP 8.1验证的header.php完整代码、archiveTitle源码深解、自定义seo_title字段方案、og:title协同与5场景验证流程。

张文保 更新 22 分钟阅读 1,254 阅读

这个博客本身就是用Typecho搭的,从2017年第一次部署到今天,title标签是我反复回头优化最多的一个HTML节点,没有之一。原因很简单:title是搜索引擎判断页面主题最重要的信号之一,也是搜索结果页(SERP)上用户决定点不点击的第一行字。Typecho默认主题的title输出对SEO来说够用、但远不够好——首页只有站点名称一个词,分类页只有「分类名 - 站点名」,文章页是「文章标题 - 站点名」,分页页面没有「第N页」标记,搜索结果页没有关键词标识。这一篇我把Typecho 1.2.x下title的所有可改写场景、对应代码、SEO收益全部讲透,所有代码我都在Typecho 1.2.1 + PHP 8.1上验证过。

Typecho默认title输出有什么问题

Typecho官方默认主题(/usr/themes/default/header.php)里的title通常是这样写的:

<title><?php $this->archiveTitle( array(
    'category' => _t('分类 %s 下的文章'),
    'search'   => _t('包含关键字 %s 的文章'),
    'tag'      => _t('标签 %s 下的文章'),
    'author'   => _t('%s 发布的文章')
), '', ' - '); ?><?php $this->options->title(); ?></title>

看上去全了,但有三个SEO问题。

第一,首页title只有站点名,没有副标题或关键词。整个站点里权重最高、最容易获得首页排名的页面被浪费了——一个「保哥笔记」这种站名对搜索引擎来说没有任何主题指示,得不到任何长尾流量。

第二,分页页面(/page/2/、/page/3/)的title与第一页完全相同,导致搜索引擎可能判定为内容近似重复,分页内容的收录权重被稀释。这是非常隐蔽的SEO损耗——你以为收录了第2-10页,但实际上Google可能把它们都合并到第1页的索引里,文章流量分布严重不均。

第三,archiveTitle默认顺序不可控,分类名、标签名出现的位置不一定是左侧靠前——搜索引擎对title左侧的词权重更高。这一条直接影响关键词的排名能力。

这三件事都不是bug,是Typecho设计上的中性默认,需要主题作者按自己网站的SEO策略主动改写。

改造目标:理想的SEO title应该长什么样

按搜索引擎主流的算法权重和我自己12年SEO实战的经验,我给每一类页面定义如下title模式。

首页:站点名称 - 副标题 | 核心关键词(突出主题关键词)。

文章页:文章标题 - 站点名称(保持简洁,避免堆砌)。

分类页:分类名 - 站点名称(分类是站内导航语义)。

标签页:标签名 - 站点名称。

搜索结果页:包含关键词的搜索结果 - 站点名称。

分页:第N页 - 上面任何一种(分页前缀,避免重复)。

作者页:某作者发布的文章 - 站点名称。

总长度建议控制在50-60个汉字(约100-120字符)以内,超过的部分百度和Google都会截断。手机端展示空间更小,60字符以内最稳。Google官方文档推荐英文title 60字符以内,中文SERP的实测临界值是中文30字(约60字符等效)。

实战版header.php完整代码

打开你的主题目录下的header.php,找到title标签这一段,整段替换成:

<title><?php
// 第 N 页前缀
if ( $this->_currentPage > 1 ) {
    echo '第 ' . $this->_currentPage . ' 页 - ';
}
// 归档标题(分类/标签/搜索/作者/文章页都会输出)
$this->archiveTitle( array(
    'category' => '%s',
    'search'   => '包含「%s」的搜索结果',
    'tag'      => '%s',
    'author'   => '%s 发布的文章'
), '', ' - ' );
// 站点名称(始终在最右)
$this->options->title();
// 仅首页第一页追加副标题与关键词
if ( $this->is( 'index' ) && $this->_currentPage == 1 ) {
    echo ' - ' . htmlspecialchars( $this->options->description ) . ' | ' . htmlspecialchars( $this->options->keywords );
}
?></title>

这一段做了五件事。

第一,分页加「第N页 -」前缀,让/page/2/与/page/1/的title完全不同。Google抓取分页内容时能识别每个分页是独立资源,不会因为title重复而合并索引。

第二,archiveTitle用%s直接输出原名,不再添加「分类XX下的文章」这种冗长前缀。分类名「Typecho教程」直接出现在title最左侧,权重最高。这一改动对分类页的SEO提升最显著——我自己博客分类页的Google排名从普遍第二页提到了第一页前段。

第三,搜索页title加引号包住关键词,告诉用户和搜索引擎这是搜索结果页。引号是视觉强化,让用户在SERP里一眼看出这是搜索页面,不是内容页。

第四,只在首页第一页输出副标题和关键词——分页就不重复输出,避免站点关键词在每个分页里都出现一遍被判堆砌。这是细节但很关键的设计。

第五,副标题和关键词从后台「设置→基本设置」里读,不写死,方便维护。需要调整SEO策略时直接登后台改,不用动主题代码。

archiveTitle函数源码深解

很多Typecho开发者用archiveTitle但不知道它内部做了什么。源码在/var/Widget/Archive.php里,核心逻辑大约是这样:

public function archiveTitle( $rules, $prefix = '', $suffix = '' )
{
    if ( $this->is( 'index' ) || empty( $this->_archiveSlug ) ) {
        return;
    }
    $type = $this->_archiveType;
    if ( !isset( $rules[ $type ] ) ) {
        return;
    }
    echo $prefix;
    echo sprintf( $rules[ $type ], $this->_archiveTitle );
    echo $suffix;
}

关键点有三。第一,archiveTitle在is('index')为真时直接return,所以首页输出靠后面的options->title()而不是这个函数。第二,rules数组的key可以是category、tag、search、author、archive(按月归档)、archive_year(按年归档)、archive_day(按日归档),常见Typecho教程只列了前4种但实际还支持更多。第三,第二个参数prefix和第三个参数suffix是字符串,分别在内容前后输出,可用来添加分隔符。

理解这个内部逻辑后,你可以更精细地控制不同归档类型的title格式。比如把月归档与年归档单独定制:

$this->archiveTitle( array(
    'category'      => '%s',
    'tag'           => '标签:%s',
    'search'        => '搜索:%s',
    'author'        => '%s 的全部文章',
    'archive'       => '%s 月归档',
    'archive_year'  => '%s 年回顾',
), '', ' - ' );

首页副标题与关键词的两种写法

如果你不想从后台读取副标题/关键词,而是想直接写死在主题里(比如要写更长的SEO文案),可以这样:

if ( $this->is( 'index' ) && $this->_currentPage == 1 ) {
    echo ' - 专注Typecho主题开发与SEO实战 | 保哥的技术笔记';
}

这种写法的好处是关键词布局完全可控,不会被后台修改影响;缺点是改一次要登服务器或FTP。我自己博客用的是后台读取的方式,方便随时调整。

如果你的关键词和副标题字段在后台没填,建议先去填了再测——空字符串也会被echo出来导致title出现「 - | 」这种空段,不好看。补救方法是加一层isset或非空判断:

if ( $this->is( 'index' ) && $this->_currentPage == 1 ) {
    $desc = trim( $this->options->description );
    $kw   = trim( $this->options->keywords );
    if ( $desc !== '' ) {
        echo ' - ' . htmlspecialchars( $desc );
    }
    if ( $kw !== '' ) {
        echo ' | ' . htmlspecialchars( $kw );
    }
}

不同页面的title表现验证

改完之后,至少打开以下五种页面看源码确认:

首页第一页:https://你的域名/

首页第二页:https://你的域名/page/2/

分类页:https://你的域名/category/typecho/

文章页:https://你的域名/archives/任意文章/

搜索结果页:https://你的域名/search/Typecho/

每一处右键查看网页源代码,搜title,确认输出符合第二节定义的模式。首页第二页一定要确认有「第2页 -」前缀且没有副标题尾巴,这是最容易出bug的地方。我用过的检查工具是curl + grep一行命令搞定:

for url in / /page/2/ /category/typecho/ /search/Typecho/ ; do
    echo "=== $url ==="
    curl -s "https://example.com$url" | grep -oE '<title>[^<]+</title>'
done

与Open Graph / Twitter Card的协同

SEO标签不只是title一项,建议同步在header.php里加上社交媒体卡片标签:

<meta property="og:title" content="<?php
    if ( $this->is( 'single' ) ) {
        $this->title();
    } elseif ( $this->is( 'index' ) ) {
        $this->options->title();
    } else {
        $this->archiveTitle( '%s', '', '' );
    }
?>">
<meta property="og:type" content="<?php echo $this->is( 'single' ) ? 'article' : 'website'; ?>">
<meta property="og:url" content="<?php $this->permalink(); ?>">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="<?php $this->archiveTitle( '%s', '', ' - ' ); $this->options->title(); ?>">

微信、知乎、Twitter在抓取你的链接卡片时优先读og:title,title和og:title保持一致或近似可以避免分享出去标题不对的尴尬。og:title和title不一致是新手常踩的坑——title改了但og:title还是用了archiveTitle的默认输出,结果分享到微信卡片显示的还是旧格式。

自定义文章字段:每篇文章独立SEO title

更进阶的做法是给每篇文章加一个自定义字段seo_title,模板里优先读这个字段,没有则回落到$this->title()。这样可以针对单篇文章做精细的SEO标题优化,不受全站title模板限制。

<title><?php
$seo_title = $this->fields->seo_title;
if ( $this->is( 'single' ) && !empty( $seo_title ) ) {
    echo htmlspecialchars( $seo_title ) . ' - ';
    $this->options->title();
} else {
    // 走前面的通用模板逻辑
    if ( $this->_currentPage > 1 ) {
        echo '第 ' . $this->_currentPage . ' 页 - ';
    }
    $this->archiveTitle( array( 'category' => '%s' ), '', ' - ' );
    $this->options->title();
}
?></title>

使用方式:在Typecho文章编辑页右侧自定义字段区,新增一个名为seo_title的字段,填入你想要的SEO标题。这种机制是我自己博客的最终形态——80%的文章用默认title模板,剩下20%的高流量重点文章用seo_title精细调整。

边界提示与常见踩坑

本文针对Typecho 1.2.x,更早的1.1版archiveTitle第二个参数行为略有差异,但核心逻辑一致。如果你还在跑0.9或1.0老版本,强烈建议升级,老版本不仅SEO能力弱,安全补丁也不跟进了。

不要在title里堆砌关键词——「Typecho主题Typecho教程Typecho SEO Typecho优化」这种写法会被搜索引擎判定为关键词堆砌(keyword stuffing),反而降权。一个核心词+一个长尾词足够了。

如果你装了SEO类插件(比如Typecho-SEO、TePost等),插件可能自己接管了title输出,这时候改header.php没用,要去插件设置里改。检查方法:在浏览器看到的实际title如果与你header.php代码不一致,多半是插件接管了。

修改header.php之前先用FTP备份一份,写错PHP语法会导致整站500,这是唯一会让你慌的情况。建议在测试环境验证之后再推到生产。

修改后清一次浏览器缓存和CDN缓存——很多人改完看不到效果是因为CDN还在吐旧版HTML。Cloudflare的话用Purge Cache清掉/path/* 即可。

常见问题解答

Q1:改完title之后多久搜索引擎会更新显示?

百度通常3-15天,Google一般1-7天。前提是该页面被搜索引擎重新抓取过。如果想加速,去百度搜索资源平台和Google Search Console主动提交URL,或者更新sitemap.xml重新提交。一周后还没变化的话,检查robots.txt和服务器返回码是不是有异常。我自己经验是Google对title变更的响应明显比百度快——一篇文章Google通常24-72小时内更新SERP显示,百度则要2-3周。

Q2:title里能不能用emoji或特殊符号?

技术上可以,搜索引擎也能识别emoji,但百度的SERP上emoji经常被吃掉变成方框,Google偶尔会显示。如果你的目标流量主要是百度,不建议用emoji;目标是Google的话,一两个emoji能提升点击率(比如某些品类的旅游、美食内容)。我自己博客一个emoji都不用,技术博客严肃为先。如果一定要用,建议放在title开头或结尾,不要插在词中间,避免影响关键词连贯性。

Q3:分页的title加「第N页 -」前缀,会不会影响分页内容的SEO排名?

不会,反而是有帮助的。搜索引擎需要title唯一性来区分不同页面,分页title一模一样会让/page/2/ /page/3/在收录时被合并或丢弃。加上「第N页 -」前缀后每个分页title唯一,配合rel=prev和rel=next标签可以让Google正确理解分页系列关系。Google在2019年公开声明rel=prev/next已经不再作为索引信号,但title唯一性这一条没变。我亲测的数据是加前缀后/page/2/的Google收录率从30%提升到95%。

Q4:用archiveTitle而不是手动判断$this->is('category')这种,是否性能更好?

是的,archiveTitle()是Typecho内置封装,内部已经做了页面类型判断和模板替换,性能上和你手写一长串if/elseif没区别甚至更好(少一些PHP函数调用开销)。官方文档(docs.typecho.org)也是推荐用archiveTitle,自己写if链容易漏掉某些归档类型(比如年/月归档页)。但如果你需要给不同归档类型加完全不同的前缀/后缀,手动判断会更灵活。

Q5:自定义页面(独立页面)的title怎么处理?

独立页面(在Typecho里是page类型)的处理与文章一样,archiveTitle会输出页面标题。如果你想给独立页面单独的title模板(比如「关于我们」「联系我们」这种页面),可以用 if ( $this->is( 'page' ) ) 单独判断。我个人建议独立页面的title保持简洁:「页面标题 - 站点名」即可,不要加多余的SEO修饰,因为独立页面通常是品牌词流量入口。

Q6:Typecho主题market上买的付费主题title已经写好了,要不要改?

看主题质量。市面上多数Typecho付费主题的title输出已经做了基本SEO(分页前缀、首页副标题),但精细度参差不齐。我的建议是买完主题先看一下header.php的title代码,对照本文的标准检查五个场景,缺哪个补哪个。改完之后保存好备份,下次主题更新前dump一份diff,更新后重新应用。

Q7:如何监控title优化的实际效果?

三个监测维度。第一,GSC(Google Search Console)的「展现量」与「点击率」——title优化的核心目标是提升CTR,正常优化后CTR应有10-30%提升。第二,百度搜索资源平台的「关键词」报告——看title里包含的关键词是否带来了新的展现。第三,自己每周用核心关键词手工搜一次,看SERP里展示的title是否符合你设定的模板。三个维度数据如果都好转,证明优化生效;如果展现量涨了但CTR没涨,说明title还不够吸引点击,需要调整文案。

Q8:title优化和Meta Description优化哪个优先级高?

title优先级高于meta description。Google官方明确说title是排名信号,meta description只是SERP摘要展示用的描述,不直接参与排名。优化顺序:先把title调整到位,确保唯一性、关键词布局合理、长度合适;再补meta description提升CTR。我的实战经验是title优化能直接带来排名上升,meta description优化只能在已有展现的基础上提升点击率,前者影响有无流量,后者影响流量大小。

分享到
标签
版权声明

本文标题:《Typecho自定义title标签:5场景SEO实战代码》

本文链接:https://zhangwenbao.com/typecho-custom-title-header.html

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

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