我有一个声明了四种节点类型的模块。我的问题是,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模块编写书上编写了这段代码,并按照说明进行操作。我已经尝试过该书中的示例代码,它可以正常工作。只有我的代码不起作用。可能是因为一个模块中有多个节点类型。任何帮助都将受到高度赞赏。
答案 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
对象。
除了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的原因。
非常感谢你的帮助。