hook_load / hook_view未调用

时间:2010-08-29 05:35:51

标签: drupal drupal-modules drupal-hooks

我有一个声明了四种节点类型的模块。我的问题是,hook_load,hook_view永远不会被调用。我使用drupal_set_message来查明是否正在调用某个钩子。我发现了hook_load,hook_view不是。只是为了给你清楚的图片,这是我的hook_load结构

HERE'S UPDATED ONE

function mymodule_node_info(){
   return array(
      'nodetype1' => array(
         'name' => t('nodetype1'),
         'module' => 'mymodule_nodetype1',
         'description' => t('....'),
         'has_title' => TRUE,
         'title_label' => t('Title'),
         'has_body' => TRUE,
         'body_label' => t('Body'),
     ),
     'nodetype2' => array(
         ......
         'module' => 'mymodule_nodetype2',
         ......
     ),
     'nodetype3' => array(
         ......
         'module' => 'mymodule_nodetype3',
         ......
     ),
     'nodetype4' => array(
         ......
         'module' => 'mymodule_nodetype4',
         .......
     ),
 );

 }

function mymodule_nodetype1_load($node){    
   $result = db_query('SELECT * from {nodetype1table} WHERE vid = %d'
               $node->vid
           );   
   drupal_set_message("hook_load is provoked.","status");
   return db_fetch_object($result);
}

我不知道为什么不打电话。我在drupal模块编写书上编写了这段代码,并按照说明进行操作。我已经尝试过该书中的示例代码,它可以正常工作。只有我的代码不起作用。可能是因为一个模块中有多个节点类型。任何帮助都将受到高度赞赏。

2 个答案:

答案 0 :(得分:7)

您的代码不起作用,因为hook_load()hook_view()不是模块挂钩:它们是节点挂钩。调用基于内容类型名称,而不是模块名称。

因此,首先您需要使用hook_node_info()声明您的内容类型:

function mymodule_node_info() {
  $items = array();

  $items['nodetype1'] = array(
    'name' => t('Node Type 2'),
    'module' => 'mymodule_nodetype1',
    'description' => t("Nodetype 1 description"),
  );
  $items['nodetype2'] = array(
    'name' => t('Node Type 2'),
    'module' => 'mymodule_nodetype2',
    'description' => t("Nodetype 2 description"),
  );
  $items['nodetype3'] = array(
    'name' => t('Node Type 2'),
    'module' => 'mymodule_nodetype3',
    'description' => t("Nodetype 3 description"),
  );

  return $items;
}

然后,您需要使用为hook_node_info()中声明的每个内容类型指定的模块名称作为节点挂钩。即mymodule_nodetype1_load()mymodule_nodetype2_view()


修改

如果您在查看或加载节点时尝试触发基于非节点的模块,则需要使用hook_nodeapi()

function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch ($op) {
    case 'view':
      mymodule_view_function($node);
      break;
    case 'load':
      mymodule_load_function($node);
      break;
  }
}

mymodule_load_function()mymodule_load_function()替换为您自己的自定义函数,这些函数旨在作用于$node对象。


编辑2

除了hook_load()实现中的语法错误之外,还有一段代码超出了您所提供的内容,阻止了正确的调用。以下代码有效(如果您创建了nodetype1节点,节点上会出现“mymodule_nodetype1_load invoked”消息):也许您可以比较整个代码以查看您缺少的内容。

function mymodule_node_info() {
  return array(
    'mymodule_nodetype1' => array(
      'name' => t('nodetype1'),
      'module' => 'mymodule_nodetype1',
      'description' => t('....'),
      'has_title' => TRUE,
      'title_label' => t('Title'),
      'has_body' => TRUE,
      'body_label' => t('Body'),
    ),
    'mymodule_nodetype2' => array(
      'name' => t('nodetype2'),
      'module' => 'mymodule_nodetype2',
      'description' => t('....'),
      'has_title' => TRUE,
      'title_label' => t('Title'),
      'has_body' => TRUE,
      'body_label' => t('Body'),
    ),
  );
}

function mymodule_nodetype1_form(&$node, $form_state) {
  // nodetype1 form elements go here

  return $form;
}

function mymodule_nodetype2_form(&$node, $form_state) {
  // nodetype2 form elements go here

  return $form;
}

function mymodule_nodetype1_load($node) {
  $additions = new stdClass();

  drupal_set_message('mymodule_nodetype1_load invoked');

  return $additions;
}

function mymodule_nodetype2_load($node) {
  $additions = new stdClass();

  drupal_set_message('mymodule_nodetype2_load invoked');

  return $additions;
}

如果您在更改模块后没有重置环境,则可能会遇到缓存问题。您应该在沙盒环境中测试您的代码,该环境可以重置为干净的Drupal安装,以确保您不会关注以前不正确的节点实现中的旧版本。

此外,如果您尝试对未由模块定义的内容类型执行操作,则应该只使用hook_nodeapi()。您的内容类型应使用节点挂钩(hook_load()hook_view()等。)。

最后,可能是你使用了错误的钩子,因为你期望它们在不适合的地方射击。如果您已完成上述所有操作,请使用您期望实现的功能以及您希望触发的位置更新您的帖子。

答案 1 :(得分:0)

我发现了为什么你的代码不起作用的罪魁祸首。这是因为我使用的是旧代码创建的测试数据。在我的旧代码中,由于hook_node_info中的节点声明使用相同的模块值,我只能创建一个hook_form实现并使用“switch”语句返回适当的形式。只是为了让你清楚地了解我的旧代码 -

function mymodule_node_info(){
   return array(
      'nodetype1' => array(
         .....
         'module' => 'mymodule',
         .....
     ),
     'nodetype2' => array(
         ......
         'module' => 'mymodule',
         ......
     ),
         .......

    );

 }
function mymodule_form(&$node, $form_state){
switch($node->type){
    case 'nodetype1':
        return nodetype1_form();
    break;      

    case 'nodetype2':
        return nodetype2_form();
    break;
    .....

}
}

在我提供了您提供的更改后创建新数据时,会调用hook_load。有用!我已经多次测试(使用以前的代码创建的旧数据进行测试,并使用在这些更改后创建的新数据进行测试)来确保这是否是根本原因,并且我得到了相同的结果。我认为drupal存储form_id或模块入口值节点声明和数据以及确定hook_load调用。这可能就是为什么它不认为它是这个节点的数据,因此不调用hook_load的原因。

非常感谢你的帮助。