WordPress中文开发手册

WordPress主题开发 — 子主题

子主题允许您改变网站外观的小部分,但仍保留主题的外观和功能。 要理解子童主题如何运作,首先要了解父主题与子主题之间的关系。

什么是父主题?

父主题是一个完整的主题,其中包含所有必需的WordPress模板文件和主题的资源。 所有主题 - 不包括子主题 - 被认为是父主题。

什么是子主题?

如概述所示,子主题继承父主题及其所有功能的外观,可用于对主题的任何部分进行修改。 以这种方式,自定义与父主题的文件保持分离。 使用子主题可以升级父主题,而不影响您对自己的站点的自定义。

子主题:

  • 使您的修改便携和可复制;
  • 保持定制与父主题功能分离;
  • 允许更新父主题,而不会破坏您的修改;
  • 让你利用这些努力和测试放在父母主题中;
  • 节省开发时间,因为您没有重新创建轮子; 并且是开始学习主题发展的好方法。

注意:如果您进行广泛的自定义 - 超出样式和一些主题文件 - 创建父主题可能比一个较小的主题更好的选择。 创建父主题可以避免将来使用已弃用的代码的问题。 这需要根据具体情况决定。

如何创建一个子主题

1. 创建一个子主题文件夹

首先,在您的主题目录中创建一个位于wp-content/themes的新文件夹。

该目录需要一个名称。 最好的做法是给子主题与父主题一样的名字,但是将-child附加到最后。 例如,如果您正在制作一个twentyfifteen的子主题,那么该目录将被命名为twentyfifteen-child。

2. 创建一个样式表:style.css

接下来,您将需要创建一个名为style.css的样式表文件,该文件将包含控制主题外观的所有CSS规则和声明。 您的样式表必须包含文件顶部的以下必需的标题注释。 这告诉WordPress关于主题的基本信息,包括它是一个具有特定父项的子主题的事实。

/*
 Theme Name:   Twenty Fifteen Child
 Theme URI:    http://example.com/twenty-fifteen-child/
 Description:  Twenty Fifteen Child Theme
 Author:       John Doe
 Author URI:   http://example.com
 Template:     twentyfifteen
 Version:      1.0.0
 License:      GNU General Public License v2 or later
 License URI:  http://www.gnu.org/licenses/gpl-2.0.html
 Tags:         light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready
 Text Domain:  twenty-fifteen-child
*/

需要以下信息:

  • Theme Name – 需要您的主题独特
  • Template – 父主题目录的名称。 我们的例子中的父母主题是“twentyfifteen”主题,所以模板将是twentyfifteen。 您可能正在使用不同的主题,因此进行相应调整。

根据需要添加剩余信息。 唯一必需的子主题文件是style.css,但是functions.php是正确排列样式所必需的(如下)。

3. 入队样式表

最后一步是排列父主题和子主题的主题样式表。

注意:在过去,常用的方法是使用@import导入父主题样式表;这不再是推荐的做法,因为它增加了加载样式表所需的时间。此外,父样式表可以包含两次。

  • 推荐使用父主题样式表的方法是添加一个wp_enqueue_scripts动作,并在您的子主题的functions.php中使用wp_enqueue_style()。

因此,您将需要在您的子主题目录中创建一个functions.php。您的子主题的functions.php的第一行将是一个开放的PHP标签(<?php),之后您可以排列父母和子主题样式表。以下示例函数仅在您的父主题仅使用一个主style.css来保存所有css的情况下才起作用。如果你的孩子主题有多个.css文件(例如ie.css,style.css,main.css),那么你必须确保保持所有的父主题依赖关系。

<?php
add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_styles' );
function my_theme_enqueue_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
 
}
?>

如果你的子主题style.css包含实际的CSS代码(通常是这样),你也需要排队它。 将“父样式”设置为依赖关系将确保在其后面加载子主题样式表。 包括子主题版本号码可确保您也可以为子主题突破缓存。 完整的(推荐)示例变为:

<?php
add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_styles' );
function my_theme_enqueue_styles() {
 
    $parent_style = 'parent-style'; // This is 'twentyfifteen-style' for the Twenty Fifteen theme.
 
    wp_enqueue_style( $parent_style, get_template_directory_uri() . '/style.css' );
    wp_enqueue_style( 'child-style',
        get_stylesheet_directory_uri() . '/style.css',
        array( $parent_style ),
        wp_get_theme()->get('Version')
    );
}
?>

在父主题注册样式表时,父样式与父主题中使用的$句柄相同。

激活子主题

您的子主题现在可以激活了。 登录到您的网站的管理屏幕,然后转到管理屏幕>外观>主题。 您应该看到您的子主题已列出并准备激活。 (如果您的WordPress安装已启用多站点,则可能需要切换到网络管理屏幕以启用主题(在“网络管理主题屏幕”选项卡中),然后可以切换回到特定于站点的WordPress管理屏幕激活你的子主题。)

注意:激活子主题后,您可能需要从外观>菜单和主题选项(包括背景和标题图像)重新保存菜单。

添加模板文件

除了functions.php文件(如上所述),您添加到您的子主题的任何文件将覆盖父主题中的相同文件。

在大多数情况下,最好从父主题创建要更改的模板文件的副本,然后对所复制的文件进行修改,使父文件保持不变。 例如,如果要更改父主题的header.php文件的代码,您可以将该文件复制到您的子主题文件夹并在那里进行自定义。

提示:有几个插件允许您检测正在查找的页面上正在使用的具体模板。

  • What The File
  • What Template File Am I Viewing?
  • Debug Bar

