WordPress 经典主题模板文件完全指南

WordPress 主题由一组模板文件构成,它们共同决定了网站的前端展示。这些文件各司其职:有的负责页面结构,有的处理特定内容类型,还有的作为可复用组件被反复调用。理解每个模板文件的用途和编写方法,是构建 WordPress 主题的基础。

这篇文章将围绕 header.php、footer.php、404.php、comments.php、sidebar.php 以及 content-{$slug}.php 这六个核心文件展开。你会看到它们如何协作,如何在适当的位置被加载,以及怎样利用条件标签让同一个文件在不同场景下输出不同内容。无论你是想从零开始开发主题,还是只是好奇 WordPress 主题的运行机制,这篇文章都能给你一个清晰的方向。

文中会穿插 Twenty Fifteen 主题的代码片段作为参考——这是 WordPress 官方维护的默认主题之一,代码规范且结构清晰,非常适合拿来学习。


header.php:页面的门面担当

header.php 负责输出每个页面的顶部区域,包括 DOCTYPE 声明、<head> 中的元数据、样式表链接,以及页眉导航栏。它是一个局部模板,只有通过 get_header() 函数调用时才会被渲染。

绝大多数 WordPress 主题都包含这个文件,因为它把重复的头部代码集中到了一处,维护起来方便很多。

text

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo( 'charset' ); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="profile" href="https://gmpg.org/xfn/11">
    <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
    <?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
    <div id="page" class="site">
        <header id="masthead" class="site-header">
            <div class="site-branding">
                <?php
                if ( is_front_page() && is_home() ) :
                    echo '<h1 class="site-title"><a href="' . esc_url( home_url( '/' ) ) . '" rel="home">' . get_bloginfo( 'name' ) . '</a></h1>';
                else :
                    echo '<p class="site-title"><a href="' . esc_url( home_url( '/' ) ) . '" rel="home">' . get_bloginfo( 'name' ) . '</a></p>';
                endif;
                ?>
            </div>
        </header>

几个关键点:

wp_head() 是一个钩子函数,所有通过 functions.php 注册的样式表、脚本(那些需要在头部加载的)以及各种 SEO 插件添加的元数据,都会在这个位置被注入。缺失这行代码,主题的功能会大打折扣。

body_class() 输出一个包含页面类型、模板名称、用户登录状态等信息的 class 列表。比如在归档页会加上 archive,在单页会加上 single,这些类名让前端样式编写变得异常灵活。

is_front_page() && is_home() 是典型的条件判断。当网站首页同时被设置为显示新文章时,网站标题用 <h1> 包裹;其他情况下用 <p> 包裹。这是一种对 SEO 友好的处理方式。


footer.php:收尾工作

footer.php 用来闭合 header.php 中打开的结构标签,输出页脚区域,并加载页面底部的脚本。它同样需要 get_footer() 主动调用。

text

    </div><!-- #content -->
    <footer id="colophon" class="site-footer">
        <div class="site-info">
            <a href="<?php echo esc_url( 'https://wordpress.org/' ); ?>">
                <?php printf( __( 'Proudly powered by %s', 'textdomain' ), 'WordPress' ); ?>
            </a>
        </div>
    </footer>
    <?php wp_footer(); ?>
</body>
</html>

wp_footer() 和 wp_head() 对应,许多 JavaScript 脚本在这里加载,可以避免阻塞页面渲染。一些统计代码、三方插件的前端逻辑也常常通过这个钩子注入。

页脚通常是放置小工具区域的好地方,很多主题会在这里注册一个或多个侧边栏,让用户可以自由拖拽添加内容。


404.php:给迷路的访客一个交代

当用户访问一个不存在的页面时,WordPress 会尝试加载 404.php。如果没有这个文件,就会回退到 index.php,但这样用户体验很差。一个合格的 404 页面应该友好地告知用户出了问题,并提供导航选项帮他们找到想要的内容。

text

<?php get_header(); ?>
<div id="primary" class="content-area">
    <main id="main" class="site-main">
        <section class="error-404 not-found">
            <header class="page-header">
                <h1 class="page-title"><?php _e( '抱歉,页面找不到了。', 'textdomain' ); ?></h1>
            </header>
            <div class="page-content">
                <p><?php _e( '可能是链接有误,或者页面已被移除。试试搜索吧。', 'textdomain' ); ?></p>
                <?php get_search_form(); ?>
            </div>
        </section>
    </main>
