使用 WordPress 子主题的终极指南

已发表: 2016-01-05

如果您想定制您在 HeroThemes 从我们这里购买的主题,或者如果您正在使用定制设计为自己或您的客户构建网站,那么您需要能够利用 WordPress 子主题的力量。

在最基本的情况下,使用子主题将使您更有效率——将您用于每个项目的代码保留在您自己的父主题中,或者使用像我们这样的现成父主题,这意味着您坚持DRY(不要重复自己)原则。

但更进一步,您可以使用子主题和父主题创建具有核心代码库的站点网络,您可以基于第三方主题框架构建自定义主题,或者您甚至可以创建自己的高级父主题以用作主题框架. 在本文中,我将简要概述儿童主题的基本要素,然后向您展示一些更高级的技术。 您将学习:

  • 如何使用子主题使第三方父主题或主题框架适应您的项目需求
  • WordPress 如何对每个父主题和子主题中的模板文件进行优先级排序
  • 如何在子主题的函数文件中覆盖父主题函数。

了解父子主题

理论上,任何主题都可以作为父主题,尽管有些主题更适合这个角色(包括我们的!)。 如果您正在使用我们的某个主题并想针对您自己的项目对其进行调整,那么使用子主题来执行此操作比破解主主题要好得多,这意味着您将在更新时丢失所有更改未来版本的主题。 要创建子主题,您只需创建一个新主题并将以下内容添加到其样式表的开头。 下面的示例使用 HeroThemes 主题 HelpGuru 作为父主题,但您可以使用任何主题,包括另一个 HeroTheme 的产品,例如 KnowAll。

立即开始建立您的知识库!

我们的 KnowAll 主题包括一个子主题,可帮助您自定义知识库站点

获取主题
/*
Theme Name: My child theme
Theme URI: URL of the theme or site it's used for
Description: Description of what the theme is for and its main features.
Author: Your name
Template: helpguru
Version: 1.0
*/
@import url("../helpguru/css/style.css");

重要的几行是这两行:

Template: helpguru
@import url("../helpguru/css/style.css");

第一部分指定模板,它告诉 WordPress 这是一个子主题,它的父主题是 HelpGuru 主题。 请注意,您在这里使用父主题文件夹的名称而不是主题的名称(所以上面我使用了“helpguru”,而不是“HelpGuru”)。

HelpGuru 可以使用子主题进行转换
HelpGuru 可以使用子主题进行转换

第二部分从父主题导入样式表,这意味着所有父主题的样式都将在您的子主题中激活。 然后,您在此@import声明下方添加自己的样式 - 这意味着将使用来自两个主题的样式,但是如果两个样式表中都存在同一元素的声明,则子主题的 CSS 将由于级联而占上风(作为您的子主题的样式来自父主题的样式)。

一个子主题可以包含一个样式表,如果您愿意,可以只包含一个样式表,在这种情况下,您将使用它来做的就是覆盖一些父主题的样式。 或者,您可以添加额外的模板文件和/或函数文件,在这种情况下,您需要了解 WordPress 如何从您的父主题和子主题访问模板文件。

父子主题模板文件

WordPress 在父子主题中使用模板文件的方式非常简单。 当显示给定页面(或帖子或任何其他内容类型)时,WordPress 将根据模板层次结构使用父主题或子主题中最相关的模板文件。 如果它找到同一个模板文件的两个版本,它将使用子主题中的一个。 这意味着您的子主题的模板文件将在两种情况下覆盖父主题的模板文件:

  • 如果您的子主题包含的模板文件在层次结构中高于父主题中的模板文件;
  • 或者如果您的父主题和子主题都包含所需模板文件的版本。

决定父主题模板文件还是子主题模板文件

WordPress 将使用模板层次结构来确定要使用的模板文件,但这会与您在每个父主题和子主题中的文件交互。 简单来说,WordPress 经历了三个步骤:

  1. 它标识正在显示的内容的类型。
  2. 它通过模板层次结构工作,直到找到一个文件来显示该内容,无论是在父主题还是子主题中。
  3. 如果该文件同时存在于父主题和子主题中,则它使用来自子主题的文件。

让我们用一个例子来说明这一点。 下表显示了两个假设主题中的模板文件集,其中一个是另一个的子主题。 我强调的文件优先。

WordPress 如何选择要使用的模板
WordPress 如何选择要使用的模板

所以在上面的例子中,让我们看看哪些模板文件将用于显示某些类型的内容:

  • “产品”自定义帖子类型的单个帖子将使用子主题中的single-product.php显示。
  • 其他帖子类型(包括普通帖子)的单个帖子将使用子主题中的single.php显示。
  • 静态页面将使用父主题中的page.php显示。
  • 小部件类别的列表将使用子主题中的category-widgets.php显示。
  • 其他类别列表将使用父主题中的category.php显示。
  • 其他存档列表将使用父主题中的archive.php显示。
  • 搜索结果将使用父主题中的search.php显示。
  • 404 页面将使用父主题中的404.php显示。
  • 其他没有特定模板文件的页面将使用子主题中的index.php显示。

