“我要改页头,改哪个文件?”
“header.php。”
“为什么改了 header.php,所有页面都变了?”
这两个问题我在第一篇提过,但当时只给了结论。这一篇把背后的机制讲透——因为它是整个主题“拼装”思路的核心。
很多人看到 get_header(),以为是“调用一个叫 get_header 的函数,它返回页头的 HTML”。
不是。
它是“把 header.php 这个文件搬到这里来”。
你可以做个实验:打开主题的 header.php,在最后加一行 echo '我在这里';,然后打开任意页面。你会发现这句话出现在页面的最顶端——因为它被“搬”进来了,而不是被“调用”后返回。
这个区别很重要:
顺便说一句,get_header()、get_footer()、get_sidebar() 这三个,底层都是同一个东西:get_template_part() 的简化版。
把主题想成一套乐高:
一个典型的模板(比如 caogenbj 的 index.php),结构是这样的:
<?php get_header(); ?> ← 搬进页头
<div class="row">
<div class="col-md-9"> ← 主体,这里是文章列表
...
</div>
</div>
<?php get_sidebar(); ?> ← 搬进侧栏
<?php get_footer(); ?> ← 搬进页脚
页头、侧栏、页脚,全站只写一份,每个页面都引用。所以你改 header.php,全站都变——因为它本来就只有一份。
有时候同一个站需要两种页头(比如首页一个样式、内页一个样式)。get_header() 可以带参数:
<?php get_header( 'home' ); ?>
这会去找 header-home.php,找不到再退回 header.php。
所以你可以准备两个文件:header.php(默认)和 header-home.php(首页专用),首页模板里调 get_header('home')。
get_sidebar() 和 get_footer() 也支持同样的写法。
讲完机制,说一个我自己主题里的实际问题——这个错很常见,你可能也在犯。
看 caogenbj 的 single.php(文章页)的结尾:
<?php get_sidebar(); ?>
<div class="row">
<div class="col-md-9">
...百度自动推送脚本...
...360 自动推送脚本...
<div class="well well-sm">Powered by ... © 2015-2020 ...</div>
</div>
</div>
<?php wp_footer(); ?>
</body>
</html>
发现问题了吗?它没有调 get_footer(),而是把 footer.php 的内容手抄了一遍。
同样的问题,page.php 里也有。
后果是什么?页脚要改的时候,得改三个地方:footer.php、single.php、page.php。改完还得检查三处是否一致。我这次改版权年份(2015-2020 改成 2015-2026),就改了三遍——漏掉一个,页面上就会出现一个 2020 一个 2026。
这不是“不优雅”的问题,是“维护成本翻倍”的问题。
正确的做法是:single.php 和 page.php 的结尾,只留一行 <?php get_footer(); ?>,把那些手抄的内容全删掉(前提是 footer.php 里已经有了)。
所以我现在正在做的重构,就是把 single.php 和 page.php 里手写的 footer 删掉,统一走 get_footer()。这样以后改页脚,只改一个文件。
因为主题是从别的主题改过来的。原作者可能在 single.php 里图省事,手写了一份 footer,后来改主题的人也没细看,就跟着抄下来了。
这也是我一直在说的:读一个主题,先读它的“重复代码”。重复的地方,往往就是设计没想清楚的地方。
一句话记住:get_header / get_footer / get_sidebar 是“搬文件”,不是“函数调用”;零件只写一份,到处引用。
下一篇讲一个更基础的东西:WordPress 凭什么“认出”一个文件夹是主题?答案是 style.css 开头那段注释。那段注释里,我自己的主题就有三个毛病。