如何编写drupal模块
-
- 如何编写一个模块
- 写hook_menu时可以参照node模块,写form时,可以参照book模块。
- 编写模块时,各文件和各相关函数的编写顺序(我的经验):
- 先编写moduleName.info,提供给Drupal系统该模块的信息。
- 然后编写moduleName.install,实现模块安装和卸载时候的一些(数据库)操作。
- 最后编写moduleName.module,并在该文件中按如下顺序编写hook函数:
- hook_node_info()提供node信息
- hook_perm()定义权限
- hook_access()控制node级的权限
- hook_menu()实现菜单/地址mapping
- hook_menu()用到的回调函数
- hook_form()编写node的表单函数
- hook_validate()编写node的验证表单函数
- hook_insert()编写创建新node时对应的函数,用于向数据库中存储额外的值
- hook_update()编写update node时对应的函数,用于向数据库中更新值
- hook_view()编写产看node时对应的函数。
- 由于不是每个模块都创建了一个新的内容类型,所以如果不创建新的内容类型的模块,可能不必安装上面提到的顺序编写代码
- 编码指南(整体代码可以参加示例源代码,这里只提供总结性的代码)
- 数据库操作函数
- db_query(); 执行SQL语句,其中SQL语句中的参数用占位符表示(We use the %d placeholder for numbers and '%s' for strings.),并由db_query()的第二个及后续参数传入。例:db_query('SELECT COUNT(*) usernum FROM {goal} WHERE nid = %d ', $node->nid)
- db_query_range(); 执行SQL语句,并取结果的一部分。例:$query ="SELECT g.nid, COUNT(g.uid) FROM {goal} g GROUP BY g.nid ORDER BY COUNT(g.uid) DESC"; $queryResult = db_query_range($query, 0, 1);
- db_fetch_object(); 从de_query()和db_query_range()返回的结果中获取结果对象。例:function goal_all() { $queryResult = db_query( "SELECT n.nid FROM {node} n " . "WHERE n.type='goal' ORDER BY n.sticky DESC, n.created DESC" ); $page_content = array(); $page_content[] = "<h2 class='category'>All the goals</h2>"; while ($goal = db_fetch_object($queryResult)) { $goal = node_load($goal->nid); $goal->url = url('$goal/' . $goal->nid); $page_content[] = theme('goal_compact', $goal); } return implode('', $page_content);}
- db_result(); 获得结果集的第一行例:// Get previously saved note, if any.$result = db_query("SELECT note FROM {annotations} WHERE uid = %d AND nid = %d",$user->uid, $node->nid);$node->annotation = db_result($result);
- 的风格
- 字符串操作函数
- t(); 封装字符串,支持占位符的使用。例:'title' => t('Stock quote at @time', array('@time' => $timestamp)),
- 如何在页面提示状态信息
- drupal_set_message(t('Some Infomation'));
- drupal_set_message(t('The installation of the sharenote module unsuccessful.'),'error');
- form_set_error('errform', t('You can not delete it! There are still people who are working on this goal!')); // 表单错误信息的显示
- drupal_set_title(); 在运行期间设置浏览器标题
- 引进全局变量的方法:
- 获取系统信息的方法
- $adddate = time();//获取系统时间
- 表单相关
- 用自己定义的函数定义Form的方法/*** Implementation of hook_menu().*/function annotate_menu($may_cache) { $items = array(); if ($may_cache) { $items[] = array( 'path' => 'admin/settings/annotate', 'title' => t('Annotation settings'), 'description' => t('Change how annotations behave.'), 'callback' => 'drupal_get_form', 'callback arguments' => array('annotate_admin_settings'), 'access' => user_access('administer site configuration') ); } return $items;}/*** Define the settings form.*/function annotate_admin_settings() { $form['annotate_nodetypes'] = array( '#type' => 'checkboxes', '#title' => t('Users may annotate these node types'), '#options' => node_get_types('names'), '#default_value' => variable_get('annotate_nodetypes', array('story')), '#description' => t('A text field will be available on these node types to make user-specific notes.'), ); $form['annotate_deletion'] = array( '#type' => 'radios', '#title' => t('Annotations will be deleted'), '#description' => t('Select a method for deleting annotations.'), '#options' => array( t('Never'), t('Randomly'), t('After 30 days') ), '#default_value' => variable_get('annotate_deletion', 0) // default to Never ); $form['annotate_limit_per_node'] = array( '#type' => 'textfield', '#title' => t('Annotations per node'), '#des ...