更进一步——覆盖父主题功能

除了覆盖或补充父主题中的 CSS 和/或模板文件之外,您还可以使用子主题来覆盖父主题中的功能或添加额外的功能。

警告! 如果您使用子主题只是为了添加额外的功能,那么您最好编写一个插件。 不幸的是,父主题和子主题中的函数文件与样式表的交互方式不同,实际上它们以相反的方式工作(令人困惑,我知道)。 WordPress 在子主题之后调用父主题中的函数,这意味着它们可以覆盖子主题的函数。 我知道这听起来有点痛苦:您创建了一个子主题,因为这就是您想要在您的网站中使用的内容,对吧? 好吧,幸运的是有办法克服这个问题。 第一种方法是您在子主题中使用的方法,即在将函数附加到相关操作或过滤器挂钩时设置优先级。 第二个是在父主题中完成的,这是为了使您的功能可插入。 稍后我会谈到这一点,但首先让我们看看您的孩子主题中的方法。

使用优先级覆盖父主题功能

要激活您在子主题中添加的每个功能,您需要使用add_action()add_filter()将其附加到操作挂钩或过滤器挂钩。 add_action()add_filter()函数具有三个参数:

  • $tag – 动作或过滤钩子的唯一标识符
  • $function_to_add – 函数的名称
  • $priority - 你想挂接你的函数的优先级(很快就会有更多)

使用add_filter()您可以使用第四个可选参数$arguments ,但这与子主题并不特别相关。 在大多数情况下,只使用前两个参数(这两个参数都是必需的),但您可以使用可选的$priority参数将父主题中的函数覆盖为子主题中的函数。 优先级越高,加载越晚:默认为10 ,因此如果父主题没有指定优先级,您只需将子主题中的优先级设置为高于 10 的数字。让我们看看这是如何实现的作品。 假设您正在使用 HelpGuru 主题的子项,并且您想要覆盖菜单功能并添加您自己的功能。 这个主题包括ht_theme_setup()函数来设置主题(包括注册菜单,添加特色图像支持等等),它附加到after_setup_theme动作挂钩。 HelpGuru的functions文件中的代码如下:

if ( ! function_exists( 'ht_theme_setup' ) ) :
function ht_theme_setup() {
// contents of function
}
}
add_action( 'after_setup_theme', 'ht_theme_setup' );

要在您的子主题中覆盖ht_theme_setup()函数的元素(但不是全部:我们很快就会谈到),您将编写一个函数来替换 HelpGuru 提供的功能元素并将其附加到after_setup_theme操作挂钩,指定高于 10 的优先级:

function my_theme_setup() {
// contents of function
}
add_action( 'after_setup_theme', 'my_theme_setup', 15 );

当 WordPress 遇到这些附加到同一个钩子的函数时,它会首先触发较低优先级的函数,即来自父主题的函数。 然后它将从您的子主题中触发更高优先级的主题,这意味着它可以覆盖父主题中的功能。 正如我上面提到的,还有另一种方法,最好将其写入您的主题中,这样它们就可以更容易地用作父主题,这就是使您的函数可插入。

使用可插入函数来允许子主题覆盖

由于 WordPress 在子主题中传递父主题中的函数,因此您可以对父主题的函数进行编码,以便它们检查子主题中具有相同名称的函数,如果存在,则父主题函数不存在通过了。 您可以使用条件语句来执行此操作,就像我们在 HelpGuru 上面看到的那样:

if ( ! function_exists( 'ht_theme_setup' ) ) :
function ht_theme_setup() {
// contents of function
}
}

如果没有同名的函数已经被传递(例如在子主题中),来自父主题的函数将被传递。 但是如果 WordPress 已经遇到过具有此名称的函数,它将忽略可插入函数(即父主题中的函数)。 为了使这项工作,您只需在您的子主题中创建与您想要覆盖的父主题中的名称相同的函数。 因此,要完全覆盖ht_theme_setup()函数,您可以在子主题中使用它:

function ht_theme_setup() {
// contents of function
}

而已! 只需编写另一个具有相同名称的函数,它将覆盖父主题中的函数。 注意:此技术仅在您创建自己的父主题时才有效——不要试图在第三方父主题中编辑函数文件以使其可插入。 毕竟,创建子主题的全部意义在于不要触碰父主题!


概括

正如我希望我已经证明的那样,使用子主题可以提高您作为 WordPress 开发人员的效率和效力,特别是如果您为客户或您自己开发自定义网站。 至少,使用现有主题的子主题(例如我们的 HeroThemes 之一)可以使您的开发工作流程更快、更高效,因为它可以节省您一遍又一遍地做同样的工作。

您可以通过使用子主题的模板文件和函数文件来覆盖或补充父主题的功能,从而进一步实现这一点。 如果您真的想将子主题发挥到极致,您可以构建自己的父主题,为您提供所有新项目的快速起点,让您可以比从头开始更轻松地为子主题添加更多内容.