</div>
<?php get_footer(); ?>

这个文件中 get_search_form() 会生成一个搜索框,让访客可以直接搜索站内内容。这是 404 页面常见的配套功能之一。


comments.php:评论区模板

comments.php 专门用来显示文章的评论列表和评论表单。它被其他模板文件通过 comments_template() 调用,而不是 get_template_part()。

评论区的逻辑相对复杂,涉及嵌套评论、分页、审核状态判断等。WordPress 官方推荐在主题中直接使用 wp_list_comments() 和 comment_form() 这两个函数,它们会按照后台设置自动生成评论结构和表单。

一个小化的 comments.php 大致长这样:

text

<div id="comments" class="comments-area">
    <?php if ( have_comments() ) : ?>
        <h2 class="comments-title">
            <?php printf( _n( '一条评论', '%1$s 条评论', get_comments_number(), 'textdomain' ), number_format_i18n( get_comments_number() ) ); ?>
        </h2>
        <ol class="comment-list">
            <?php wp_list_comments( array( 'avatar_size' => 50 ) ); ?>
        </ol>
    <?php endif; ?>
    <?php comment_form(); ?>
</div>

关于评论模板的深入细节,会在专门的章节展开,这里先有个整体印象即可。


sidebar.php:侧边栏组件

侧边栏是 WordPress 小工具系统的载体。使用侧边栏之前,必须先在 functions.php 中注册,然后才能在 sidebar.php 中通过 dynamic_sidebar() 输出。

text

<?php if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
    <aside id="secondary" class="widget-area">
        <?php dynamic_sidebar( 'sidebar-1' ); ?>
    </aside>
<?php endif; ?>

这里的关键是 is_active_sidebar(),它先检查指定的侧边栏里是否真的有内容,如果有才输出 HTML 结构,避免产生空容器。dynamic_sidebar() 则负责渲染该侧边栏中所有已添加的小工具。

侧边栏也可以结合条件标签做灵活控制,比如只在单个文章页显示,或者只在首页显示。


content-{slug}.php:内容片段模板

这类模板文件并不是 WordPress 内置的加载规则,而是主题开发者约定俗成的一种组织方式。{slug} 通常对应页面类型,比如 content-page.php、content-single.php、content-none.php。

它们被 get_template_part() 函数调用:

text

get_template_part( 'content', 'page' );

这句代码会尝试加载 content-page.php,如果不存在则回退到 content.php。

为什么要拆出这些文件?因为不同内容类型的展示方式往往差异很大:

  • 普通页面(page):只需要标题和正文内容
  • 博客文章(post):需要显示发布日期、作者、分类、标签、上下篇导航
  • 作品集项目(portfolio):可能需要展示多张图片或者视频
  • 搜索结果项:只需要展示摘要和链接

把它们拆开,每个文件的职责清晰,代码也更容易维护。

以下是 Twenty Fifteen 中 content-page.php 的简化版:

text

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <header class="entry-header">
        <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
    </header>
    <div class="entry-content">
        <?php the_content(); ?>
        <?php
        wp_link_pages( array(
            'before'      => '<div class="page-links">' . __( 'Pages:', 'textdomain' ),
            'after'       => '</div>',
            'link_before' => '<span>',
            'link_after'  => '</span>',
        ) );
        ?>
    </div>
</article>

the_ID() 输出文章 ID,post_class() 为文章容器添加一系列 CSS 类,比如 post-123、type-page、status-publish 等,方便精细样式控制。wp_link_pages() 处理分页文章内部的多页导航。


总结

WordPress 经典主题的模板文件体系围绕一个核心原则:职责分离,按需加载。

  • header.php 和 footer.php 处理全局结构和头尾区域
  • 404.php 处理异常访问
  • comments.php 专门承载评论功能
  • sidebar.php 作为小工具容器,需要预先注册
  • content-{$slug}.php 是细粒度的内容模板,通过 get_template_part() 调用

这些文件共同构成了主题的前端骨架。wp_head() 和 wp_footer() 是两个至关重要的钩子,缺少任何一个都会导致主题功能残缺。条件标签则让同一个模板文件在不同页面展现出不同的面貌。

理解这套体系,你就已经掌握了 WordPress 主题开发的基本脉络。