>头
Tahir是一个专注于WordPress和AI的全栈web开发人员. 他曾在几个WordPress聚会和wordcamp上担任演讲嘉宾.
以前在
像任何CMS一样, WordPress 不会总是一开始就满足你的所有需求. 因为它是开源的, 您可以修改它,使其符合您的业务需求,但相反, 你可以使用WordPress的钩子来实现你的目标. 用钩子建造房屋是一种成功的策略,它能让人解脱 WordPress的开发者 构建几乎任何可以想象的网站功能.
WordPress 钩子 不只是强大的定制工具吗, 它们是WordPress组件彼此交互的方式. 钩接函数管理许多我们认为是WordPress的一部分的日常任务, 例如向页面添加样式或脚本, 或者用HTML元素包围页脚文本. 搜索一下WordPress Core的代码库就会发现 成千上万的钩子 在700多个地点. WordPress主题和插件包含更多的钩子.
在我们进入钩子并探索动作钩子和过滤器钩子之间的区别之前, 让我们来了解一下它们在WordPress架构中的位置.
WordPress的模块化元素很容易相互集成, 所以我们可以很容易地混合, 匹配, 并结合:
既然我们可以访问所有五个层的源代码,为什么WordPress还需要钩子呢?
为了跟上不断发展的技术, WordPress核心贡献者, 父主题, 并且插件经常发布更新以减轻安全漏洞, 修正错误, 解决不兼容, 或者提供新功能. 任何有急救经验的顾问都知道, 未能使WordPress组件保持最新 可以妥协,甚至 禁用站点.
如果我们直接修改上游WordPress组件的本地副本, 我们遇到了一个问题:更新覆盖了我们的自定义. 我们如何在定制WordPress时规避这个问题? 通过钩子,在子主题和自定义插件.
A 儿童主题 是一个安全的空间,我们可以自定义我们安装的主题的外观和感觉. 此处添加的任何代码都将覆盖父类中的可比代码,而不会有被更新覆盖的风险.
子主题被激活时, 它链接到一个未激活的父节点, 继承和展示父代的特征,同时不受父代更新的影响. 为了不受诱惑而修改主题, 最佳实践建议激活子主题作为我们设置的一部分.
当一个插件被激活时 功能.php
文件在服务器上的每次调用时执行. WordPress, 反过来, 根据所有活动插件的优先级加载和排序钩子,并依次执行. 要扩展第三方插件的功能,我们可以 编写我们自己的WordPress自定义插件.
目标 | 例子 | 在哪里? | |
---|---|---|---|
子主题PHP | 自定义插件PHP | ||
修改网页的结构 | 添加自定义样式表来更改网站元素的颜色和字体 | ✔ | |
修改另一个插件的功能.e.,创建一个插件来增强第三方插件的功能) | 添加副标题(例如.g.(“新闻”)来自定义帖子类型 | ✔ | |
添加一个超越WordPress核心的新功能 | 修改访问邮件时发生的工作流,以包括更新数据库中的计数器 | ✔ |
为了避免混淆术语,我们将坚持使用以下术语:
记住这些区别,我们就可以开始探索钩子了.
当动作或过滤器被合并到钩子中时, 根据需要, 我们实现了每个任务只编写一个函数的目标,并避免了项目中代码的重复. 例如, 假设我们想要将相同的样式表添加到三个页面模板(归档, 单页, 和自定义帖子)在我们的主题. 而不是重写父模板中的每个模板, 然后在我们的子主题中重新创建每个, 然后将样式表添加到各个头部部分, 我们可以在单个函数中编写代码,并将其附加到 wp_head
钩.
通过唯一地命名子主题或自定义插件钩子来主动避免冲突. 在单个站点中使用同名钩子会导致意外的代码行为. 最佳实践规定,在钩子名的开头使用唯一的短前缀(例如.g.(作者、项目或公司的首字母缩写),后面跟着一个描述性的钩子名称. 例如, 使用“项目首字母加钩子名称”模式,项目Tahir 's Fabulous 插件, 我们可以给钩子起名字 tfp-upload-document
or tfp-create-post-news
.
一个钩子可以触发不止一个动作或过滤器. 例如,我们可以编写一个包含多个脚本的网页,所有这些脚本都使用 wp_head
行动钩子打印HTML(例如.g., a or
节)在
页面前端的部分.
因此,几 插件开发人员 能否在一个插件上并行推进多个目标, 或者将插件分成多个, 更简单的独立插件. 如果某个特性不能正常工作, 我们可以直接调查和调试它的钩子函数,而不必搜索整个项目.
当事件在WordPress中发生时,操作将运行代码. 动作可以执行如下操作:
可以触发动作的事件示例包括:
初始化
,在WordPress加载之后,但在它向输出流发送报头之前.save_post
,表示帖子已被保存.wp_create_nav_menu
,在成功创建导航菜单之后.操作可以与API交互以传输数据.g.(链接到社交媒体上的帖子),但它不会向调用钩子返回数据.
假设我们想通过社交媒体自动分享我们网站上的所有新帖子. 首先,在WordPress文档中查找一个可以在帖子发布时触发的钩子.
找到我们的钓钩没有捷径:我们将通过经验或仔细研究来学习 列出的操作 寻找可能的候选人. 我们可以考虑 save_post
一个候选人, 但很快排除这种可能性,因为它会在一次编辑过程中触发多次. 更好的选择是 transition_post_status
,仅在帖子状态发生更改时触发.g.,从 草案
to 发布
,从 发布
to 垃圾
).
我们会选择 transition_post_status
而且还将改进我们的动作,使其只在我们的post状态过渡到时运行 发布
. 进一步, 通过遵循各种社交媒体平台的官方文档和api, 我们可以整合和发布我们的帖子的内容, 随附特色图像:
现在我们知道了如何使用动作挂钩, 有一个特别有用, 尤其是在CSS方面.
wp_enqueue_scripts
假设我们想最后添加子主题的样式表, 在所有其他加载完毕之后, 以确保在其他地方产生的任何同名类都被子主题的类覆盖.
WordPress以默认顺序加载样式表:
在这个结构中:
Add_行动 (string $钩_name, callable $回调, int $优先级 = 10, int $accepted_args = 1)
… 优先级
的价值 添加操作 确定其执行顺序:
优先级
值 wp_enqueue_scripts
(或任何行动)是“10”.”优先级
到一个更低的数字.优先级
到一个更高的数字.最后加载子主题的样式表,使用 wp_enqueue_scripts
,这是WordPress主题和插件常用的操作. 我们只需要改变子主题动作的优先级 wp_enqueue_scripts
对于高于默认值“10”的数字,例如“99”:
Add_行动 ('wp_enqueue_scripts', 'child_主题_styles', 99);
通常,在不查找返回值时使用操作. 为了向调用钩子返回数据,我们需要查看过滤器.
过滤器允许我们在处理数据以便在浏览器中显示之前对其进行修改. 为此目的, 过滤器接受一个或多个变量, 修改传递的值, 并返回用于进一步处理的数据.
在为浏览器准备内容之前,WordPress会检查并执行所有注册的过滤器. 这样,我们就可以在将数据发送到浏览器或数据库之前对其进行操作.
我的一个客户通过在他销售的产品上印上客户提供的图像来个性化产品. 这个客户端使用WooCommerce插件来管理电子商务. WooCommerce不支持这种开箱即用的功能. 因此,我在客户端代码中添加了两段代码 功能.php
:
woocommerce_checkout_cart_item_quantity
,列于 WooCommerce文档是一个过滤器挂钩,允许客户在结账之前向购物车添加外部元素.my_customer_image_data_in_cart
是我们自己编写并用于触发的过滤器吗 woocommerce_checkout_cart_item_quantity
每当WooCommerce准备展示购物车时.使用下面的模板,我们可以添加我们的过滤器和修改购物车的默认行为:
Add_过滤器 ('woocommerce_checkout_cart_item_quantity', 'my_customer_image_data_in_cart', 1,3);
函数my_customer_image_data_in_cart($html, $cart_item, $cart_item_key) {
if ( !空($cart_item['images_data'])) {
//存储图像
//获取图片URL
//修改$html
}
返回html美元;
}
We 添加过滤器 与添加动作的方式相同. 过滤器的工作方式类似于操作,包括处理优先级的方式. 过滤器和操作之间的主要区别在于,操作不会向调用钩子返回数据,而过滤器会.
编写自定义动作钩子并没有扩展Wordpress Core,而只是在我们自己的代码中创建新的触发点.
在我们的主题或插件中添加自定义钩子允许其他开发人员在不修改我们的代码库的情况下扩展功能. 添加自定义钩子, 使用WordPress Core代码库本身使用的相同技术:在我们期望的触发点, 我们只需调用 do_行动
上面写着我们新钩子的名字, 可选地添加尽可能多的参数,因为我们的回调函数可能会发现有用:
Do_行动 ('myorg_hello_行动', $arg1, $arg2);
这段代码只是简单地运行任何挂接到自定义钩子上的回调函数. 请注意,名称空间是全局的, 如前所述, 这将是一个好主意,以我们的组织(可能是我们的项目)的名称的缩写形式开始我们的自定义钩子名称, ), 因此, myorg_
在这里.
现在我们已经定义了 myorg_hello_行动
, 开发人员可以使用与我们前面介绍的内置钩子完全相同的方法来挂钩:定义一个函数, 然后调用 add_行动 ()
.
除非我们只想在内部使用一个新的钩子,否则这是构建代码的一种有用的方法, 毕竟,我们必须向下游传达它的可用性, 致我们团队的其他成员或我们插件的外部用户, 通过清晰的文档.
WordPress的自定义过滤器钩子的模式与动作钩子的模式相同,除了我们调用 apply_过滤器 ()
而不是 do_行动 ()
.
这次让我们来看一个更具体的例子. 假设我们的插件创建了一个侧边栏菜单,它通常由四个项目组成. 我们将添加一个自定义过滤器钩子,以便我们(和下游开发人员)可以在其他地方修改该列表:
//侧边栏菜单的文本标签
$sidebar_menu = array("Page One", "Page Two", "Page Three", "Page Four");
$sidebar_menu = apply_Filterss('myorg_sidebar_menu', $sidebar_menu);
这就是我们的自定义过滤器钩子 myorg_sidebar_menu
现在已经准备好在一个插件中使用,这个插件可能会在以后或在这个插件的其他地方加载. 这允许任何编写下游代码的人定制我们的侧栏.
我们或其他开发人员在使用内置的WordPress钩子时也会遵循相同的模式. 换句话说, 我们将从定义一些回调函数开始,它们返回传递给它们的数据的修改版本:
函数lowercase_sidebar_menu($menu) {
$menu = array_map('strtolower', $menu);
返回$菜单;
}
add_donate_item($menu) {
$menu = array_push($menu, '捐赠');
返回$菜单;
}
和我们前面的例子一样, 现在,我们准备将过滤器回调函数与自定义钩子挂钩:
Add_过滤器 ('myorg_sidebar_menu', 'add_donate_item', 100);
Add_过滤器 ('myorg_sidebar_menu', 'lowercase_sidebar_menu');
这样,我们就将两个示例回调函数连接到自定义过滤器钩子上了. 现在两者都修改了原来的内容 the_sidebar_menu美元
. 因为我们给出了更高的值 优先级
价值 add_donate_item
,它稍后运行 lowercase_sidebar_menu
执行.
下游开发人员总是可以自由地将更多回调函数挂钩到 myorg_sidebar_menu
. 当他们这样做的时候,他们可以使用 优先级
参数使它们的钩子在我们的两个示例回调函数之前、之后或之间运行.
有了动作、过滤器和钩子,WordPress的功能可以突飞猛进. 我们可以为我们的网站开发自定义功能, 让我们自己的贡献像WordPress一样可扩展. Hooks让我们在将WordPress网站提升到一个新的水平时坚持安全和最佳实践.
Toptal 工程博客向 法赫德穆尔塔扎 对于他的专业知识、beta测试和本文的技术审查.
钩子是WordPress Core中的一个点, 一个主题, 或者一个插件,开发人员可以在其中注册要运行的自定义函数. WordPress包含许多预定义的钩子. 使用动作或过滤器,您可以连接到其中一个或创建自己的钩子.
动作是一个附加到钩子上的函数,扩展了WordPress的功能. 当事件在WordPress中发生时,操作就会运行. 不像过滤器, 操作可以执行数据库操作, 比如创建, 阅读, 更新, 或者删除数据. 动作的回调函数不会向调用动作的钩子返回任何东西.
过滤器是一个附加到钩子上的函数,扩展了WordPress的功能. 当事件在WordPress中发生时,过滤器会运行. 过滤器允许我们在处理数据以便在浏览器中显示之前修改数据. 过滤器接受变量,修改传递的值,并返回数据以供进一步处理.
伊斯兰堡,伊斯兰堡首都地区,巴基斯坦
2020年9月4日成为会员
Tahir是一个专注于WordPress和AI的全栈web开发人员. 他曾在几个WordPress聚会和wordcamp上担任演讲嘉宾.
以前在
世界级的文章,每周发一次.
世界级的文章,每周发一次.