深入解析wordpress_深入研究WordPress挂钩和过滤器

深入解析wordpress

WordPress comes loaded with a series of hooks and filters that let you hook into specific parts of when WordPress operates. For example, you can attach a custom function so that it executes when the WordPress save_post action is called, giving you access to the post being saved.

WordPress装有一系列的挂钩和过滤器,可让您挂钩WordPress运行时的特定部分。 例如,您可以附加一个自定义函数,以便在调用WordPress save_post操作时执行该函数,从而使您可以访问正在保存的帖子。

Plugins and themes are an area where hooks are in abundance. Any decent plugin or theme will come with a range of these hooks that they either use internally to operate or expose externally for developers. When a plugin or theme isn’t exposed enough you might have issue customizing how it operates.

插件和主题是一个包含大量钩子的区域。 任何体面的插件或主题都将带有这些钩子的范围,它们可以在内部用于操作或向开发人员外部公开。 如果插件或主题的暴露程度不足,则可能无法自定义其操作方式。

wordpress hooks banner

Generally speaking, the plugins and themes you will run into will be based around Object Orientated Design methods, where one or more classes define how the functionality works. Inside these classes they might define hooks that you want to remove entirely or replace with your own custom functions.

一般而言,您将遇到的插件和主题将基于面向对象的设计方法 ,其中一个或多个类定义了功能的工作方式。 在这些类中,它们可能会定义要完全删除的钩子,或者用自己的自定义函数替换。

Today were going to dig into WordPress hooks and how you can handle them both in a traditional sense and also when dealing with classes or objects.

今天,我们将深入探讨WordPress挂钩,以及如何在传统意义上以及在处理类或对象时如何处理它们。

卸下标准挂钩 (Removing Standard Hooks)

When hooks and filters are not inside a class they are fairly straight-forward to remove. To remove these hooks you need to use the remove_action function. The basics of this are that you need to supply the following:

当钩子和过滤器不在类中时,它们很容易删除。 要删除这些挂钩,您需要使用remove_action函数。 其基础是您需要提供以下内容:

  • $tag – The name of the hook to which the function is attached to.

    $tag –函数连接到的钩子的名称。

  • $function_to_remove – The name of the function that should be removed.

    $function_to_remove –应该删除的函数的名称。

  • $priority – The priority of the function when it was attached to the hook.

    $priority –函数的优先级,当它附加到钩子上时。

When actions hooks are created with do_action it will trigger all functions that have been added to it with add_action as soon as WordPress reaches it.

当使用do_action创建动作挂钩时,一旦WordPress到达,它将触发使用add_action添加到其中的所有功能。

示例1:标准WooCommerce挂钩 (Example 1: Standard WooCommerce Hook)

Let’s look at a visual example. Consider the WooCommerce plugin. When you’re on a single page (using the single-product template) you will by default see the breadcrumb bar.

让我们看一个视觉示例。 考虑一下WooCommerce插件。 当您在单个页面上(使用single-product模板)时,默认情况下会看到面包屑栏。

Basic WordPress hook WooCommerce

This is outputted via the do_action( 'woocommerce_before_main_content' ); hook. It’s purpose is to output the starting content wrapper and the breadcrumbs for the product.

这是通过do_action( 'woocommerce_before_main_content' );输出的do_action( 'woocommerce_before_main_content' ); 钩。 目的是输出产品的初始内容包装和面包屑。

WooCommerce hook photo

Since we know the name of the action and the function name attached to that hook, we can remove the function entirely as follows.

由于我们知道动作的名称和该钩子附带的函数名称,因此可以按照以下说明完全删除函数。

//remove breadcrumbs from single product
remove_action('woocommerce_before_main_content', 'woocommerce_breadcrumb', 20);

Now the breadcrumbs will disappear. As long as you know the name of the hook, the name of the function you want to remove and the priority you can remove and replace functions as you see fit. The priority of the hook is important as it has to match the priority used when the function was originally hooked.

现在,面包屑将消失。 只要知道钩子名称,要删除的函数名称以及可以根据需要删除和替换函数的优先级即可。 挂钩的优先级很重要,因为它必须与最初挂钩该函数时使用的优​​先级相匹配。

basic hook WooCommerce removed

删除类中添加的挂钩 (Removing Hooks Added Inside Classes)

When you have actions and filters defined inside classes it can be a little bit tricky. Even though you might know the name of the hook and the name of the function, you won’t be able to use remove_action as we did before.

当您在类内部定义了动作和过滤器时,可能会有些棘手。 即使您可能知道该钩子名称和该函数名称 ,也将无法像以前一样使用remove_action