您还可以在父主题中未包含的子主题中包含文件。 例如,您可能需要创建一个比您的父主题中更具体的模板,例如特定页面或类别归档的模板(例如,页面3php将为ID为3的页面加载)。

有关WordPress如何确定要使用哪个模板的更多信息,请参阅“模板层次”页面。

使用functions.php

与style.css不同,子主题的functions.php不会覆盖其父对象。而是除了父项的functions.php之外加载它。 (具体来说,它是在父文件之前加载的。)

这样,一个子主题的functions.php提供了一个聪明,无故障的修改父主题功能的方法。假设你想添加一个PHP函数到你的主题。最快的方式是打开它的functions.php文件并把功能放在那里。但这不聪明:下次主题更新时,您的功能将会消失。但是有一种替代方法是聪明的方法:您可以创建一个子主题,在其中添加一个functions.php文件,并将该函数添加到该文件中。该功能也将从那里做同样的工作,其优点是不会受到父主题的未来更新的影响。不要将父主题的functions.php的完整内容复制到child主题的functions.php中。

functions.php的结构很简单:在顶部打开PHP标签,下面是PHP的位。在其中,您可以根据需要放置尽可能多的功能。下面的例子显示了一个基本的functions.php文件,它提供了一个简单的事情:向HTML页面的头元素添加一个favicon链接。

<?php // Opening PHP tag - nothing should be before this, not even whitespace
 
// Custom Function to Include
function my_favicon_link() {
    echo '<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />' . "\n";
}
add_action( 'wp_head', 'my_favicon_link' );
Tip: The fact that a child theme’s functions.php is loaded first means that you can make the user functions of your theme pluggable —that is, replaceable by a child theme— by declaring them conditionally.

if ( ! function_exists( 'theme_special_nav' ) ) {
    function theme_special_nav() {
        //  Do something.
    }
}

这样一来,一个子主题就可以通过简单地声明它来代替父代的PHP函数。

有关您的子主题的functions.php文件中包含的内容的详细信息,请阅读“主题功能”页面。

参考或包括其他文件

当您需要包含位于子主题目录结构中的文件时,您将需要使用get_stylesheet_directory()。 由于style.css位于子主题子目录的根目录中,所以get_stylesheet_directory()指向您的子主题目录(而不是父主题目录)。 要引用父主题目录,可以使用get_template_directory()。

下面是一个示例,说明如何在引用存储在子主题目录中的文件时使用get_stylesheet_directory():

<?php require_once( get_stylesheet_directory(). '/my_included_file.php' ); ?>

同时,此示例使用get_stylesheet_directory_uri()显示存储在子主题目录中的/ images文件夹中的图像。

<img src="<?php echo get_stylesheet_directory_uri(); ?>/images/my_picture.png" alt="" />

与返回文件路径的get_stylesheet_directory()不同,get_stylesheet_directory_uri()返回一个URL,这对前端资源很有用。

入队样式和脚本

每个脚本和样式都应该使用自己的功能排队,然后应该包含在一个动作中。 有关更多信息,请阅读包含CSS和JavaScript的页面。

WordPress不会自动加载您的孩子主题的样式表在前端。 以下是使用wp_enqueue_scripts()动作钩子调用排序子主题样式表的函数的示例。

<?php
add_action( 'wp_enqueue_scripts', 'my_plugin_add_stylesheet' );
function my_plugin_add_stylesheet() {
    wp_enqueue_style( 'my-style', get_stylesheet_directory_uri() . '/style.css', false, '1.0', 'all' );
}

帖子格式

子主题继承父主题定义的帖子格式。 但是当创建子主题时,请注意使用add_theme_support('post-formats')会覆盖父主题定义的格式,而不添加它。

RTL支持

要支持RTL语言,请将rtl.css文件添加到您的子主题中,其中包含:

/*
Theme Name: Twenty Fifteen Child
Template: twentyfifteen
*/

即使父主题没有rtl.css文件,建议将rtl.css文件添加到您的子主题中。 只有在is_rtl()为true时,WordPress才会自动加载rtl.css文件。

国际化

子主题可以通过使用WordPress国际化API来准备翻译成其他语言。 有关子主题国际化的特殊考虑。

要使子主题国际化,请按照下列步骤操作:

  • 1.添加语言目录。
    例如:twentyfifteen/language/
  • 2.添加语言文件。
    您的文件名必须是he_IL.po&he_IL.mo(取决于您的语言),不同于plugin-he_IL.xx的插件文件。
  • 3.加载文本域
    在after_setup_theme动作期间,在functions.php中使用load_child_theme_textdomain()。在load_child_theme_textdomain()中定义的文本域应该用于翻译子主题中的所有字符串。
  • 4.使用GetText函数为字符串添加i18n支持。

示例:textdomain

<?php
/**
  * Set up My Child Theme's textdomain.
  *
  * Declare textdomain for this child theme.
  * Translations can be added to the /languages/ directory.
  */
function twentyfifteenchild_theme_setup() {
    load_child_theme_textdomain( 'twentyfifteenchild', get_stylesheet_directory() . '/languages' );
}
add_action( 'after_setup_theme', 'twentyfifteenchild_theme_setup' );
?>

此时,子主题中的字符串已准备好进行翻译。 为了确保它们被正确地翻译成国际化,每个字符串需要有twentyfifteen文本域。

示例:gettext函数

这是一个回应短语“Code is Poetry”的例子:

<?php
esc_html_e( 'Code is Poetry', 'twentyfifteenchild' );
?>

在load_child_theme_textdomain()中定义的文本域应该用于翻译子主题中的所有字符串。 如果父类中包含一个模板文件,则应将该文本域从父主题中定义的模板文件更改为子主题定义的文本。

Tags