WordPress教程

WordPress子主题中覆盖父主题的函数功能

阿里云

如果您有使用 WordPress 中的父主题和子主题的经验,您会知道子主题中的模板文件会覆盖父主题中的模板文件。例如,如果您的父主题具有 page.php 文件,并且您在子主题中创建了一个同名的新文件,那么 WordPress 在显示页面时将使用子主题的这个 page.php 文件。

您可能会认为函数(function)会以相同的方式工作:在子主题的 functions.php 文件中创建一个与父主题名称相同的新函数,它将优先运行。不幸的是,它并非如此简单。

也想出现在这里?联系我们
创客主机

在研究覆盖父主题中的函数的方法之前,它有助于了解函数在父主题和子主题中的工作方式。首先,您需要知道当您使用子主题时,父主题中的所有函数都将运行。您无需在子主题的功能文件 functions.php 中添加任何内容即可实现此目的。这与 CSS 不同,在 CSS 中,您必须手动将父主题的样式表包括在子主题的样式表中。

此外,如果您的父主题和子主题具有相同名称的函数,则这将破坏您的网站,除非父主题中的函数是可插拔的函数(稍后将对此进行详细介绍)。这就是为什么为所有函数需要使用前缀并且在父主题和子主题中使用不同的前缀(以防万一)的原因。但是,您可以更改函数的触发顺序,并且可以完全阻止函数触发,我们将很快看到。

可插拔(扩展)函数(Pluggable Functions)是您在父主题中编写的代码,因此,如果您正在使用不具有可插拔功能的现有父主题,则它们对您没有任何用处。

但是,如果您正在编写自己的父主题,或者作为将来项目的起点,或者正在创建自己的主题框架,则最好使函数可插拔,以便可以轻松地在子主题中覆盖它们。浏览正在使用的父主题中的函数也是一个好主意,因为其中许多函数(包括 WordPress 默认主题)将具有可插拔功能。

要编写可插拔函数,只需将其封装在条件标记中,以检查具有该名称的函数是否已运行:

  1. <?php
  2. if ( ! function_exists ( 'my_function' ) ) {
  3.     function my_function() {
  4.         // Contents of your function here.
  5.     }
  6. }
  7. ?>

因此,如果您将父主题中的函数包含在这样的条件标记中,则 WordPress 将检查子主题中是否已经有同名函数已经运行过,如果是这种情况,它将不会运行父主题的函数。

然后,当您要在子主题中编写要覆盖父主题中的功能的函数时,只需为其命名与父主题中的名称相同即可:

  1. <?php
  2. function my_function() {
  3.     // Contents for your function override here.
  4. }
  5. ?>

WordPress 将首先在子主题中运行该函数,当涉及到父主题中的函数时,它将检查它是否已经存在,并且因为它已经存在,所以不会运行它。

如果您没有使用自己的父主题,或者正在使用没有可插拔函数的第三方主题,则需要另一种方法。在编写函数时,可以为它们分配优先级,告诉 WordPress 何时运行它们。将函数添加到动作或过滤器挂钩时,可以执行此操作。WordPress 将按照优先级的升序运行附加到给定钩子上的函数,因此优先级数字更大的那些将最后运行。让我们想象一下父主题中的函数不可插拔,并且看起来像这样:

  1. <?php
  2. function parent_function() {
  3.     // Contents for your function here.
  4. }
  5. add_action( 'init', 'parent_function' );
  6. ?>

此函数已附加到 init 钩子上,尚未获得优先级。默认情况下,WordPress 会为尚未添加优先级的功能分配优先级为 10 ,因此要在该函数运行后执行新函数,请使用大于 10 的数字。我倾向于使用 15 ,以便在以后要在两者之间添加另一个函数的情况下留出一些喘息的空间。

这意味着您的子主题中的函数将如下所示:

  1. <?php
  2. function child_function() {
  3.     // Contents for your function here.
  4. }
  5. add_action( 'init', 'child_function', 15 );
  6. ?>

或者,您父主题中的函数可能已分配了优先级:

  1. <?php
  2. function parent_function() {
  3.     // Contents for your function here.
  4. }
  5. add_action( 'init', 'parent_function', 20 );
  6. ?>

因此,您只需要确保在子主题中赋予该函数更高的的优先级:

  1. <?php
  2. function child_function() {
  3.     // Contents for your function here.
  4. }
  5. add_action( 'init', 'child_function', 25 );
  6. ?>

有时,在第一个函数之后运行另一个函数不足以覆盖它 - 您需要确保父主题中的函数根本不运行。在这种情况下,您可以使用 remove_action() 或 remove_filter() 函数将父主题函数从其附加的挂钩中删除 。您将使用的函数取决于该功能是附加到父主题中的动作挂钩还是过滤器挂钩。让我们回到父主题中的上一个函数:

  1. <?php
  2. function parent_function() {
  3.     // Contents for your function here.
  4. }
  5. add_action( 'init', 'parent_function' );
  6. ?>