The issue is that if a plugin or theme defines these actions inside of class, those hooks are now attached inside the class. To remove them you will need to pass in the class variable to the remove_action function as follows:

问题是,如果插件或主题在类内部定义了这些动作,则这些钩子现在将附加在类内部 。 要删除它们,您需要将类变量传递给remove_action函数,如下所示:

//remove a hooked function from within a call
function('hook_name', array($myclass, 'my_function_remove'), 10);

那么类对象到底在哪里? (So Where Exactly Is the Class Object?)

This often is the trickiest part. To remove your function you need the class object. To find this you will need to hunt through either the documentation for the plugin or theme (if there is anyway) or alternatively (and less excitingly) searching through their source code to find the variable name.

这通常是最棘手的部分。 要删除函数,您需要class对象。 为了找到这个,您将需要浏览插件或主题的文档(如果有的话),或者(不那么令人兴奋)搜索其源代码以找到变量名。

If the class is a Singleton class, meaning that there should be only one of them at a single time, then you should be able to get the class from using one of the classes inbuilt functions to return the instance of the class such as:

如果该类是Singleton类 ,则意味着一次只能有一个,那么您应该能够使用类的内置函数之一来返回该类,例如:

$myClassObject = MyClass::getInstance()

$myClassObject = MyClass::getInstance()

If the class doesn’t have a method like that you can try and get the object by calling it globally such as:

如果该类没有这样的方法,则可以尝试通过全局调用来获取对象,例如:

global $myClassObject

global $myClassObject

Since each developer develops differently you might have to search to find the variable you need. Hopefully, if the class has been structured correctly, you should be able to get the object.

由于每个开发人员的开发方式都不同,因此您可能必须搜索以找到所需的变量。 希望,如果类的结构正确,则应该可以获取该对象。

If you’re trying to remove visual elements outputted you should be able to trace back where it all comes from, for example:

如果您尝试删除输出的视觉元素,那么您应该能够追溯所有元素的来源,例如:

  1. If you’re trying to remove some text, inspect the element and see if it has any classes or ID’s.

    如果您要删除一些文本,请检查该元素并查看它是否具有任何类或ID。
  2. If you have something to search on you can open up your theme or plugin and search for where those classes or ID’s are uses, they most likely will be wrapped in some function.

    如果您有需要搜索的内容,则可以打开主题或插件,并搜索这些类或ID的使用位置,它们很可能将被包装在某些函数中。
  3. If you’ve found a function that causing the output, try and see if it’s hooked with add_action anywhere.

    如果找到了导致输出的函数,请尝试查看它是否与add_action挂钩。

If you’re successful you should have the name of the hook and the name of the function you want to remove. All you need is the object itself and you’re good to go!

如果成功,则应具有钩子的名称和要删除的函数的名称。 您所需要的只是对象本身,您一切顺利!

示例1:WooCommerce类中的钩子 (Example 1: Hook Inside WooCommerce Class)

Let’s look at a practical example so you can see how you’d apply this technique.

让我们看一个实际的示例,以便您可以了解如何应用此技术。

Inside of WooCommerce the WC_Emails class is used to generate the output for emails that are sent out (such as the new, processing and completed orders). Inside of WC_Emails the constructor attaches all of the various functions onto hooks to build the output as seen below.

在WooCommerce内部, WC_Emails类用于为已发送的电子邮件(例如新订单,处理订单和已完成订单)生成输出。 在WC_Emails内部,构造函数将所有各种函数附加到钩子上以构建输出,如下所示。

advanced class hook screenshot

When displaying an email WordPress will hit the woocommerce_email_customer_details hook and will trigger all functions attached to it. When this happens it will trigger the customer_details function defined in the WC_Emails class, outputting the customer details.

当显示电子邮件时,WordPress将点击woocommerce_email_customer_details钩子,并将触发所有附加功能。 发生这种情况时,它将触发WC_Emails类中定义的customer_details函数,输出客户详细信息。

advanced class hook details

If we didn’t want to display these details we would have to remove the customer_details function from the class.

如果我们不想显示这些详细信息,我们将不得不从类中删除customer_details函数。

Luckily, at the bottom of the constructor is the woocommerce_emails action that’s being called with do_action. We can hook onto there so we can remove our customer details. This hook is passed the object itself via $this so it’s perfect for our needs.

幸运的是,在构造函数的底部是被woocommerce_emails调用的do_action 。 我们可以挂在那儿,这样我们就可以删除我们的客户详细信息。 该钩子通过$this传递给对象本身,因此非常适合我们的需求。

//Remove email details from the `WC_Emails` class
function remove_customer_email_details($instance) {

    //remove `customer_details` hooked function
    remove_action('woocommerce_email_customer_details', array( $instance, 'customer_details'), 10);
}
add_action('woocommerce_email', 'remove_customer_email_details');

