搜索全站
主题 13 分钟阅读

WordPress 主题文件结构详解:每个模板文件负责什么

从 style.css、functions.php 到 index/single/page/archive,逐个说明主题目录里每个文件的职责与调用关系,附最小可运行主题示例和后台识别不出来的排查清单。

U
UFO_PF 2017-10-25 · 阅读 13 分钟
Wo 主题
阅读提示
本文约 5,183 字,预计阅读 13 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:解压主题包后,二十多个 php 文件看不懂

下载一个主题解压开,根目录躺着 index.php、functions.php、header.php、footer.php、single.php、page.php、archive.php、404.php、comments.php、searchform.php,还有 inc/、template-parts/、assets/ 三个目录。想改首页 Banner 却不知道该动哪个文件,于是每个都打开看一遍,最后在 header.php 里改了半天,发现首页用的其实是 front-page.php。

理解文件结构不是为了背目录,而是为了知道”改一个地方应该去哪个文件”,以及”新建的文件 WordPress 认不认”。

原理分析:三类文件,三种身份

主题目录里的文件按身份可以分成三类:

类型 文件 作用
必需文件 style.css、index.php 缺一个后台就识别不出主题
功能文件 functions.php、screenshot.png、rtl.css 由 WordPress 按约定名自动加载
模板文件 single.php、page.php、archive.php 等 由模板层级按请求类型挑选

style.css 的头部注释是主题的”身份证”,WP_Theme 类靠它识别主题:

/*
Theme Name:       迷忙飞基础主题
Theme URI:        https://mimangfei.com
Author:           mimangfei
Author URI:       https://mimangfei.com
Description:      一个用于演示主题结构的极简主题
Version:          1.0.0
License:          GNU General Public License v2 or later
License URI:      http://www.gnu.org/licenses/gpl-2.0.html
Text Domain:      mimangfei-basic
Tags:             blog, one-column, custom-logo
*/

子主题与父主题的区别就在这段注释里:多一行 Template: 父主题目录名。functions.php 则是主题唯一的”自动加载入口”,它在 WordPress 初始化早期被包含进来,主题所有的 add_theme_support、菜单注册、脚本加载都写在这里。

模板文件之间不是孤立的,它们通过一套”包含函数”拼装成完整页面:

// 典型 single.php 的骨架
get_header();          // 引入 header.php
?>
<main id="primary" class="site-main">
<?php
while ( have_posts() ) :
    the_post();
    get_template_part( 'template-parts/content', 'single' ); // 引入 content-single.php
    the_post_navigation();
    if ( comments_open() || get_comments_number() ) {
        comments_template();   // 引入 comments.php
    }
endwhile;
?>
</main>
<?php
get_sidebar();         // 引入 sidebar.php
get_footer();          // 引入 footer.php

保姆级实操

第 1 步:搭一个最小可运行主题

只有两个文件也能成为一个主题。新建 wp-content/themes/mmf-basic/style.css(写入上面的头部注释)和 index.php:

<?php
/**
 * 兜底模板:所有请求最终都会落到这里
 */
get_header();
?>
<main id="primary" class="site-main">
    <?php if ( have_posts() ) : ?>
        <?php while ( have_posts() ) : the_post(); ?>
            <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                <div class="entry-summary"><?php the_excerpt(); ?></div>
            </article>
        <?php endwhile; ?>
        <?php the_posts_pagination(); ?>
    <?php else : ?>
        <p><?php esc_html_e( '还没有发布任何内容。', 'mimangfei-basic' ); ?></p>
    <?php endif; ?>
</main>
<?php
get_footer();

再到后台启用它。能显示文章列表,说明结构理解到位了。

第 2 步:补齐通用零件

按需新建,不必一次做全:

文件 何时需要 调用方式
header.php 几乎必须 get_header()
footer.php 几乎必须 get_footer()
sidebar.php 有侧边栏 get_sidebar(),可传参调用 sidebar-shop.php
searchform.php 覆盖默认搜索框 get_search_form()
comments.php 需要评论区 comments_template()
404.php 自定义 404 自动匹配
front-page.php 静态首页专用布局 自动匹配,优先级最高

