3

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

这里更新了一个

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模块编写书编写了这段代码并按照说明进行操作。我已经尝试过那本书的示例代码,它工作正常。只有我的代码不起作用。可能是因为一个模块中有多种节点类型。任何帮助将不胜感激。

4

2 回答 2

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()等)。

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

于 2010-08-29T05:45:39.670 回答
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 的原因。

非常感谢您的帮助。

于 2010-08-30T13:43:17.640 回答