We call remove_action and pass in both the $instance and the customer_details function and when we view our emails the customer details have vanished, removed entirely.

我们调用remove_action并传入$instancecustomer_details函数,当我们查看电子邮件时,客户详细信息消失了,被完全删除了。

advanced class hook details removed

In this scenario, WooCommerce left a perfect location for us to hook onto so we could remove these functions. It’s up to the plugin or theme developer to place these handy hooks in locations where other developers may need them. That being the case you might struggle removing some functions if the developers haven’t thought about it.

在这种情况下,WooCommerce为我们提供了一个理想的位置,因此我们可以删除这些功能。 由插件或主题开发人员将这些方便的钩子放置在其他开发人员可能需要的位置。 在这种情况下,如果开发人员未考虑删除某些功能,则可能会遇到困难。

示例2:自定义类中的钩子 (Example 2: Hook Inside a Custom Class)

With WooCommerce they have a dedicated team of great developers plus a series of volunteers or contributors continually working to improve their plugin. They’ve gone through years of development so they know the importance of proving the right hooks so developers can customize things.

借助WooCommerce,他们拥有一支由出色的开发人员组成的敬业团队,以及一系列致力于改善其插件的志愿者或贡献者。 他们已经经历了多年的开发,因此他们知道证明正确钩子的重要性,以便开发人员可以自定义内容。

In this example, we’re going to look at just a simple situation. The idea behind this example is that you can’t be guaranteed you will have hooks to rely on and if the developer is even thinking about people extending their work. In this scenario, we’re working between a parent and child theme. Inside the parent theme we have our main class and in our child theme we have our additional function.

在这个例子中,我们将只看一个简单的情况。 该示例背后的思想是,不能保证您会依赖于钩子,并且即使开发人员甚至在考虑人员扩展他们的工作。 在这种情况下,我们正在父级和子级主题之间进行工作。 在父主题中,我们有主类,在子主题中,我们有附加的功能。

NOTE: It’s useful to point out that remove_filter is the same as remove_action. At the end of the day, they are all a way to removed hooked function and WordPress is happy for you to use them interchangeably.

注意:指出remove_filterremove_action相同是很有用的。 归根结底,它们都是删除钩子函数的方法,而WordPress很高兴您可以互换使用它们。

//A simple test class, loaded directly in your website
//Loaded from the parent theme
class testClass{

    //magic constructor
    public function __construct(){
        add_filter('the_title', array($this, 'wrapTitle'), 10, 1);
        add_filter('add_extra_word', array($this, 'output_word'), 10, 1);  
    }

    //wrap the title for each post 
    public function wrapTitle($title){
        $html = '';
        $html .= '<div class="titleWrap">';
        $html .= $title;

        //append a word to the end of the title
        $html = apply_filters('add_extra_word', $title);

        $html .= '</div>';

        return $html;
    }

    //append the word 'Hello World' to the end of the title
    public function output_word($title){
        $html = '';

        $html = $title . ' <strong>Hello World</strong>';
        return $html;
    }
}
$testclass = new testClass();

This class adds a function called wrapTitle onto the the_title hook right in the _construct method. This means that as soon as the class is loaded it will hook that function onto the title and be called every time we’re displaying a post. Inside of the wrapTitle function it wraps the current title around a div and then calls the add_extra_word filter.

此类在_construct方法中的the_title钩子上添加了一个称为wrapTitle的函数。 这意味着,一旦加载了类,它将立即将该函数挂接到标题上,并在每次显示帖子时被调用。 在wrapTitle函数内部,它将当前标题包装在div周围,然后调用add_extra_word过滤器。

Back in the constructor we hooked another function called output_word onto the add_extra_word filter. This functions purpose is to add the bolded Hello World text to the end of the title.

回到构造函数中,我们将另一个名为output_word函数output_wordadd_extra_word过滤器上。 此功能的目的是将加粗的Hello World文本添加到标题的末尾。

hook example two before

As you can see this isn’t very attractive. We want to remove this added word from the end of the title. This is the perfect opportunity to remove the function added in the class. Here’s how we do it:

如您所见,这不是很吸引人。 我们要从标题的末尾删除此添加的单词。 这是删除类中添加的函数的绝佳机会。 这是我们的方法:

//removes the extra word appended to the title (added by the class)
//Added to your child theme 
function remove_extra_word(){
    global $testclass;
    remove_filter('add_extra_word', array($testclass, 'output_word'), 10);
}
add_action('init', 'remove_extra_word');

