如何覆盖 WordPress 子主题中的小部件?

How to override a widget in a child theme in WordPress?

我想对父主题中位于此处的 PHP 文件进行简单修改:

wp-content\themes\sailing\inc\widgets\gallery\tpl\base.php

所以我在子主题中创建了相同的文件夹结构,并在此文件中进行了我需要的修改。我还 copied/pasted 声明此小部件所需的所有 PHP 文件。

wp-content\themes\sailing\inc\widgets\widgets.php  
wp-content\themes\sailing\inc\widgets\gallery\gallery.php

wp-content\themes\sailing-child\inc\widgets\widgets.php  
wp-content\themes\sailing-child\inc\widgets\gallery\gallery.php

我在这里错过了什么?

WordPress 子主题无法以这种方式工作。您可以通过在子主题中使用相同路径覆盖的唯一文件是 "basic" 文件:index.php、page.php、style.css...主要是模板文件。

涉及覆盖子主题中的 函数或 classes 时。您有多种处理方式:

  1. 重新声明 functions/classes
  2. 复制 functions/classes

但这取决于您的主题是如何构建的以及它是否 "child theme" 就绪。让我们看看您的小部件问题。

如果您在父主题中打开小部件声明文件,您会看到如下内容:

class Widget_Name extends WP_Widget {
...
CODE OF THE WIDGET
...

参见:https://codex.wordpress.org/Widgets_API

理想的情况是您没有先看到上面几行,但是:

if(!class_exists('Widget_Name')) {
    class Widget_Name extends WP_Widget {
    ...
    CODE OF THE WIDGET
    ...

这意味着,您可以 copy/past 您的文件,这样就可以正常工作,您的小部件将覆盖父小部件,并且不会抛出任何错误,因为父小部件不会被执行。这就是 "child theme ready" 主题。请注意,它与函数 (if(!function_exists('function_name')).

相同

不要忘记从 child-theme/functions.php 文件中调用文件 ,因为默认情况下不会调用它。

赞:

require_once('path/to/your/widget_class.php');

其他方式,如果您没有 class_exists 调用只是复制文件,请使用 require_once 调用它。您应该会看到一个错误,因为您定义了 2 倍相同的 class。 PHP 不会让这种情况发生,致命错误。

只需重命名:

class Widget_Name2 extends WP_Widget {

在文件的某处(大部分时间在末尾),查找 register_widget( 并编辑 class 名称:

register_widget( 'Widget_Name2' );

这不是最方便的方法,因为您将拥有 2 次相同的小部件,但这确实有效。

因此,由于@2Fwebd 的答案有点不完整(如评论中所标记),这里有一个更完整的答案(只是为了使其比答案及其评论更清楚。)我建议对他的答案进行编辑,但虽然它不被接受,但这里有一个更完整的答案:

WordPress 子主题无法以这种方式工作。您可以通过在子主题中使用相同路径覆盖的唯一文件是 "basic" 文件:index.php、page.php、style.css...主要是模板文件。

涉及覆盖子主题中的函数或 classes 时。您有多种处理方式:

  1. re-declaring functions/classes
  2. 复制 functions/classes

但这取决于您的主题是如何构建的以及它是否 "child theme" 就绪。让我们看看您的小部件问题。

如果您在父主题中打开小部件声明文件,您会看到如下内容:

class Widget_Name extends WP_Widget {
...
CODE OF THE WIDGET
...

参见:https://codex.wordpress.org/Widgets_API

理想的情况是您没有先看到以上几行,但是:

if(!class_exists('Widget_Name')) {
    class Widget_Name extends WP_Widget {
    ...
    CODE OF THE WIDGET
    ...

这意味着,您可以 copy/past 您的文件,这样就可以正常工作,您的小部件将覆盖父小部件,并且不会抛出任何错误,因为父小部件不会被执行。这就是 "child theme ready" 主题。请注意,它与函数 (if(!function_exists('function_name')).

相同

不要忘记从您的 child-theme/functions.php 文件调用您的文件,因为默认情况下不会调用它。

喜欢:

require_once('path/to/your/widget_class.php');

其他方式,如果您没有 class_exists 调用只是复制文件,请使用 require_once 调用它。您应该会看到一个错误,因为您定义了 2 倍相同的 class。 PHP 不会让这种情况发生,致命错误。

只需重命名:

class Widget_Name2 extends WP_Widget {

然后,将 parent::_construct 中的 id_base 更改为唯一 ID(如下所示:

parent::__construct( 'new_uniq_id', 'name of your widget', ...)

在文件的某处(大部分时间在末尾)查找 register_widget( 并编辑 class 名称:

register_widget( 'Widget_Name2' );

这不是最方便的方法,因为您将拥有 2 次相同的小部件,但这确实有效。

希望对大家有所帮助。