【问题标题】:What Ties a Drupal Hook to a Particular Module?什么将 Drupal Hook 与特定模块联系起来?
【发布时间】:2011-06-27 08:32:11
【问题描述】:

Drupal Hook 与特定模块的联系是什么?

在 Drupal 7 中,每个核心模块都有一个“api”文件

$ ls modules/*/*.api.php
modules/aggregator/aggregator.api.php   modules/openid/openid.api.php
modules/block/block.api.php             modules/overlay/overlay.api.php
modules/comment/comment.api.php         modules/path/path.api.php
modules/contextual/contextual.api.php   modules/rdf/rdf.api.php
modules/dashboard/dashboard.api.php     modules/search/search.api.php
modules/field/field.api.php             modules/shortcut/shortcut.api.php
modules/field_ui/field_ui.api.php       modules/simpletest/simpletest.api.php
modules/file/file.api.php               modules/system/system.api.php
modules/filter/filter.api.php           modules/system/theme.api.php
modules/help/help.api.php               modules/taxonomy/taxonomy.api.php
modules/image/image.api.php             modules/trigger/trigger.api.php
modules/locale/locale.api.php           modules/update/update.api.php
modules/menu/menu.api.php               modules/user/user.api.php
modules/node/node.api.php

这些文件中的每一个都包含一个从未(?)调用的函数,但记录了其他模块(包括第 3 方)可以实现的钩子的存在。

File: modules/path/path.api.php
function hook_path_delete($path) {
  db_delete('mytable')
    ->condition('pid', $path['pid'])
    ->execute();
}

我的问题:是什么将特定的钩子与特定的模块联系在一起?为什么path_delete 挂钩包含在path.api.php 文件中?为什么entity_view 挂钩包含在system.api.php 文件中?在事实组织之后,这只是任意的,还是 Drupal 系统中的某些东西将特定的钩子与特定的模块联系起来?还是别的什么?

【问题讨论】:

    标签: php drupal drupal-modules drupal-hooks


    【解决方案1】:

    使用module_invoke()module_invoke_all() 调用钩子:如果您查看这两个函数的代码,您可能能够拼凑出它的工作原理,但基本上,如果我将它添加到我的模块代码中:

    // Other code
    
    $foo = module_invoke_all('foo_bar', $var1, $var2);
    
    // More code
    

    Drupal 将调用它在启用的模块中找到的每个hook_foo_bar($var1, $var2) 实现。基于此,您应该看到,将特定钩子与特定模块联系起来的唯一东西是命名约定:如果我将模块称为 foo,我的钩子函数应该以 hook_foo_ 开头。

    您对 *.api.php 被调用的说法是正确的:由于模块调用只是一个函数调用,因此模块作者包含 foo.api.php 仅用于文档目的,以告知实现者如何实现挂钩。

    例如,在上述情况下,foo.api.php 将包含一个示例函数,例如:

    /**
     * Doxygen comments documenting the function goes here
     */
    function hook_foo_bar($var1, $var2) {
      return $var1 + $var2;
    }
    

    但作为一个模块实现者,我可以用不同的方式实现hook_foo_bar()

    function mymodule_foo_bar($var1, $var2) {
      return $var1 - $var2;
    }
    

    module_invoke_all() 被调用时,Drupal 将使用实现模块的短名称 (mymodule) 和传递给 module_invoke_all() (foo_bar) 的钩子名称创建一个函数,从而调用函数 mymodule_foo_bar() I刚刚定义。

    核心中的system 模块有点包罗万象:Drupal 8 的一项任务是kill it off 并将其功能委托给其他模块。

    【讨论】:

    • 谢谢,正是我想要的。我了解基本的钩子概念,但想确认模块和钩子之间没有正式的联系,那只是约定。
    【解决方案2】:


    也许你可以尝试学习挂钩drupal?很简单:
    http://api.drupal.org/api/drupal/includes--module.inc/group/hooks/7

    关于 hook_path_delete:
    查看 path.module,您会在某处看到 path_delete(...) 调用。
    例如,在 path_node_update() - 这个函数调用然后你改变当前路径 - 它之前删除旧路径,而不是为节点创建新路径。
    现在查看定义 path_delete() 函数的位置 - 它位于 path.inc 文件中:
    在这个函数中你会看到: module_invoke_all('path_delete', $path); - 这个函数有什么作用?
    它列出了定义 hook_path_delete 的所有模块(在 drupal 7 中它被缓存)(如我之前所示,对于 yiu 自定义模块,它定义为 YOURMODULENAME_path_delete,它也将包括在这里),并一一运行所有这些函数(运行顺序由模块的权重和文件名定义)。
    那么现在您可以在自定义模块中做什么?您可以对此删除反应做出响应并执行一些其他操作 - 例如,删除可用于复制该节点的路径的其他路径(这只是示例)。

    附言 启动自定义模块的好点:http://drupal.org/contributors-guide

    【讨论】:

    • hook_entity_view 在评论、节点、分类和用户模块中调用(可能更多在 contrib.modules 上)。这是“低级”钩子,您可以在那里跟踪“$entities”发生的事情。
    • 我知道如何使用钩子,但我对特定钩子的具体内容不感兴趣;我试图完整地和孤立地理解模块系统,以便我可以理解 Drupal 的其余部分。您的 cmets 很有用,但没有回答我的核心问题:什么将钩子与特定模块联系起来?约定,或正式的东西。
    • 嗯,从答案中可以看出:modulename_hookname - 此层模块名称与 hookname。
    • module_hook_name 是您实现模块的方式。然而,durpal 在模块 api 文件中记录了它的钩子,这意味着每个模块都在“提供”一个钩子供其他模块实现。我在问这种关系是正式的,还是只是通过文档和用法隐含的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 2019-09-02
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多