We first hook our function to be loaded on init. The reason we do this instead of just executing the remove_filter right in the PHP file is because we want it to trigger only once WordPress has started loading. If we declared this function before the class was even loaded it would do nothing (as the class needs to exist first).

我们首先钩住要在init上加载的函数。 我们之所以这样做,而不是仅仅在PHP文件中直接执行remove_filter ,是因为我们希望它仅在WordPress开始加载后才触发。 如果我们在类加载之前就声明了此函数,它将什么都不做(因为该类首先需要存在)。

We grab a copy of the class by using global $testclass. We do this because this class didn’t have any way of giving us our object directly.

我们通过使用global $testclass来获取该类的副本。 我们这样做是因为该类没有任何直接给我们对象的方法。

Inside the function we now use the remove_filter function and remove the output_word function attached to the add_extra_word action defined in our class.

在函数内部,我们现在使用remove_filter函数,并删除附加到我们类中定义的add_extra_word操作的output_word函数。

When this is all done and dusted the Hello World text will be removed and your titles will be back to normal.

完成所有操作后,将清除Hello World文本,并且标题将恢复正常。

hook example two after

We managed to do all that just by adding our own custom function and removing our hooked actions.

我们仅通过添加自己的自定义函数并删除了钩子动作就可以做到所有这些。

这项技术行不通的地方 (Where This Technique Won’t Work)

If there is no way for you to find the object of the class at all (either passed in as a variable in a hook or via some other method) then this technique will fail. A core part of Object Orientated Design principals says that there should always be a reference to the object so that it can be accessed, or failing that an easy way to load the object.

如果没有办法让你找到所有的类(在任一通过在钩或通过其他方法的变量)的对象,然后这种技术将失败。 面向对象设计原则的核心部分说,应该始终对对象进行引用,以便可以对其进行访问,否则将无法通过一种简单的方式来加载对象。

If this happens you can try the following steps (each more drastic and less recommended as we go down):

如果发生这种情况,您可以尝试执行以下步骤(在进行下一步操作时,每个步骤都比较激烈,建议不要这样做):

  • Contact the theme or plugin developer and ask for additional hooks.

    联系主题或插件开发人员,并要求其他挂钩。

    • Most developers are pretty keen to help people out so it’s a good place to start. When they update their plugin or theme you should be able to seamlessly update (if it’s been set up correctly).

      大多数开发人员都非常热衷于帮助人们,因此这是一个不错的起点。 当他们更新其插件或主题时,您应该能够无缝更新(如果设置正确)。
  • Change your plugin or your theme.

    更改您的插件或主题。

    • If it’s not working for you, see if there is anything else out there that might provide better functionality and be more developer friendly.

      如果对您不起作用,请查看是否有其他任何东西可以提供更好的功能并且对开发人员更友好。
  • Manually edit your plugin or theme directly.

    直接手动编辑您的插件或主题。

    • If you must stick with your plugin or theme and you desperately need to change the way it works, then you can always edit the files directly. Generally speaking this is an awful suggestion as any changes you make will be lost if you ever update your theme or plugin. However, sometimes you just need to get a problem solved.

      如果您必须坚持使用插件或主题,并且迫切需要更改其工作方式,那么您始终可以直接编辑文件。 一般来说,这是一个可怕的建议,因为如果您更新主题或插件,所做的任何更改都会丢失。 但是,有时您只需要解决问题即可。

包装全部 (Wrapping It All Up)

Hopefully after all this you should have a strong grasp on how to use WordPress’s hook system to remove and adjust functionality inside your themes and plugins. If you’re patient enough and can track down the hook, function and the class object you can remove and replace functionality as you see fit.

希望所有这些之后,您应该对如何使用WordPress的挂钩系统删除和调整主题和插件中的功能有深刻的了解。 如果您有足够的耐心并且可以追踪问题,功能和类对象,则可以根据需要删除和替换功能。

You might want to examine some of your currently installed plugins to see how developer friendly they are. Do they supply a wide range of hooks and filters? Are any of their values or settings explicitly hard coded in their theme or plugin? This information is important if you want to be able to extend and customize your website as you see fit.

您可能需要检查一些当前安装的插件,以了解它们对开发人员的友好程度。 他们是否提供各种钩子和过滤器? 它们的任何值或设置是否在其主题或插件中明确地硬编码? 如果您希望能够扩展和自定义网站,则此信息很重要。

For some further reading on the WordPress hook system check out Demystifying the WordPress Hook System by Agbonghama Collins.

有关WordPress挂钩系统的更多信息,请查看Agbonghama Collins撰写的《 解密WordPress挂钩系统神秘化》

翻译自: https://www.sitepoint.com/digging-deeper-wordpress-hooks-filters/

深入解析wordpress

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值