如果您曾在wordpress中使用过父主题和子主题,您就会知道子主题中的模板文件会覆盖父主题中的模板文件。例如,如果您的父主题有一个页面。php 文件并在子主题中创建一个新文件,WordPress 将在显示页面时使用子主题中的文件。
您可能认为函数会以相同的方式工作:在您的子主题的 functions.php 文件中创建一个与父主题中的同名的新函数,它会优先。不幸的是,事情并没有这么简单。
在本教程中,我将向您展示三种可用于在子主题中覆盖父主题中的函数的方法:
可插拔功能
功能优先级
从它们附加到的钩子中删除函数
父子主题中的功能如何工作
在检查子主题中覆盖函数的方法之前,了解函数在父主题和子主题中的工作方式会有所帮助。
首先,您需要知道当您使用子主题时,您的父主题中的所有功能都会运行。您无需向子主题的函数文件添加任何内容即可实现此目的。这与css不同,您必须手动将父主题的样式表包含在子主题的样式表中。
要知道的另一件事是,如果您的父主题和子主题具有相同名称的函数,这将破坏您的站点——除非父主题中的函数是可插入的函数(稍后会详细介绍)。这就是为什么为所有函数使用前缀很重要,并在父主题和子主题中使用不同的前缀——以防万一。
但是,您可以更改函数被触发的顺序,并且您可以完全避免事件函数被触发,我们很快就会看到。
可插拔功能
可插入功能是您在父主题中编码的东西,因此如果您正在使用没有它们的现有父主题,它们对您没有任何用处。
但是,如果您正在编写自己的父主题,可能作为未来项目的起点,或者如果您正在创建自己的主题框架,最好让您的函数可插入,以便您可以轻松地在子进程中覆盖它们主题。查看写入您正在使用的父主题中的函数也是一个好主意,因为其中许多函数,包括 WordPress 默认主题,将具有可插入的函数。
要编写可插入函数,您只需将其包含在条件标记中,以检查具有该名称的函数是否已运行:
<?php if ( ! function_exists ( 'my_function' ) ) { function my_function() { // Contents of your function here. } } ?>
因此,如果您将父主题中的函数包含在这样的条件标记中,WordPress 将检查您的子主题中是否存在已运行的同名函数,如果是这种情况,它将不会运行父主题的功能。
然后,当您在子主题中编写一个要覆盖父主题中的函数时,只需将其命名为与父主题中的函数相同的名称:
<?php function my_function() { // Contents for your function override here. } ?>
WordPress 将首先在子主题中运行该功能,当涉及到父主题中的功能时,它会检查它是否已经存在,因为它存在,所以它不会运行它。
功能优先级
如果您没有使用自己的父主题,或者您使用的是没有可插入功能的第三方主题,则需要另一种方法。
当您编写函数时,您可以为它们分配优先级,这会告诉 WordPress 何时运行它们。在将函数添加到操作或过滤器挂钩时执行此操作。然后,WordPress 将按照优先级升序运行附加到给定钩子的函数,因此具有较高数字的函数将最后运行。
让我们想象一下父主题中的函数是不可插入的,看起来像这样:
<?php function parent_function() { // Contents for your function here. } add_action( 'init', 'parent_function' ); ?>
此函数附加到 init 钩子并且没有被赋予优先级。默认情况下,WordPress 将优先级分配给 10 尚未添加优先级的函数,因此要在它之后触发函数,请使用大于 10. 我倾向于使用 15 这样我有一些喘息的空间,以防我以后想在两者之间添加另一个功能。
这意味着您的子主题中的函数将如下所示:
<?php function child_function() { // Contents for your function here. } add_action( 'init', 'child_function', 15 ); ?>
或者,您的父主题中的功能可能已分配了优先级:
<?php function parent_function() { // Contents for your function here. } add_action( 'init', 'parent_function', 20 ); ?>
因此,您只需要确保您在子主题中赋予该功能的优先级更高:
<?php function child_function() { // Contents for your function here. } add_action( 'init', 'child_function', 25 ); ?>
从 Hooks 中移除函数
有时,在第一个函数之后运行另一个函数并不足以覆盖它——您需要确保父主题中的函数根本不运行。在这种情况下,您可以使用 remove_action() or 函数从它所附加的钩子中删除父主题remove_filter() 函数。您使用的将取决于该函数是否附加到父主题中的操作挂钩或过滤器挂钩。
那么让我们回到我们之前在父主题中的函数:
<?php function parent_function() { // Contents for your function here. } add_action( 'init', 'parent_function' ); ?>
要从其动作挂钩中删除此函数并因此防止其触发,您可以在子主题中创建一个函数以使用以下方法将其删除 remove_action():
<?php remove_action( 'init', 'parent_function' ); ?>
但是,这不会单独工作——您需要将此函数附加到一个钩子上, 该钩子将在父主题函数附加到的钩子之后触发。这是因为您无法在动作被触发之前将其移除。您可以 在 Codex中找到触发操作顺序的详细信息。
<?php function child_remove_parent_function() { remove_action( 'init', 'parent_function' ); } add_action( 'wp_loaded', 'child_remove_parent_function' ); ?>
完成此操作后,您可以简单地编写一个替代函数来替换子主题的函数文件中的父主题函数,或者如果您只想从父主题中删除该功能,则您什么也做不了。
关于优先事项的说明
请注意,如果您尝试使用 remove_action() or 删除函数remove_filter() 并且该函数已分配了 优先级,则在删除它时必须 包括优先级,否则它将不起作用。
因此,如果父主题中的函数如下所示:
<?php function parent_function() { // Contents for your function here. } add_action( 'init', 'parent_function', 15 ); ?>
...删除它时,您需要包含相同的优先级值:
<?php function child_remove_parent_function() { remove_action( 'widgets_init', 'parent_function', 15 ); } add_action( 'wp_loaded', 'child_remove_parent_function' ); ?>
高级父子主题函数:可插入函数和扩展函数
除了上述之外,还有一些特定的场景ios,您可能希望在其中更进一步。以下提示是对以下评论中提出的问题的回应。
如何部分覆盖父主题中的函数
严格来说,你不能部分覆盖一个函数。您只能让它运行或禁用它。但是有一些解决方法。
第一个是如果您要部分覆盖的函数本身包含可插入的函数。您可能会发现该函数包括从父主题中调用另一个可插入函数。
如果是这种情况,您可以覆盖主函数中的任何函数,如果这是您想要更改的代码。return 通过编写仅包含一条语句或包含替代代码的可插入函数的新版本来做到这一点 。请注意,这仅在该功能是可插入的情况下才有效 - 如果不是,您的站点将中断。
但是,此方法仅在您有幸需要覆盖由另一个包含且可插入的函数提供的函数中的功能时才有效。
在绝大多数情况下,这不是一个选择。在这些情况下,您需要停用该功能并将其替换为您自己的具有不同名称的功能。要创建新函数,您可以将父主题中的函数复制并粘贴到子主题的 functions.php 文件中,然后对其进行编辑以删除不需要的代码。
您将使用您自己的两个函数:一个删除原始函数,第二个提供新代码,就像这个示例覆盖在 init 挂钩上调用的父主题:
<?php function remove_parent_function( remove_action( 'init', 'parent_theme_function'); ) add_action( 'wp_loaded', 'remove_parent_function'); function child_theme_function( // contents of child theme function based on original parent theme function ) add_action( 'init', 'child_theme_function'); ?>
如何覆盖不可插拔的函数
不能以任何特殊方式覆盖父主题中不可插入的函数。所以你必须使用上面的方法,从它的动作钩子中删除函数,然后在提供新代码的同一个动作钩子上编写一个新函数。
不要将子主题中的函数与父主题中的函数同名,因为这会破坏您的网站!
如何扩展父主题功能
功能通常不被设计为可扩展的。但是,如果您的函数包含对其他可插入函数的调用,则可能会有例外。
如果是这种情况,您可以通过覆盖 main 函数中的函数来扩展该函数,而不必替换整个 main 函数。
在大多数情况下,您只能通过以下三种方式之一扩展父主题功能:
如果您要扩展的功能是可插拔的,请将其复制到您的子主题中并添加额外的代码来扩展它。
如果该函数不可插入,请使用将其从其钩子中删除, remove_action() 并在同一个钩子上使用额外的代码编写一个新函数(具有不同的名称)。您可能希望将原始函数中的代码复制到新函数中并对其进行编辑。
编写第二个函数,该函数在与第一个函数相同的钩子上调用,并添加将在第一个函数之前或之后运行的额外代码。使用优先级参数 in add_action() 来指定您的第二个函数是在原始函数之前还是之后运行。
概括
覆盖父主题中的函数比覆盖模板文件或样式更复杂,但可以做到。在这里,我向您展示了执行此操作的三种方法:
如果您正在编写自己的父主题,或者使用具有它们的父主题,请使用可插入函数,以便子主题中与父主题中同名的函数将替换它。
为您的子主题中的功能分配更高的优先级,以确保它们在您的父主题中运行。
使用 remove_action() 或 remove_filter() 完全删除父主题中的功能。
您使用哪种方法将取决于您的父主题的编码方式以及您是否需要完全删除父主题函数或只是在它之后运行另一个函数来覆盖它。
- 父子主题中的功能如何工作
- 关于优先事项的说明
- 如何部分覆盖父主题中的函数
- 如何覆盖不可插拔的函数
- 如何扩展父主题功能