带后缀的变体用参数调用是这套结构的通用约定:get_header( 'shop' ) 会去找 header-shop.php,找不到再退回 header.php。这条规则对 get_footer()、get_sidebar()、get_template_part() 都成立。

第 3 步:按内容类型拆分列表与详情

index.php      兜底(必须有)
├── home.php           文章列表首页
├── front-page.php     静态首页(优先级高于 home.php)
├── single.php         文章详情
│   └── single-{post_type}.php   自定义类型详情
├── page.php           页面
│   └── page-{slug}.php          指定别名页面
├── archive.php        归档兜底
│   ├── category.php / category-{slug}.php
│   ├── tag.php / tag-{slug}.php
│   ├── author.php
│   ├── date.php
│   └── archive-{post_type}.php
├── search.php         搜索结果
├── attachment.php     附件页
└── 404.php

具体匹配规则见WordPress 模板层级图解,这里只需记住一条:index.php 是最后兜底,缺了它主题不可用。

第 4 步:把可复用片段放进 template-parts/

template-parts/ 不是 WordPress 的硬性约定,而是官方主题(Twenty 系列)带起来的行业惯例。把文章卡片、分页、面包屑这类片段拆进去,再用 get_template_part() 引入,比在每个模板里复制粘贴好维护。

第 5 步:给目录加说明文件与预览图

mmf-basic/
├── style.css          主题身份证 + 主样式
├── functions.php      功能注册入口
├── index.php          兜底模板
├── rtl.css            从右向左语言补充样式(可选)
├── screenshot.png     主题缩略图,建议 1200×900
├── readme.txt         面向 wordpress.org 的说明
├── assets/            css / js / images
├── inc/               辅助函数(自定义器、区块等)
├── template-parts/    可复用模板片段
└── page-templates/    自定义页面模板

screenshot.png 建议 1200×900 像素,太大会拖慢后台主题页加载。子目录一层足够,不要把 inc/ 再套三层——找文件的时间成本比”结构优雅”重要。

常见踩坑

  1. 缺 index.php。 后台主题列表里直接不显示,或提示 The theme is missing the index.php file。
  2. style.css 头部注释格式写错。 少了 */、用了中文冒号、头部前面有多余空行,都会导致 WP_Theme 解析失败,主题显示为无名。
  3. 目录名带中文或空格。 我的主题/ 在部分主机上会让 get_template_directory_uri() 生成的 URL 出现编码问题,一律用小写英文加连字符。
  4. 把业务逻辑全塞进 functions.php。 换主题就全没了。帖子类型、短代码这类应放插件,划分原则见functions.php 与插件职责划分。
  5. header.php 末尾忘了 wp_head()。 插件的样式、统计代码、SEO 标签全部注入失败。
  6. 案例: 某学员新建 single-product.php 想改产品详情页,改完前台毫无变化。排查发现他装的是子目录里的主题,文件被放到了 wp-content/themes/child/single-product.php 之外的 wp-content/ 根目录。更隐蔽的一类情况是文件放对了但文件名大小写不符——Linux 服务器上 Single-Product.php 与 single-product.php 是两个文件,模板层级查的是小写。
  7. 在 style.css 里 @import 一堆子样式。 每个 @import 都是一次串行请求,应改到 functions.php 里用 wp_enqueue_style() 并行加载。

总结

记住三条就够:一、style.css + index.php 是主题存在的最低条件,前者提供身份信息,后者提供兜底;二、functions.php 是唯一的自动加载入口,只放与外观相关的注册逻辑;三、其余 php 文件都是模板零件,通过 get_header() / get_template_part() 这类包含函数拼装,命名规则统一为 {基础名}-{变体}.php,找不到变体就退回基础名。按这三条理一遍任何主题,都能在五分钟内定位到该改的文件。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。