学习创建自定义 WordPress Theme主题将为您打开一个全新的世界供您探索。它允许您为自己、您的客户构建定制设计,甚至可以回馈开源社区。在本指南中,我们将带您从零开始,拥有一个功能齐全、可以提交到WordPress.org主题目录的主题。
要继续学习,您需要对 HTML、CSS、PHP 以及 WordPress 的工作原理有基本的了解。
步骤#1:为您的自定义主题创建基本文件
一个正常运行的 WordPress 主题可以只包含两个文件:style.css和index.php。这是可能的,因为 WordPress 的模板层次结构。(开发WordPress主题,创建哪些目录文件结构?【主题开发基础】)
当 WordPress 输出网页时,它会搜索具体的可用模板,如果模板不存在,它将沿着层次结构向下移动,直到找到一个存在的模板。这是一个实际的例子:
用户位于https://example.com/practical-example,这是一个页面。WordPress 将尝试按以下顺序查找模板:
- page-{slug}.php – 页面 slug 是 /practical-example,WordPress 将使用 your-theme/page-practical-example.php
- page-{id}.php – 页面 ID 为 42,WordPress 将使用 your-theme/page-42.php。
- page.php – WordPress 将尝试通用的 your-theme/page.php 模板。
- single.php – 单数模板可以渲染帖子和页面,因此在更具体的 page.php 之后尝试
- index.php – *后,如果没有找到其他模板,则使用 your-theme/index.php。
让我们*先构建一个仅包含基本文件的主题,然后我们可以在探索它们的工作原理时添加更多功能。
在 中/wp-content/themes/
,创建一个名为的文件夹my-custom-theme
并创建以下两个文件:
style.css
为了让 WordPress 识别我们的主题并在外观 → 主题列表中正确输出,我们需要在style.css的顶部放置一些 WordPress 特定的代码,如下所示:
/*
Theme Name: My Custom Theme
Theme URI: https://yourwebsite.com/theme
Author: Your Name
Author URI: https://yourwebsite.com
Description: This is my first custom theme!
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: <https://www.gnu.org/licenses/gpl-2.0.html>
Text Domain: my-custom-theme
Tags: custom-background
*/
从技术上讲,这些字段都不是必需的,但如果您希望您的主题在 wp-admin 中看起来不错,那么强烈建议使用它们。如果您要在 WordPress 上分发主题,也需要它们。
- 主题名称– 您应该始终提供主题名称。如果不这样做,则将使用文件夹名称,在我们的示例中为 my-custom-theme。
- 主题 URI – 如果使用,主题 URI 应提供指向页面的链接,访问者可以在其中了解有关主题的更多信息。
- 作者——你的名字在这里。
- 作者 URI – 可以在此处放置指向您的个人或企业网站的链接。
- 描述– 描述显示在 wp-admin 主题模式以及WordPress 主题列表中。
- 版本– 版本号可帮助开发人员跟踪更改并让用户知道他们是否使用*新版本。我们遵循SemVer编号系统来表示更新中更改的严重性。
- 许可证– 如何许可主题取决于您,但如果您选择非 GPL 兼容许可证,那么您将无法在 WordPress 上分发您的主题。
- 许可证 URI – 这只是上面列出的许可证的链接。
- 文本域– 将主题翻译成其他语言时使用文本域。别担心,我们稍后会深入探讨这个问题。现在,只要知道主题文件夹和文本域是用连字符而不是空格分隔的主题名称是一个很好的做法就足够了。
- 标签 –仅当您将主题上传到 WordPress.org 主题目录时才使用标签。它们是“特征过滤器”机制的基础。
将以上内容复制并粘贴到style.css中,您将得到如下内容:
注意:目前看起来有点空白,因为我们还没有屏幕截图。我们稍后会添加。
index.php
index.php是*一个严格要求的文件。它的工作是渲染我们主题的所有前端输出。
由于index.php将渲染我们所有的页面(主页、帖子、类别、档案),因此它将做很多工作。*先,我们需要一个涵盖 HTML 基础知识的 head 部分。
<!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">
<?php wp_head(); ?>
</head>
这是标准 HTML,但有一个例外[wp_head()](<https://developer.wordpress.org/reference/hooks/wp_head/>)
:. wp_head
是一个核心功能,允许 WordPress 和第三方插件在不修改模板文件的情况下将代码插入到标头中。这称为动作挂钩。
如果您熟悉HTML,您可能会注意到没有 <title> 标记来输出页面标题。这是因为 WordPress 可以使用 wp_head 钩子来动态插入标题。
wp_head 的另一个用途是对样式 (.css) 和脚本 (.js) 进行排队。这样做有很好的理由,而不是对它们进行硬编码,我们稍后会讨论。
接下来,我们有页面的主体:(后面研究具体实现)
<body <?php body_class(); ?>>
body_class()是 WordPress 提供的辅助函数,它将输出有用的 CSS 类列表,这些类描述了正在显示的页面,例如:
class="page page-id-2 page-parent page-template-default logged-in"
body_class() ; 还接受一个参数,以便您可以添加自己的类,例如:
<body <?php body_class( 'wide-template blue-bg' ); ?>>
接下来,我们有模板标题。
<header class="site-header">
<p class="site-title">
<a href="<?php echo esc_url( home_url( '/' ) ); ?>">
<?php bloginfo( 'name' ); ?>
</a>
</p>
<p class="site-description"><?php bloginfo( 'description' ); ?></p>
</header><!-- .site-header -->
这里我们使用WordPress的内置模板功能来输出站点标题和描述。我们还使用了辅助函数home_url()将站点标题链接回主页。
接下来是页面正文:
<div class="site-content">
<?php
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
?>
<article <?php post_class(); ?>>
<header class="entry-header">
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
</header><!-- .entry-header -->
<div class="entry-content">
<?php the_content( esc_html__( 'Continue reading →', 'my-custom-theme' ) ); ?>
</div><!-- .entry-content -->
</article><!-- #post-## -->
<?php
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) :
comments_template();
endif;
endwhile;
else :
?>
<article class="no-results">
<header class="entry-header">
<h1 class="page-title"><?php esc_html_e( 'Nothing Found', 'my-custom-theme' ); ?></h1>
</header><!-- .entry-header -->
<div class="entry-content">
<p><?php esc_html_e( 'It looks like nothing was found at this location.', 'my-custom-theme' ); ?></p>
</div><!-- .entry-content -->
</article><!-- .no-results -->
<?php
endif;
?>
</div><!-- .site-content -->
这就是它变得有趣的地方(而且有点复杂)。这里我们使用 WordPress *重要的功能,循环Loop(这个循环也是比较重要,后面可以再深入研究,重点关注链接中的文字介绍)。该循环完成了确定用户所在页面以及应该显示什么内容的艰苦工作。然后,它返回一个或多个“帖子”的列表,我们可以循环遍历该列表并使用模板函数输出数据。
如果循环未返回任何结果,例如在 404 页面或已删除的帖子上,我们将使用 else 运算符来显示预定义的消息。
如果没有任何周围的代码,简化的循环如下所示:
if ( have_posts() ) : // check if the loop has returned any posts.
while ( have_posts() ) : // loop through each returned post.
the_post(); // set up the content so we can use template tags like the_title().
the_title(); // output the post title.
the_content(); // output the post content.
endwhile;
else :
echo 'No Page Found'; // output an error message if there are no posts.
endif;
?>
注意:由于 WordPress 起源于博客,因此许多函数都使用“Post”术语,即使它们可以返回和输出任何类型的内容(帖子、页面、自定义帖子类型)。
*后,我们有页脚,我们需要做的就是关闭之前打开的 HTML 标签。还有另一个操作钩子wp_footer(),WordPress 和插件积极使用它来在渲染页面所需的页脚中包含脚本。
<?php wp_footer(); ?>
</body>
</html>
如果您到目前为止一直在关注,您将拥有一个功能齐全的 WordPress 主题,如下所示:
我们的主题还是基础的(它没有 CSS),并且缺少用户认为必不可少的许多功能(侧边栏、导航、元数据、缩略图、分页等),但这是一个很好的开始!
让我们继续看看如何改进它。
步骤#2:创建functions.php
Functions.php严格来说并不是必需的文件,但它提供了如此多的好处,以至于 99.99% 的主题都拥有它。在functions.php中,您可以利用WordPress的内置主题功能,还可以添加您自己的自定义PHP代码。
现在在您的主题文件夹中创建一个functions.php,因为我们将在下一节中向其中添加代码。
添加导航菜单
大多数(如果不是全部)网站都使用导航菜单,但到目前为止我们的主题不支持导航菜单。为了告诉 WordPress 我们的主题有一个导航菜单,我们必须在functions.php中注册它,如下所示:
register_nav_menus( array(
'menu-1' => __( 'Primary Menu', 'my-custom-theme' ),
);
注意: register_nav_menus()接受一个数组,因此您可以根据需要注册多个菜单。
WordPress 现在知道我们的菜单,但我们仍然需要在我们的主题中输出它。我们通过在index.php中的站点描述下方添加以下代码来实现此目的:
wp_nav_menu( array(
'theme_location' => 'menu-1',
) );
现在我们有一个(无样式的)导航菜单:
添加侧边栏
我们的主题也没有侧边栏(小部件区域),让我们现在解决这个问题。
*先,我们需要在functions.php中注册侧边栏:
function my_custom_theme_sidebar() {
register_sidebar( array(
'name' => __( 'Primary Sidebar', 'my-custom-theme' ),
'id' => 'sidebar-1',
) );
}
add_action( 'widgets_init', 'my_custom_theme_sidebar' );
现在在主题文件夹中创建sidebar.php并添加以下代码:
<?php if ( is_active_sidebar( 'sidebar-1' ) ) { ?>
<ul class="sidebar">
<?php dynamic_sidebar('sidebar-1' ); ?>
</ul>
<?php } ?>
这里,我们在输出代码之前使用if语句来检查侧边栏是否处于“活动”状态。活动侧边栏是用户至少添加了一个小部件的侧边栏。
*后一步是在index.php中包含侧边栏,在wp_footer()上方添加get_sidebar()调用。
添加特色图像
与侧边栏和导航菜单一样,我们不能只在主题中输出特色图像并期望它们起作用,我们必须*先告诉 WordPress 我们支持该功能。在functions.php中添加:
add_theme_support( 'post-thumbnails' );
现在我们可以add_post_thumbnail(); 在我们的循环中,缩略图将起作用。*的问题是它们将以 WordPress 的*大尺寸 1920px x 2560px 输出,这对于大多数用途来说太大了。幸运的是 WordPress 有另一个辅助函数:add_image_size();
当用户上传图像时,如果定义了图像大小,WordPress 将生成该大小的上传图像版本(同时保留原始图像)。如果用户的图像小于您设置的尺寸,WordPress 将不会执行任何操作,因为它无法使图像大于原始图像。
要使用优化的特征图像而不是原始图像,请将以下代码放置在functions.php中:
add_image_size( 'my-custom-image-size', 640, 999 );
*个参数,第二个参数是图像宽度,第三个参数是高度。如果您只想限制一维,高度和宽度都是可选的。
在index.php调用标签:
the_post_thumbnail( 'my-custom-image-size' );
备注:如何只获取WordPress特色图片URL(在WordPress中,如果你想获取特色图片的URL而不是包含完整的img标签,可以使用get_the_post_thumbnail_url函数。)
调用CSS样式和JS脚本
之前我们说过,*好将CSS样式和HS脚本排入队列,而不是将它们直接硬编码到模板文件中。这是因为编入队列可以提供更大的灵活性。
如果正确完成,编入队列的方式还会告诉 WordPress 正在加载哪些资源。当 WordPress 知道需要哪些资源时,它可以确保相同的资源不会被多次加载。当您有一个非常流行的库(例如 jQuery 或 FontAwesome)且多个主题和插件将使用时,这一点尤其重要。
编入队列的另一个好处是,编入队列的资源可以通过插件被禁用,从而无需修改模板文件。
虽然我们的主题有一个style.css文件,但它还没有使用它,现在让我们将其加入队列,在functions.php添加如下代码,那么在style.css添加的样式将会作用于主题的样式:
function my_custom_theme_enqueue() {
wp_enqueue_style( 'my-custom-theme', get_stylesheet_uri() );
}
add_action( 'wp_enqueue_scripts', 'my_custom_theme_enqueue' );
get_stylesheet_uri()
是一个辅助函数,用于检索当前主题样式表的 URI。如果我们要对任何其他文件进行排队,我们需要这样做:
wp_enqueue_style( 'my-stylesheet', get_template_directory_uri() . '/css/style.css' );
我们的主题没有任何脚本,如果有,我们将像这样将它们排队:
function my_custom_theme_enqueue() {
wp_enqueue_style( 'my-custom-theme', get_stylesheet_uri() );
wp_enqueue_script( 'my-scripts', get_template_directory_uri() . '/js/scripts.js' );
}
add_action( 'wp_enqueue_scripts', 'my_custom_theme_enqueue' );
上述情况的一个例外是 WordPress预先注册的脚本,在这种情况下,您只需提供*个参数 ($handle):
wp_enqueue_script( 'jquery' );
在functions.php文件中把所有的路劲都写好:(以下代码来源于WP大学https://www.wpdaxue.com/docs/theme-handbook/basics/including-css-javascript)
function add_theme_scripts() {
wp_enqueue_style( 'style', get_stylesheet_uri() );
wp_enqueue_style( 'slider', get_template_directory_uri() . '/css/slider.css', array(), '1.1', 'all');
wp_enqueue_script( 'script', get_template_directory_uri() . '/js/script.js', array ( 'jquery' ), 1.1, true);
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
add_action( 'wp_enqueue_scripts', 'add_theme_scripts' );
然后在header.php通过<?php wp_head(); ?>
引用就可以。(<?php wp_head(); ?>
除了引用样式,还引用标题等其他元素,安装的很多插件都依赖这个hook)
调用标题<title></title>(重点在研究)
所有主题都应该利用 WordPress 的内置功能来生成标题标签,这是通过将此代码添加到您的functions.php文件中来启用的:add_theme_support( 'title-tag' );
这就是全部,WordPress 将处理页面<title>的输出,如果需要的话插件可以使用过滤器修改输出。SEO 插件通常这样做是为了进一步优化标题。
步骤#3:添加模板部件
现在我们 80% 的模板代码都在index.php中。
虽然这有效,但当我们有其他模板文件(例如single.php、search.php和archive.php )时,它会导致大量代码重复。模板部件允许我们跨模板重复使用代码,从而使主题开发变得更加容易。由于我们的页眉和页脚在每个页面上都是相同的,因此它们是使用模板部件的完美候选者。*先,创建 header.php 并从index.php中移动以下代码:
<!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>">
<?php wp_head(); ?>
</head>
<header class="site-header">
<p class="site-title">
<a href="<?php echo esc_url( home_url( '/' ) ); ?>">
<?php bloginfo( 'name' ); ?>
</a>
</p>
<p class="site-description"><?php bloginfo( 'description' ); ?></p>
<?php
wp_nav_menu( array(
'theme_location' => 'menu-1',
) );
?>
</header><!-- .site-header -->
在index.php中将上面的代码替换为:
<?php get_template_part( 'header' ); ?>
接下来,通过将此代码移动到footer.php并重复上述过程来创建页脚模板部分:
<?php wp_footer(); ?>
</body>
</html>
*后,我们也将“无结果”代码移至模板部分,因为它可能会在多个模板中使用。创建content-none.php并将此代码移动到新文件中。
<article class="no-results">
<header class="entry-header">
<h1 class="page-title"><?php esc_html_e( 'Nothing Found', 'my-custom-theme' ); ?></h1>
</header><!-- .entry-header -->
<div class="entry-content">
<p><?php esc_html_e( 'It looks like nothing was found at this location.', 'my-custom-theme' ); ?></p>
</div><!-- .entry-content -->
</article><!-- .no-results -->
您的index.php现在应该如下所示:
<?php get_template_part( 'header' ); ?>
<div class="site-content">
<?php
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
?>
<article <?php post_class(); ?>>
<?php the_post_thumbnail(); ?>
<header class="entry-header">
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
</header><!-- .entry-header -->
<div class="entry-content">
<?php the_content( esc_html__( 'Continue reading →', 'my-custom-theme' ) ); ?>
</div><!-- .entry-content -->
</article><!-- #post-## -->
<?php
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) :
comments_template();
endif;
endwhile;
else :
get_template_part( 'content-none' );
endif;
?>
</div><!-- .site-content -->
<?php
get_sidebar();
get_template_part( 'footer' );
虽然上面的方法可以完美地工作,但我们还可以做一些小小的改进。WordPress 具有包含页眉、页脚和侧边栏模板部分的辅助函数。由于尽可能使用核心功能是*佳实践,因此我们应该使用这些功能。
替换get_template_part( 'header' );
为get_header();
和get_template_part( 'footer' );
_get_footer();
步骤#4:添加single.php、archive.php、search.php 和 404.php
当我们向主题添加新的模板文件时,我们使用模板部分完成的基础工作将得到回报。下面我们列出了*常见的。为了避免代码示例让您不知所措,我们链接到了 Github 上的源代码。
singular.php
帖子和页面在其自己的 URL 上显示时被视为“singular”,因为大多数情况下这两种页面类型的布局都是相同的。但如果不是,您可以使用更具体的page.php和single.php (post) 来代替。
示例代码:
<?php
/**
* The template for displaying single posts and pages.
*
* @copyright Copyright (c) 2020, Danny Cooper
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
*/
get_header(); ?>
<div class="site-content">
<?php
while ( have_posts() ) :
the_post();
?>
<article <?php post_class(); ?>>
<?php the_post_thumbnail( 'my-custom-image-size' ); ?>
<header class="entry-header">
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
</header><!-- .entry-header -->
<div class="entry-content">
<?php the_content(); ?>
</div><!-- .entry-content -->
</article><!-- #post-## -->
<?php
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) :
comments_template();
endif;
endwhile;
?>
</div><!-- .site-content -->
<?php
get_sidebar();
get_footer();
archive.php
存档模板通常与单一模板有两个不同之处:它们显示摘录而不是完整内容,并具有解释内容的存档标题。
返回到模板层次结构,您将看到存档模板涵盖了所有类型的存档(作者、类别、标签、分类、日期),如果这不适用于您的用例,您仍然可以使用更具体的模板:
- author.php
- category.php
- tag.php
- taxonomy.php
- date.php
示例代码:
<?php
/**
* The template for displaying archive pages.
*
* @copyright Copyright (c) 2020, Danny Cooper
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
*/
get_header(); ?>
<div class="site-content">
<header class="page-header">
<?php
the_archive_title( '<h1 class="page-title">', '</h1>' );
the_archive_description( '<div class="archive-description">', '</div>' );
?>
</header><!-- .page-header -->
<?php
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
?>
<article <?php post_class(); ?>>
<?php the_post_thumbnail( 'my-custom-image-size' ); ?>
<header class="entry-header">
<?php the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '">', '</a></h2>' ); ?>
</header><!-- .entry-header -->
<div class="entry-content">
<?php the_content( esc_html__( 'Continue reading →', 'my-custom-theme' ) ); ?>
</div><!-- .entry-content -->
</article><!-- #post-## -->
<?php
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) :
comments_template();
endif;
endwhile;
the_posts_navigation();
else :
get_template_part( 'content-none' );
endif;
?>
</div><!-- .site-content -->
<?php
get_sidebar();
get_footer();
search.php
可以使用 ?s= URL 参数搜索 WordPress 网站,例如yourwebsite.com?s=test
. search.php模板输出这些搜索的结果。
示例代码:
<?php
/**
* The template for displaying search result pages.
*
* @copyright Copyright (c) 2020, Danny Cooper
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
*/
get_header(); ?>
<div class="site-content">
<header class="page-header">
<h1 class="page-title">
<?php
/* translators: %s: the search query */
printf( esc_html__( 'Search Results for: %s', 'scaffold' ), '<span>' . get_search_query() . '</span>' );
?>
</h1>
</header><!-- .page-header -->
<?php
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
?>
<article <?php post_class(); ?>>
<?php the_post_thumbnail( 'my-custom-image-size' ); ?>
<header class="entry-header">
<?php the_title( '<h2 class="entry-title">', '</h2>' ); ?>
</header><!-- .entry-header -->
<div class="entry-content">
<?php the_content( esc_html__( 'Continue reading →', 'my-custom-theme' ) ); ?>
</div><!-- .entry-content -->
</article><!-- #post-## -->
<?php
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) :
comments_template();
endif;
endwhile;
the_posts_navigation();
else :
get_template_part( 'content-none' );
endif;
?>
</div><!-- .site-content -->
<?php
get_sidebar();
get_footer();
404.php
我们在 index.php 中添加的 else 语句捕获“找不到页面”错误,但您可能希望将该功能解耦到其自己的模板文件中,以便更好地控制输出。这就是404.php模板文件的用例。
示例代码:
<?php
/**
* The template for displaying 404 page.
*
* @copyright Copyright (c) 2020, Danny Cooper
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
*/
get_header(); ?>
<div class="site-content">
<article class="no-results">
<header class="entry-header">
<h1 class="page-title"><?php esc_html_e( 'Nothing Found Here', 'my-custom-theme' ); ?></h1>
</header><!-- .entry-header -->
<div class="entry-content">
<p><?php esc_html_e( 'It looks like nothing was found at this location.', 'my-custom-theme' ); ?></p>
</div><!-- .entry-content -->
</article><!-- .no-results -->
</div><!-- .site-content -->
<?php
get_sidebar();
get_footer();
步骤#5:辅助文件
如果您要将主题分发给所有人,那么以下文件是必不可少的。如果没有这些,您的主题将被主题存储库和市场拒绝。
screenshot.png
当用户选择新主题时,屏幕截图显示在 wp-admin 主题列表中。以下是您应该遵循的一些*佳实践:
- 屏幕截图应为 1200 像素 x 900 像素
- 屏幕截图应为 .png 或 .jpg 格式
- 屏幕截图应该准确表达主题
- 应优化屏幕截图(使用tinypng.com或类似网站)
readme.txt
WordPress 不使用readme.txt中的任何信息,它从style.css中提取所需的所有内容。另一方面,WordPress 主题目录确实从自述文件中提取重要信息,并将其视为必需文件。
大多数开发人员使用readme.txt作为存储有关其主题的所有信息的中心位置。一个简单的readme.txt如下所示:
=== Theme Name ===
Requires at least: 5.0
Tested up to: 5.2
Requires PHP: 5.6
License: GPLv2 or later
License URI: <https://www.gnu.org/licenses/gpl-2.0.html>
Short description. No more than 150 chars.
== Description ==
Theme desc.
== Changelog ==
= 1.0 =
* Added new option
== Resources ==
* normalize.css <https://necolas.github.io/normalize.css/>, (C) 2012-2016 Nicolas Gallagher and Jonathan Neal, [MIT](<https://opensource.org/licenses/MIT>)
- 至少需要– 这是您的主题兼容的 WordPress 的*低版本。
- 已测试至– 此字段表示您的主题已测试过的*新 WordPress 版本。
- 需要 PHP – 该字段表示您的主题将运行的*低 PHP 版本。
- 描述– 此描述字段当前未显示在任何地方。
- 变更日志– 变更日志不在任何地方使用,但开发人员和一些用户将引用此文件来查看进行了哪些更改。
- 资源——大多数第三方资源都需要某种类型的归属。资源部分是一个被广泛接受的放置这些内容的地方。即使对于没有明确要求归属的资源,在此处列出它们仍然是一个很好的做法,以便用户了解他们正在使用的资源的许可证。
步骤#6:创建页面模板
页面模板允许开发人员创建可用于单个帖子和页面的自定义模板。例如,大多数主题都有两列(内容 – 侧边栏)布局,但在某些页面上,用户可能只想关注内容而不显示侧边栏。这就是页面模板可以提供帮助的地方。
“页面模板”是如何创建的?
在我们的主题文件夹中,创建一个名为“page-templates”的新文件夹,并在该文件夹中创建一个名为single-column.php的文件。为了加快速度,请将single.php中的所有代码复制到page-templates/single-column.php并删除对get_sidebar()的调用,因为此模板不需要它。
现在我们需要添加一个特殊的标头,告诉 WordPress 这是一个页面模板,它看起来像这样:
/*
Template Name: Single Column Template
Template Post Type: post, page
*/
该代码是不言自明的,我们只是告诉 WordPress 模板的名称以及它可以与哪些帖子类型一起使用。
这就是全部,我们的新页面模板现在可以在编辑器中的“页面属性”下使用。
步骤#7:使您的主题与 RTL.css 兼容
并非所有语言都是从左到右阅读的。例如,阿拉伯语和希伯来语是从右向左 (RTL) 阅读的。有一种简单的方法可以使您的主题与 RTL 语言兼容。
在主题文件夹中创建一个名为rtl.css的新文件,然后复制并粘贴以下代码:
body {
direction: rtl;
unicode-bidi: embed;
}
如果 RTL 语言是 WordPress 网站上的活动语言,WordPress 就会自动加载此 CSS 文件。
这是 RTL 功能的非常基本的实现,可帮助您入门。如果您有兴趣了解更多信息,这里有两个很棒的资源:
步骤#8:始终遵循*佳实践(Theme主题开发必不可少的知识)
*佳实践随着时间的推移不断发展,使构建和维护 WordPress 主题变得更加容易。遵循这些原则不仅可以帮助您,而且还可以让其他开发人员在需要使用您的代码时更轻松。
1) 使用入门主题
入门主题为您构建主题提供了坚实的基础。通常它们是轻量级的,几乎不包含样式,也没有配置选项。随着时间的推移,您可能会构建自己的入门主题,您可以将所有项目都基于该主题,但目前以下是一些流行的选项:
- Underscores(这个可以帮助您快速生成一套非常标准的WordPress主题Theme模板,你就修改修改就可以!!)
- Scaffold(这是很标准的能在WordPress市场上发布的主题Theme,它满足了能发布的基础要求)
- HTML5 Blank(这也是一套WordPress主题模板,在github上开源)
2) 了解 WordPress 编码标准
编码标准是一种在整个代码库中以一致的方式格式化代码的方法。WordPress 具有 HTML、CSS、Javascript 和 PHP 的编码标准。虽然使用编码标准对*终用户体验没有影响,但它确实使您的代码更具可读性。即使您不使用 WordPress 编码标准,我们也始终建议使用标准。
3)使用本地化
感谢志愿者的辛勤工作,WordPress 现已支持数百种语言。如果您的主题要公开发布,则需要以允许翻译的方式构建它。
别担心,这非常容易做到。我们需要做的就是确保所有字符串都通过“本地化函数”传递,而不是直接输出。
而不是这个:
<?php echo 'Previous Post'; ?>
我们这样做:
<?php echo __( 'Previous Post', 'my-custom-theme' ); ?>
__()是一个接受字符串和文本域的本地化函数。该函数返回所提供字符串的翻译,如果翻译不可用,则返回原始字符串。
4)避免插件功能
当用户更改主题时,只有表示层应该更改。内容和功能应该基本保持不变。这意味着任何影响 WordPress 角色的功能都应该包含在插件中,而不是您的主题中。插件功能的一些示例包括:
- 自定义帖子类型
- 页面构建器
- 社交媒体分享
- 搜索引擎优化(SEO)
虽然在主题中包含 SEO 控件似乎很方便(也可能是一个卖点),但从长远来看,它实际上会伤害用户。将来,他们需要更改主题,但无法更改,因为他们所有的 SEO 配置都与当前主题紧密耦合。相反,如果配置存储在插件中,他们就可以放心地更改主题。
5) 前缀(防止冲突)
为了防止冲突,主题创建的所有函数、类和全局变量都应该加上前缀。这很重要,因为不可能知道用户的网站上正在运行哪些其他代码。前缀可以防止名称冲突和致命错误。
大多数情况下,由破折号或下划线分隔的主题名称将用作前缀。如果主题名称很长,则可以使用*字母缩写。主题名称:
Theme Name: Scaffold
class Scaffold_Class {}
function scaffold_function() {}
global $scaffold_global
Theme Name: My Long Theme Name
class MLTN_Class {}
function mltn_function() {}
global $mltn_global
6)使用核心功能
如果存在的话,您应该始终使用核心功能,而不是重新发明轮子。这包括但不限于侧边栏、导航菜单、帖子缩略图、自定义标题和自定义背景。这些功能已经过数百万用户的实际测试,并得到积极维护和改进。
如果您需要更改核心函数的功能或输出,则可以使用 WordPress 提供的众多挂钩和过滤器之一。例如,wp_nav_menu()
有一个“walker”参数,这样您就可以完全控制输出。
7) 转义和清理数据
作为主题开发人员,您必须熟悉转义和清理数据,以保护您的用户免受潜在的攻击。
Escaping 转义
转义是在输出之前检查数据是否安全的过程,而清理是在将数据保存到数据库之前检查数据的过程。
WordPress 具有可用于转义数据的辅助函数,因此您无需自己构建这些函数。esc_html是转义函数的一个示例。未转义的输出如下所示:
echo get_theme_mod( 'error_page_title' );
为了Escaping 转义输出,我们这样做:
echo esc_html( get_theme_mod( 'error_page_title' ) );
您应该注意的其他一些转义函数是esc_attr()、absint()、esc_url()。
还可以使用单个函数来转换和转义字符串:
echo esc_html( __( '404 Not Found', 'my-custom-theme' ) );
变成:
echo esc_html__( '404 Not Found', 'my-custom-theme' );
// or
esc_html_e( '404 Not Found', 'my-custom-theme' );
提示:在主题中的任何位置都echo $
应该检查是否需要转义,通常需要转义。
Sanitizing 清理
如果您向主题添加设置,则需要确保用户输入到这些设置的数据在进入数据库之前是安全的。WordPress 有许多功能可以帮助清理输入。
使用定制器 API 向主题添加设置时,它有一个名为“ sanitize_callback ”的参数,该参数接受清理函数的名称。设置所采用的任何输入都会在进入数据库之前由您提供给“ sanitize_callback ”的函数进行检查。
它强调了清理的重要性,即使您的其中一项设置缺少 sanitize_callback,它也不会被接受到 WordPress 主题目录中。
$wp_customize->add_setting(
'my_custom_theme_setting',
array(
'sanitize_callback' => 'sanitize_text_field' // A core sanitization function.
)
);
可以在此处查看清理和转义功能的官方列表:数据清理/转义
步骤#9:分发您的 WordPress 主题
主题可以通过不同的渠道分发,具体取决于您想要实现的结果。如果您的结果只是为开源社区做出贡献,那么没有比将主题上传到 WordPress 目录更好的方法了。相反,如果您希望出售主题并直接赚钱,也有一些方法可以做到这一点。
以下是主题分发的*网站:
1) WordPress.org(获取下载和用户的*佳场所)
在 WordPress 上托管主题的主要好处是,您的主题不仅可以在 wordpress.org 网站上看到,还可以在 wp- admin仪表板中看到,从而提高可见性。
使用 WordPress 托管主题的另一个好处是内置的更新系统。如果您更新主题,所有用户都将在其wp-admin仪表板内收到通知,并获得更新到*新版本的简单路径。
WordPress.org 只接受免费主题,但这并不意味着你不能赚钱。免费主题可以成为推广您的*主题、插件或服务的*渠道。
2) WordPress.com
WordPress.com 提供免费和付费主题。然而,他们已经好几年没有开放新作者的投稿了。
3) ThemeForest主题森林
ThemeForest是优质主题的重要市场。*畅销的主题 (Avada) 销售额超过 5,000,000 美元。
一般来说,主题森林的买家期望功能齐全的“多用途”主题。所有热门主题都具有页面构建器功能,并得到开发团队的支持。对于新作者来说,这是一个非常难以进入的市场。
4)创意市场和Mojo市场
Creative Market和Mojo Marketplace是优质主题市场中的小参与者,这就是我们将它们归为一类的原因。它们实际上都提供与 ThemeForest 相同的服务,但规模较小。
5)Github
Github是公开免费主题的简单方法。没有审查流程,也没有可遵循的指南。但是,您不会从 wordpress.org 的可见性中受益,并且需要构建自己的更新机制,以便用户获取*新版本。
步骤#10:测试和改进代码
1) 测试你的主题
主题单元测试
主题单元测试是一个标准的 WordPress 内容导入文件,其中包含各种内容类型和边缘情况。它很容易上传到您的开发环境,并将突出显示您可能忽略的许多场景。
WP_DEBUG 函数测试
作为主题开发人员,在启用WP_DEBUG的情况下测试您的主题是您应该做的**基本的事情。当 WP_DEBUG 设置为 true 时,您的主题不应返回任何错误或警告。
使用主题支持的不同 PHP 版本重复测试也很重要。每个主要的 PHP 版本都会有新的更改、警告和折旧。主题在 PHP5.6 上没有错误但在 PHP7 上显示错误的情况并不少见。
要启用 WP_DEBUG,请将以下代码添加到wp-config.php:
DEFINE( 'WP_DEBUG', true );
Monster Widget 插件主题检查
Monster Widget是一个有用的插件,可让您*向侧边栏添加 13 个核心小部件。核心小部件使用各种 HTML 元素,这使得它们非常适合测试您的主题。
Theme Sniffer 插件检查主题
Theme Sniffer是由 Theme Review Team (TRT) 创建的插件。它捕获了大量(但不是全部)转义和本地化错误。它还会根据 WordPress 编码标准检查您的主题。
2) 将您的主题提交到 WordPress.org
在本指南的开头,我们说过,当您到达*后时,您将拥有一个可以提交到 wordpress.org 的主题。让我们看看这个过程。
上传流程
上传过程很简单。创建或登录您的 WordPress 帐户,然后导航到此页面 – https://wordpress.org/themes/upload/
您可以立即压缩主题并上传,但您可能*先想了解以下一些内容。
要求
主题审核小组 (TRT) 有一套严格的要求。您的主题在满足所有要求之前不会被接受到目录中。
审核流程
当您上传主题时,必须通过一个两阶段的审核过程才能被接受到目录中。
*先,一旦您按下“上传” ,就会执行自动检查。在幕后,自动检查器的工作方式与主题嗅探器插件(Theme Sniffer 插件)非常相似。如果发现任何错误,它将拒绝该主题,上传过程就此结束。
如果您的主题通过了自动检查,那么它将加入等待人工审核的主题队列。人工审核由 TRT 的志愿者完成。队列中的主题数量远远超过审阅者的数量,这意味着您的主题通常需要 2-3 个月才能到达队列的前面。
当您的主题到达人工审核阶段时,您的主题必须没有错误并且符合所有要求,如果有超过 3 个重大错误,则可以被拒绝。如果主题在人工审核阶段被拒绝,则必须重新加入后面的队列,这意味着再次等待 2-3 个月才能进行另*人工审核。
有用的资源:*常见的 WordPress 主题开发错误(以及如何修复它们)
值得注意的是,TRT 一直在寻找新的审稿人,志愿服务可以是一种很好的学习经历,也是为开源社区做出贡献的一种方式。
3) 您的主题列表
恭喜,您的主题已获得批准!您现在拥有自己的列表,如下所示。
以下是您可以在此页面上看到的内容的概述:
- 屏幕截图 –屏幕截图是潜在用户看到的*件事,因此请使其尽可能吸引人。但请记住,它仍然必须是主题的准确表示,而不是 Photoshop 渲染。从*流行的主题中获取灵感。
- 描述 –从style.css中提取的描述是描述您的主题及其主要功能的理想位置。它还有助于在此处列出推荐或必需的插件。该描述不支持任何格式(粗体、斜体、超链接)甚至换行符。
- 标签 –这是您在style.css中列出的标签的表示。仅接受此处的这些标签。
- 预览按钮 –预览由 wordpress.org 生成,作为主题开发人员,我们无法控制输出。不幸的是,由于预览器使用基本内容且没有配置,因此通常会导致预览不太完美。
- 主题主页链接–预览按钮的 URL是从 style.css 中的“主题 URI”字段中提取的。有严格要求,该 URL 必须仅用于显示显示有关您的主题的信息的页面。
- 活跃安装数– 这是活跃使用该主题的网站数量。该数字四舍五入到*接近的十、百或千。无法检索准确的数字。
- 每日下载次数– 这是您的主题被下载的次数。“下载”可以是新下载或主题更新。
- 评论 –用户必须登录 wordpress.org 帐户才能留下评论。一般来说,除非您明确要求用户提交评论,否则很难获得评论。
- 支持– 内置支持平台非常适合管理和解决主题问题。用户必须登录才能创建支持线程。
- 翻译– 翻译平台是一个很棒的资源。如果您一直遵循本指南中的建议来本地化您的主题,那么您的用户将能够将其翻译成其他语言,并将您的潜在用户群扩展到英语用户之外。
4) 更新你的主题
当您将来更改主题并需要更新 WordPress 上托管的版本时,过程很简单。
*先更新readme.txt中的“版本:”字段和更改日志。然后压缩文件并使用与之前相同的上传页面重新上传。
系统会将其识别为更新并自动批准它,因此不需要再次进行人工审核。