要将函数从其动作挂钩中删除并防止触发,请在子主题中创建一个函数,以使用 remove_action()以下方法将其删除 :

  1. <?php
  2. remove_action( 'init', 'parent_function' );
  3. ?>

但是,这不能单独工作-您需要将此函数附加到一个钩子上, 该钩子将在附加了父主题函数的钩子之后触发 。这是因为您无法在触发操作之前将其删除。您可以在官方文档中找到触发操作顺序的详细信息 。

  1. <?php
  2. function child_remove_parent_function() {
  3.     remove_action( 'init', 'parent_function' );
  4. }
  5. add_action( 'wp_loaded', 'child_remove_parent_function' );
  6. ?>

完成此操作后,您可以在子主题中编写一个替代函数来替换父主题的函数,或者如果您要做的只是从父主题中删除该功能,那您什么也不需要做了。

请注意,如果您尝试使用 remove_action() 或 remove_filter() 删除函数功能 , 并且该函数已分配了优先级,则删除时必须包含该优先级,否则它将无法正常工作。因此,如果父主题中的函数如下所示:

  1. <?php
  2. function parent_function() {
  3.     // Contents for your function here.
  4. }
  5. add_action( 'init', 'parent_function', 15 );
  6. ?>

删除时,您需要包含相同的优先级值:

  1. <?php
  2. function child_remove_parent_function() {
  3.     remove_action( 'init', 'parent_function', 15 );
  4. }
  5. add_action( 'wp_loaded', 'child_remove_parent_function' );
  6. ?>

除上述内容外,在某些特定情况下,您可能需要进一步处理。以下提示是针对以下评论中提出的问题的解答。严格来说,您不能部分覆盖函数。您只能让它运行或禁用它。但是有解决方法。

第一种是您要部分覆盖的函数本身包含可插拔的函数。您可能会发现该函数包括从父主题中调用另一个可插拔函数。在这种情况下,如果您要更改的代码,则可以覆盖主函数中的任何函数。通过编写新版本的可插拔函数来做到这一点,该函数仅包含一条 return 语句或包含替代代码。请注意,这仅在该函数可插拔时才有效;否则,您的站点将中断。

但是,仅当您足够幸运地需要重写由另一个包含的可插入函数提供的函数中的功能时,此方法才有效。在大多数情况下,这不是一个选择。在这种情况下,您将需要停用该函数,并使用其他名称的自己的函数来替换它。要创建新函数,您可以将函数从父主题复制并粘贴到子主题的 functions.php 文件中,然后对其进行编辑以删除不需要的代码。

您将使用两个自己的函数:一个删除原始函数,第二个提供新代码,如下面的示例覆盖在 init 钩子上调用的父主题:

  1. <?php
  2. function remove_parent_function(
  3.     remove_action( 'init', 'parent_theme_function');
  4. )
  5. add_action( 'wp_loaded', 'remove_parent_function');
  6.  
  7. function child_theme_function(
  8.     // contents of child theme function based on original parent theme function
  9. )
  10. add_action( 'init', 'child_theme_function');
  11. ?>

父主题中不可插拔的函数不能以任何特殊方式覆盖。因此,您必须使用上述方法,从其动作挂钩中删除该函数,然后在提供新代码的同一动作挂钩上编写一个新函数。不要给子主题中的函数命名与父主题中的函数相同的名称,因为这会破坏您的站点!

函数通常不设计为可扩展的。但是,如果您的函数包含对其他可插拔函数的调用,则可能会有例外。在这种情况下,您可以通过覆盖主功能中的函数来扩展功能,而不必替换整个主函数。在大多数情况下,您只能通过以下三种方式之一扩展父主题函数:

  • 如果您要扩展的函数是可插拔的,请将其复制到您的子主题中并添加额外的代码以对其进行扩展。
  • 如果该函数不可插拔,请使用remove_action() 将该钩子从其挂钩中删除,并使用相同的代码在同一个钩子上编写一个新函数(名称不同)。您可以将代码从原始函数复制到新函数中并进行编辑。
  • 编写第二个函数,该函数在与第一个函数相同的钩子上调用,并添加将在第一个函数之前或之后运行的额外代码。在 add_action() 中使用优先级(priority)参数,指定您的第二个函数将在原始函数之前还是之后运行。

您使用哪种方法将取决于父主题的编码方式以及是否需要完全删除父主题的函数功能,还是仅在其后运行另一个函数以覆盖它。

WordPress 子主题中覆盖父主题的函数功能

已有 212 人购买
查看演示升级 VIP立刻购买

收藏
(0)

发表回复

热销模板

Ashade - 作品展示摄影相册WordPress汉化主题
LensNews

本站承接 WordPress / PbootCMS / DedeCMS 等
系统建站、仿站、开发、定制等业务!