WordPress 主题开发终极指南
这份教程将带你从零开始,构建一个名为 MyAwesomeTheme 的 WordPress 主题,我们将涵盖从基础文件结构到高级功能(如自定义izer、小工具、自定义文章类型)的所有内容。

第一部分:准备工作与基础结构
环境准备
在开始之前,请确保你拥有一个本地或线上的 WordPress 开发环境,推荐使用以下工具:
- 本地服务器环境:
- XAMPP / WAMP / MAMP: 一键搭建 Apache, MySQL, PHP 环境的经典选择。
- Local (by Flywheel): 强烈推荐!专为 WordPress 设计,管理多个站点非常方便。
- 代码编辑器:
- Visual Studio Code (VS Code): 免费、强大,拥有丰富的 WordPress 插件支持。
- Sublime Text / Atom: 也是不错的选择。
创建主题文件夹
在你的 WordPress 安装目录下的 wp-content/themes/ 文件夹中,创建一个新的主题文件夹,我们将其命名为 my-awesome-theme。
/wp-content/
└── /themes/
└── /my-awesome-theme/
必需的文件:style.css 和 index.php
每个 WordPress 主题至少需要这两个文件。
style.css - 主题的“身份证”
这是 WordPress 识别你的主题的核心文件,它必须在文件顶部包含一个特殊的注释块,称为“主题头标”。

在 my-awesome-theme 文件夹中创建 style.css 文件,并填入以下内容:
/*
Theme Name: My Awesome Theme
Theme URI: https://example.com/my-awesome-theme
Author: Your Name
Author URI: https://example.com
Description: A modern, responsive theme for my blog.
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: myawesome
*/
/* 在这里添加你的 CSS 样式 */
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
background-color: #f4f4f4;
color: #333;
}
- Theme Name: 主题在后台显示的名称。
- Text Domain: 用于主题的国际化(翻译),非常重要。
index.php - 主题的“骨架”
这是当没有其他更具体的模板文件(如单篇文章页面 single.php)时,WordPress 默认用来显示内容的文件,它只是一个空的占位符。
在 my-awesome-theme 文件夹中创建 index.php 文件,内容如下:
<?php
// 这行代码是必须的,它告诉 WordPress 这个文件是一个模板
get_header();
?>
<div id="primary" class="content-area">
<main id="main" class="site-main">
<?php if ( have_posts() ) : ?>
<?php if ( is_home() && ! is_front_page() ) : ?>
<header>
<h1 class="page-title screen-reader-text"><?php single_post_title(); ?></h1>
</header>
<?php endif; ?>
<?php
// 开始循环:遍历并显示每一篇文章
while ( have_posts() ) : the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
// 文章分页导航
the_posts_navigation();
else :
// 如果没有找到文章,显示这个内容
get_template_part( 'template-parts/content', 'none' );
endif;
?>
</main><!-- #main -->
</div><!-- #primary -->
<?php
get_sidebar();
get_footer();
?>
代码解释:

get_header(): 加载header.php文件(我们稍后会创建)。have_posts(): 检查是否有文章可以显示。while ( have_posts() ) : the_post();: The Loop (主循环),WordPress 的核心,它会为每一篇文章设置数据,让你可以在循环内调用文章信息(如标题、内容)。get_template_part(): 一个强大的函数,用于加载可重用的模板片段,我们这里会创建一个content.php文件来显示文章内容。the_posts_navigation(): 显示“上一页”/“下一页”的分页链接。get_template_part( 'template-parts/content', 'none' ): 如果没有文章,加载一个“未找到内容”的模板。get_sidebar(): 加载sidebar.php文件。get_footer(): 加载footer.php文件。
第二部分:构建模板文件
现在我们来创建上面代码中引用的其他文件。
header.php - 网站头部
创建 header.php 文件,包含网站的 <head> 部分和页眉内容。
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php wp_head(); // 必须保留,用于加载 WordPress 自动添加的CSS、JS等 ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); // WordPress 5.2+ 推荐使用 ?>
<header id="masthead" class="site-header">
<div class="site-branding">
<?php
if ( has_custom_logo() ) {
the_custom_logo();
} else {
// 如果没有自定义Logo,显示网站标题
?>
<h1 class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></h1>
<p class="site-description"><?php bloginfo( 'description' ); ?></p>
<?php
}
?>
</div><!-- .site-branding -->
<nav id="site-navigation" class="main-navigation">
<?php
wp_nav_menu( array(
'theme_location' => 'primary', // 我们稍后会注册这个菜单位置
'menu_class' => 'main-menu',
) );
?>
</nav><!-- #site-navigation -->
</header><!-- #masthead -->
wp_head(): 极其重要! WordPress 和许多插件通过这个钩子来添加 CSS、JavaScript、meta 标签等,没有它,你的网站会出问题。body_class(): 为<body>标签添加动态的 CSS 类,例如根据当前页面(首页、文章页、分类页等)添加不同的类,方便样式定制。wp_nav_menu(): 用于显示 WordPress 自定义菜单,我们需要先在functions.php中注册菜单位置。
footer.php - 网站页脚
创建 footer.php 文件。
<footer id="colophon" class="site-footer">
<div class="site-info">
© <?php echo date('Y'); ?> <?php bloginfo( 'name' ); ?>. All Rights Reserved.
</div><!-- .site-info -->
</footer><!-- #colophon -->
<?php wp_footer(); // 同样必须保留,用于加载JS等 ?>
</body>
</html>
wp_footer(): 和wp_head()一样重要,许多脚本(如 jQuery)都在这里加载。
sidebar.php - 侧边栏
创建 sidebar.php 文件。
<aside id="secondary" class="widget-area">
<?php if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
<?php dynamic_sidebar( 'sidebar-1' ); ?>
<?php endif; ?>
</aside><!-- #secondary -->
functions.php - 主题的“大脑”
这是主题中最重要的 PHP 文件之一,它不是一个模板,而是用来声明主题的功能、支持特性、加载脚本和样式等。
创建 functions.php 文件,并添加以下功能:
<?php
/**
* 主题功能文件
*/
// 1. 启用主题特色图片(文章缩略图)
add_theme_support( 'post-thumbnails' );
// 2. 注册导航菜单
register_nav_menus( array(
'primary' => '主导航菜单',
'footer' => '页脚菜单',
) );
// 3. 注册侧边栏
function myawesome_widgets_init() {
register_sidebar( array(
'name' => '主侧边栏',
'id' => 'sidebar-1',
'description' => '拖拽小工具到这里。',
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
) );
}
add_action( 'widgets_init', 'myawesome_widgets_init' );
// 4. 加载主题样式表
function myawesome_enqueue_styles() {
// 加载父主题样式(如果有的话)
// wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
// 加载主题主样式表
wp_enqueue_style( 'myawesome-style', get_stylesheet_uri(), array(), '1.0.0' );
}
add_action( 'wp_enqueue_scripts', 'myawesome_enqueue_styles' );
// 5. 加载主题 JavaScript 文件
function myawesome_enqueue_scripts() {
// 加载一个自定义的 JS 文件,假设它放在 /js/ 目录下
wp_enqueue_script( 'myawesome-main-script', get_template_directory_uri() . '/js/main.js', array( 'jquery' ), '1.0.0', true );
// true 表示脚本加载到页脚
}
add_action( 'wp_enqueue_scripts', 'myawesome_enqueue_scripts' );
template-parts/content.php - 文章内容模板
创建 template-parts 文件夹,然后在其中创建 content.php 文件,这个文件负责在循环中显示单篇文章。
<?php
/**
* 模板部分:用于显示文章内容的通用模板
*
* @package MyAwesomeTheme
*/
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
<?php
if ( is_singular() ) :
the_title( '<h1 class="entry-title">', '</h1>' );
else :
the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
endif;
if ( 'post' === get_post_type() ) :
?>
<div class="entry-meta">
<?php
myawesome_posted_on();
myawesome_posted_by();
?>
</div><!-- .entry-meta -->
<?php endif; ?>
</header><!-- .entry-header -->
<?php myawesome_post_thumbnail(); ?>
<div class="entry-content">
<?php
the_content( sprintf(
wp_kses(
/* translators: %s: Name of current post. Only visible to screen readers */
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'myawesome' ),
array(
'span' => array(
'class' => array(),
),
)
),
get_the_title()
) );
wp_link_pages( array(
'before' => '<div class="page-links">' . __( 'Pages:', 'myawesome' ),
'after' => '</div>',
) );
?>
</div><!-- .entry-content -->
<footer class="entry-footer">
<?php myawesome_entry_footer(); ?>
</footer><!-- .entry-footer -->
</article><!-- #post-<?php the_ID(); ?> -->
这个文件引用了一些我们还没定义的函数(myawesome_posted_on, myawesome_post_thumbnail 等),我们将在 functions.php 中添加这些辅助函数。
第三部分:高级功能与优化
在 functions.php 中添加辅助函数
将以下函数添加到你的 functions.php 文件末尾。
// 辅助函数:显示文章发布时间
function myawesome_posted_on() {
$time_string = '<time class="entry-date published updated" datetime="%1$s">%2$s</time>';
if ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) {
$time_string = '<time class="entry-date published" datetime="%1$s">%2$s</time> <time class="updated" datetime="%3$s">%4$s</time>';
}
$time_string = sprintf( $time_string,
esc_attr( get_the_date( 'c' ) ),
esc_html( get_the_date() ),
esc_attr( get_the_modified_date( 'c' ) ),
esc_html( get_the_modified_date() )
);
$posted_on = sprintf(
/* translators: %s: post date. */
esc_html_x( 'Posted on %s', 'post date', 'myawesome' ),
'<a href="' . esc_url( get_permalink() ) . '" rel="bookmark">' . $time_string . '</a>'
);
echo '<span class="posted-on">' . $posted_on . '</span>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
// 辅助函数:显示文章作者
function myawesome_posted_by() {
$byline = sprintf(
/* translators: %s: post author. */
esc_html_x( 'by %s', 'post author', 'myawesome' ),
'<span class="author vcard"><a class="url fn n" href="' . esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ) . '">' . esc_html( get_the_author() ) . '</a></span>'
);
echo '<span class="byline"> ' . $byline . '</span>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
// 辅助函数:显示文章特色图片
function myawesome_post_thumbnail() {
if ( post_password_required() || is_attachment() || ! has_post_thumbnail() ) {
return;
}
if ( is_singular() ) :
?>
<div class="post-thumbnail">
<?php the_post_thumbnail(); ?>
</div><!-- .post-thumbnail -->
<?php else : ?>
<a class="post-thumbnail" href="<?php the_permalink(); ?>" aria-hidden="true" tabindex="-1">
<?php
the_post_thumbnail( 'post-thumbnail', array(
'alt' => the_title_attribute( array(
'echo' => false,
) ),
) );
?>
</a>
<?php endif; // End is_singular().
}
// 辅助函数:显示文章底部的元信息(分类、标签等)
function myawesome_entry_footer() {
// 隐藏分类和标签。
if ( 'post' === get_post_type() ) {
/* translators: used between list items, there is a space after the comma */
$categories_list = get_the_category_list( esc_html__( ', ', 'myawesome' ) );
if ( $categories_list ) {
/* translators: 1: list of categories. */
printf( '<span class="cat-links">' . esc_html__( 'Posted in %1$s', 'myawesome' ) . '</span>', $categories_list ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/* translators: used between list items, there is a space after the comma */
$tags_list = get_the_tag_list( '', esc_html_x( ', ', 'list item separator', 'myawesome' ) );
if ( $tags_list ) {
/* translators: 1: list of tags. */
printf( '<span class="tags-links">' . esc_html__( 'Tagged %1$s', 'myawesome' ) . '</span>', $tags_list ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
if ( ! is_single() && ! post_password_required() && ( comments_open() || get_comments_number() ) ) {
echo '<span class="comments-link">';
comments_popup_link(
sprintf(
wp_kses(
/* translators: %s: post title. */
__( 'Leave a Comment<span class="screen-reader-text"> on %s</span>', 'myawesome' ),
array(
'span' => array(
'class' => array(),
),
)
),
get_the_title()
)
);
echo '</span>';
}
edit_post_link(
sprintf(
wp_kses(
/* translators: %s: post title. */
__( 'Edit <span class="screen-reader-text">%s</span>', 'myawesome' ),
array(
'span' => array(
'class' => array(),
),
)
),
get_the_title()
),
'<span class="edit-link">',
'</span>'
);
}
创建 php - 页面未找到模板
创建 php 文件,当用户访问一个不存在的页面时显示。
<?php
/**
* 404模板
*
* @package MyAwesomeTheme
*/
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 esc_html_e( 'Oops! That page can’t be found.', 'myawesome' ); ?></h1>
</header><!-- .page-header -->
<div class="page-content">
<p><?php esc_html_e( 'It looks like nothing was found at this location. Maybe try one of the links below or a search?', 'myawesome' ); ?></p>
<?php get_search_form(); ?>
</div><!-- .page-content -->
</section><!-- .error-404 -->
</main><!-- #main -->
</div><!-- #primary -->
<?php
get_footer();
创建 page.php - 页面模板
WordPress 的“页面”(Page,如“关于我们”、“联系方式”)和“文章”(Post)是分开的。page.php 用于显示所有页面。
你可以复制 index.php 的内容,然后稍作修改,我们的主题结构很简单,index.php 和 page.php 的逻辑几乎一样,所以我们可以让 page.php 直接使用 index.php 的内容。
在 page.php 中只写一行代码:
<?php // 页面模板 get_template_part( 'index' );
get_template_part( 'index' ) 会加载 index.php 文件。
创建 single.php - 单篇文章模板
当用户点击一篇文章的标题进入文章详情页时,single.php 会被调用。
创建 single.php 文件,内容如下:
<?php
/**
* 单篇文章模板
*
* @package MyAwesomeTheme
*/
get_header();
?>
<div id="primary" class="content-area">
<main id="main" class="site-main">
<?php
while ( have_posts() ) :
the_post();
get_template_part( 'template-parts/content', get_post_format() );
// 如果启用了评论,则加载评论模板
if ( comments_open() || get_comments_number() ) :
comments_template();
endif;
endwhile; // End of the loop.
?>
</main><!-- #main -->
</div><!-- #primary -->
<?php
get_sidebar();
get_footer();
这个模板和 index.php 很像,但关键区别在于:
- 它不包含
the_posts_navigation(),因为单篇文章没有“上一页/下一页”的分页需求。 - 它加载了
comments_template(),以显示文章的评论部分。
第四部分:激活主题与最终步骤
激活主题
- 通过 FTP 或文件管理器,将整个
my-awesome-theme文件夹上传到你的 WordPress 网站的/wp-content/themes/目录下。 - 登录你的 WordPress 后台。
- 导航到 外观 -> 主题。
- 你会看到 "My Awesome Theme",点击 “激活” 按钮。
设置菜单
- 在后台,导航到 外观 -> 菜单。
- 创建一个新菜单,主导航”。
- 添加你想要的页面(如“首页”、“关于我们”、“联系”)或文章链接到菜单中。
- 在菜单设置下,找到 “主题位置”,将你刚创建的菜单分配给 “主导航菜单”。
- 保存菜单。
设置侧边栏小工具
- 在后台,导航到 外观 -> 小工具。
- 你会看到一个名为“主侧边栏”的 widget 区域。
- 从左侧可用的小工具列表中,拖拽你想要的小工具(如“分类目录”、“近期文章”、“文本”等)到“主侧边栏”区域。
- 保存小工具。
添加一些样式
现在你的主题已经可以运行了,但看起来可能很朴素,打开 style.css 文件,在主题头标下方添加一些 CSS 来美化它,为文章、导航、侧边栏添加一些边距、颜色和布局。
进阶学习方向
你已经成功创建了一个基础的 WordPress 主题!接下来可以探索:
- WordPress Customizer (主题定制器): 使用
add_action('customize_register', ...)在functions.php中添加选项,让用户可以在后台自定义颜色、Logo、标题等。 - 自定义文章类型: 创建“作品集”、“服务”、“团队”等不同于文章和页面的内容类型。
- 自定义小工具: 创建你自己的小工具,用于在侧边栏或页脚中显示特定内容。
- 主题选项页面: 创建一个完整的后台页面来管理主题的设置。
- 响应式设计: 使用媒体查询让你的网站在各种设备上(手机、平板、桌面)都能良好显示。
推荐资源
- WordPress Developer Resources: 官方文档,最权威的资料。
- Underscores / _s: Automattic 官方提供的主题启动器,包含所有最佳实践,是学习主题结构的绝佳起点。
- GeneratePress: 一个轻量级的主题,其代码结构清晰,是学习现代主题开发的优秀范例。
- CodeinWP / Torque: 提供大量高质量的 WordPress 教程。
祝你开发愉快!
