问题描述

我遇到的所有文档都会通过插件讨论覆盖可插拔功能。

如果你正在做主题开发怎么办?

我的 functions.php 需要另一个文件来覆盖 pluggable.php 中定义的 get_user_by()函数。

如果我省略了 if( function_exists() )调用,我得到 「无法重新发送…」 错误。

如果我包括 if( function exists() )调用,那么我没有错误,但是当然我的功能被忽略,因为可插拔版本存在。

基于 Dominic 在 the WordPress startup order 上的令人敬畏的帖子,很显然,pluggable.php 在您的主题的 functions.php 等之前加载,因此可以解释错误。

所以问题是 – 如何从一个主题中利用这个可爱的可插拔架构,而不需要编写插件,然后必须捆绑或安装主题?

更多注意事项:所以看来,这个论点是主题不应该试图做插件。但是这个说法是四岁以上 (根据 4 位数的 trac 号) 。考虑到今天主题开发景观的复杂拓扑结构,我很乐意听到一些沉重的打击者的看法。我想相信自那以后我们已经演变。

背景信息:我为客户开发了一个 one-off CMS 解决方案,具有很多自定义元数据,管理员 back-end 的定制,登录/身份验证过程,作品。当然,还有设计组件 – 这就是主题部分所在。事实上,这些组件根本不是可重用的组件 – 它们永远不会适用于另一个客户端,它们永远不会被放在 GPL 和开放源代码之下,而且它们最多肯定不会在其他 WordPress 部署上分发/安装。最好还有一些我将来会对未来项目有利的最佳实践,但这将是严格的参考/copy-paste 工作。

这听起来不像是插件给我的用例。主题是安装的,也许是二十一十一的孩子主题,也许是一个独立的,它的 functions.php 调用在一个包含的船只,每个处理有问题的 CMS 的不同方面。然后,主题模板文件使用在包含中定义的自定义’template tags’ 。我不想有一些主题文件依赖于某些插件或其他被激活等等。在系统中构建复杂性是没有意义的。当然,我可以把它放在 must-use 插件文件夹中,但是仍然感觉像是一个黑客 – 现在,与本项目所做的定制有关的一切都包含在 wp-content/themes/my-theme/中。我也不想考虑在一些插件文件夹中搜索东西。

不要误会我我喜欢插件,我使用它们并编写它们。当插件是 third-party 时,我会使用插件和这种高度自定义的主题开发,并表示远远超出了我在合理的时间框架内可能推出的最佳实践。但是当我需要修改一个 one-off 场景的核心功能时,我转而采取行动钩子,过滤器钩子,而且我想要能够依赖用户和身份验证方面的可插拔功能。

最佳解决方案

如果您为单个客户端构建,那么您应该绝对利用 mu-plugins

WordPress 中有很多东西在 functions.php 中无法做到。可插拔功能是其中之一,但更为明显的是,在 functions.php 之前,有许多挂钩 (动作和过滤器) 都会触发。在某些情况下,这些钩子甚至会在常规插件之前启动,然后需要使用 mu-plugins 或 network-activated 插件。在其他情况下,即使是 mu-plugin 也是太晚了。也许你需要在 sunrise.php 中的东西。或者甚至是 wp-config.php 的东西 (常数或其他) 。

我宁愿添加一些钩子到可插拔的功能,而不是使它更容易覆盖它们。我们不太可能再有一个可插拔的功能 – 他们的 pre-date 钩子和我几乎从来没有看到有一个好的 old-fashioned(new-fashioned?) 钩子有优势的情况。

六年后,Andy Skelton 仍然同意:「主题功能文件和插件之间有许多区别,让我们一起来吧。」

除此之外,这样的改变永远都不会发生。它会打破很多事情。 functions.php 的主体中无数主题调用函数,如果 pluggable.php 尚未加载 (如 current_user_can()) 或 wp_create_nonce(),将导致致命错误。他们都失败了它也会打破插件,通常可以开始在 plugins_loaded 上调用这些功能。 (刚刚在 wp-settings.php 中移动 pluggable.php,我下注一半的核心会破坏 – 或者至少是定制工具。)

最后,不可避免的想法是,一个主题可以包括一个单独的文件,如 pluggable.php,我们可以在加载插件时加载,因此可以覆盖可插拔功能。除了这个错误的想法 (见这篇评论的前四段),它仍然是不兼容的,因为直到 setup_theme 挂钩,可以通过过滤样式表和模板值来覆盖哪个主题被加载。

不幸的是,鉴于 WordPress 的架构如何,这只是不能成功的。好的是,有无数 (更好) 的方式来做到这一点。

(原本贴在这里:http://core.trac.wordpress.org/ticket/2479#comment:5)

次佳解决方案

在 once-off 项目的上下文中,将 must-use 代码放入 mu-plugins 是绝对适用的。如果 「一次性存在」 是一个问题,只需在 mu-plugins drop-in 的主题目录中创建一个符号链接,就会在搜索主题目录时显示。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。