如果我想要相同的文件夹结构,有什么好方法可以重写子主题中的文件?

时间:2020-05-07 作者:Daniel Simmons

我的父主题的结构如下Core\\Utilities\\Gallery.php. 它位于的命名空间中Product\\Theme\\Core 使用composer的自动加载加载文件。我想,我在主题中有大量的过滤器,但当涉及到文件时,如果只是简单地遵循父主题的相同结构来覆盖,那就更好了。

我知道子主题只能覆盖模板文件,但在一个优秀的开发人员的技巧包中,有什么好的工具/方法可以克服这一问题?

如果有更好的方向,我甚至可以重写整件事。

1 个回复
最合适的回答,由SO网友:Jacob Peattie 整理而成

因为您使用的是Composer,所以没有任何提供子主题支持的常规方法适用。

对于不使用composer的主题,可以使用get_theme_file_path() 作用在函数中也是如此。php,而不是:

require_once \'Core\\Utilities\\Gallery.php\';
您可以使用:

require_once get_theme_file_path( \'Core\\Utilities\\Gallery.php\' );
get_theme_file_path() 将返回子主题中给定文件的完整路径(如果存在),否则将在父主题中为其提供路径。这意味着可以通过在子主题中放置具有相同名称和路径的文件来替换以这种方式包含的任何文件。

对于使用Composer自动加载类文件的主题,这不适用,因为您没有手动按路径包含PHP文件。相反,您可能正在使用Composer的自动加载程序,在Composer中添加类似的内容。json文件:

"autoload": {
    "psr-4": {
        "Product\\\\Theme\\\\Core\\\\": "Core/"
    }
},
所以像这样的班级Product\\Theme\\Core\\Utilities\\Gallery 将从加载Core\\Utilities\\Gallery.php. 由于目录是相对于父主题的目录的,并且Composer正在执行实际的包含,因此您不能使用get_theme_file_path().*

允许子主题替换类的一种方法是将子主题文件夹添加到命名空间的自动加载生成器中。json:

"autoload": {
    "psr-4": {
        "Product\\\\Theme\\\\Core\\\\": [ "../child-theme/Core", "Core/" ]
    }
},
这是可行的,但明显的问题是,它需要将子主题的名称硬编码到父主题中。所以这不是一个切实可行的解决方案。

但是,如果子主题使用composer本身,它可以将其目录之一注册为父主题命名空间中文件的源。例如,如果子主题使用composer并将其添加到其composer中。json文件:

"autoload": {
    "psr-4": {
        "Product\\\\Theme\\\\Core\\\\": "Core/"
    }
},
然后,它可以通过在自己的主题中放置副本来替换父主题中的类文件Core/ 目录,因为composer也会在子主题中查找类文件。

要使其工作,您需要确保子主题vendor/autoload.php 在父主题之后加载文件,否则PHP将首先查看父主题,因为父主题的自动加载程序是最后注册的。这是因为子主题的功能。php文件在父主题之前加载。解决方案是让子主题在after_setup_theme 挂钩:

add_action(
    \'after_setup_theme\',
    function() {
        require_once \'vendor/autoload.php\';
    }
);
您可能会注意到,使用此解决方案,父主题实际上没有做任何事情。这是子主题可以用来替换类的努力,即使父主题并不打算这样做,也可以这样做。

*据我所知,有一种方法可以配置Composer,使其成为可能,但我不知道。