Hooks 是的集合名称filters 和actions. 两者都是为了改变函数的正常行为。从编程角度来说,没有什么大的区别,正如您从以下事实中所看到的in the WP source code 添加操作与添加筛选器相同。
区别在于用法。您可以使用操作来完全更改函数的行为或向现有函数添加某些内容。您可以使用过滤器更改函数或变量的结果。读一点more on the theory here.
Example
假设这是您的主题模板文件
index.php
:
$me = \'I love Star Wars\';
$you = \'I love Star Trek\';
$me = apply_filters (\'do_force\', $me);
$you = apply_filters (\'do_force\', $you);
do_action (\'echo_me_you\', $me, $you);
然后在
functions.php
对于主题或插件的主php文件,可以定义过滤器和操作。例如:
add_filter (\'do_force\',\'wpse_do_force\');
function wpse_do_force ($string) {
str_replace (\'Trek\',\'Wars\', $string); // change all occurences of \'Trek \' to \'Wars\'
return $string;
}
过滤器不影响
$me
, 但它确实改变了
$you
, 因为它在字符串中搜索“Trek”并将其更改为“Wars”。所以,在应用过滤器之后,我们都喜欢《星球大战》。
现在,代码转到操作。这可能非常简单:
add_action (\'echo_me_you\', \'wpse_echo_neutral\');
function wpse_echo_neutral ($me, $you) {
echo $me;
echo $you;
}
但是你可以随心所欲地采取行动。例如,您可以通过将所有发生的“战争”更改回“Trek”,使过滤器无效:
add_action (\'echo_me_you\', \'wpse_echo_trek\');
function wpse_echo_trek ($me, $you) {
str_replace (\'Wars\',\'Trek\', $me);
str_replace (\'Wars\',\'Trek\', $you);
echo $me;
echo $you;
}
How does this function?
当WordPress开始组装页面时,它会读取
functions.php
第一它在那里收集您添加的所有操作和过滤器。它将这些放在队列中。然后,当它发现
do_action
或
apply_filters
它获取相应的队列,并按照找到它们的顺序逐个执行操作/过滤器。
因此,在上面的示例中,定义了一个在过滤器上触发的函数do_force
定义了两个在操作上触发的函数echo_me_you
. 首先,它将过滤器应用于$me
, 然后应用过滤器$you
, 然后执行函数wpse_echo_neutral
最后wpse_echo_trek
.
Priorities
加载(子)主题后,插件(和父主题)也会加载。它们还添加了操作和过滤器。所以
filter you have written for the_title
可能看起来不起作用,因为该过滤器被插件中的另一个过滤器覆盖。这就是优先权派上用场的地方。
优先级允许您确定筛选器/操作在队列中的位置。因此,如果您对此进行定义:
add_filter (\'the_title\', \'wpse_the_title\', 999, 2);
优先级999应确保此筛选器作为队列中的最后一个筛选器执行(数字2是传递给筛选器/操作的参数量)。
It doesn\'t work!
是的,这种情况经常发生,或者看起来是这样。从上面的示例中可以看到,如果您有一个操作否决了过滤器,那么您可以对过滤器执行任何操作,而不会产生任何效果。您的子/父和插件的设置可能非常复杂,您必须仔细调试。
第一步是包括以下内容echo \'GOT HERE\'
作为你职能的第一行。这将告诉您是否调用了过滤器/操作。如果不是这样的话,你就太晚了。看看你的functions.php
:
add_action (\'wp_footer\',\'wpse_footer\');
function wpse_footer() {
add_action (\'wp_head\', \'wpse_head\');
}
function wpse_head() {
echo \'GOT HERE\';
}
这行不通,因为
do_action (wp_head)
已由WP在遇到
do_action (wp_footer)
. 因此,如果您向
wp_head
此时排队,则没有效果。始终查看
hook order 向本机WordPress挂钩添加操作时。一个常见的错误是试图将小部件中的脚本/样式文件排队。正如你从钩子顺序中所看到的,
dynamic_sidebar
, 小部件连接到WordPress页面的位置,在
wp_enqueue_scripts
.
可能根本无法执行筛选/操作还有其他原因。例如,因为WP在某些情况下跳过过滤器。在这里,您别无选择,只能深入研究源代码(或在WPSE上询问)。
第二步,一旦确定调用了过滤器,就要将其更改为非常高的优先级,以确保它不会被否决。此外,禁用所有插件以排除干扰。
第三步,如果您的函数被调用并且排除了干扰,但它仍然不起作用,那么这可能与您自己的编码技能有关。检查拼写错误、回显中间结果等,找出错误的地方。
Wrapping up
hooks系统是一个功能强大但有时令人困惑的系统,可以修改WordPress本身或插件/主题的行为。因为每个人都在使用流行的钩子,所以结果可能出乎意料。然而,大多数问题都可以通过仔细查看挂钩顺序和优先级来解决。