drupal:hook_menu 的基本应用

web 网站,几乎都是以路径为基础,废话,没路径用户咋访问呢?所以,hook_menu 的重要性不言而喻了。几乎每个模块,都会使用到这个钩子,纯 api 式的模块除外。

hook_menu 相对 form 来说,简单许多,没有那么多参数,但也不容小视。需要特别注意的就是权限验证,权限是一个站点的重中之重,稍有不慎,就有安全问题。

本篇教程,以说明 hook_menu 的常见使用方法为目的,不需要数据库,所有页面回调函数,返回的内容也是随意而写。

模块名称:mymenu。
实现功能:演示 hook_menu 的基本使用方法
权限设置:有

第一步:模块信息,创建 mymenu.info 文件

1// $Id$
2name = "自定义路径"
3description = hook_menu 实例模块
4core = "6.x"


第二步: 模块主文件 ,创建 mymenu.module 文件

模块重在演示,所有回调函数并没有太多内容,所以均写在模块主文件中。

提示:重点部分在于回调函数和传递参数,通配符的使用,以及 menu 类型的应用。

注意:hook_menu 之内的代码,有任何更改,请清除缓存。

001<?php
;$Id$
name = Create Course
description = "create course module"
core = 7.x
dependencies[] = entity
package =  Create Course
009  /**
010   * 一个完整的路径包含以下参数:
011   * 页面标题(<title></title>)部分:
012   * title:页面标题,可选,
013   * title callback:页面标题回调函数,可选
014   * title arguments:传递给标题回调函数的参数,可选
015   * 例如:
016   *  array(
017   *    'title' => '页面标题测试', // 不需要使用 t() 函数,menu 将缓存,显示时,自动调用 t()
018   *  );
019   * 
020   * 访问该页面时,不出意外的话,<title></title> 部分将显示“页面标题测试”
021   * 意外是什么?我们可以在页面回调函数中使用  drupal_set_title() 重新指定页面标题
022   * 
023   * 或者:
024   *  array(
025   *    'title callback' => 'mymenu_menu_title', // 回调函数
026   *    'title arguments' => array('test'), // 传递的参数
027   *  );
028   * 
029   * 访问该页面时,将以回调函数的返回值做为 title,即: mymenu_menu_title($var)
030   *
031   * 页面  content 区域:
032   * page callback:页面回调函数,若没有,则调用父级,一直往上
033   * page arguments:传递给页面回调函数的参数,可选
034   *
035   * 例如:
036   *  array(
037   *    'page callback' => 'mymenu_test',
038   *    'page arguments' => array('test', 'abcd')
039   *  );
040   * 
041   * 访问该页面时,将以回调函数的返回值做为页面主体内容,即 page.tpl.php 中的 $content 变量。
042   * 以上例子中的回调函数这样定义即可: mymenu_test($var1, $var2)
043   *
044   * 页面权限判断:
045   * access callback:权限回调函数,若不指定,则默认使用 user_access,这是 Drupal 权限系统的基础函数,可选
046   * access arguments:传递给权限回调函数的参数,可选
047   *
048   * 例如:
049   *  array(
050   *    'access arguments' => array('node view'),
051   *  );
052   * 
053   * 没有权限回调函数,默认使用 user_access,即:user_access('node view')
054   * 判断用户是否具有 node view权限,如有,则可以访问该页面。
055   * 
056   * 或者:
057   *  array(
058   *    'access callback' => 'mymenu_is_access',
059   *    'access arguments' => array('node view'),
060   *  );
061   * 
062   * 回调指定函数,即:mymenu_is_access($var),自定义判断,有权限访问则返回 true 即可
063   * 
064   * 包含指定文件:
065   * file:文件名称,相对于模块目录,或者指定目录。在 myform 教程中,我们讨论了这样做的好处。可选
066   * file path:指定待包含文件的路径
067   * 
068   * 在访问该页面时,将包含指定文件,所以页面回调函数可写在指定文件中。
069   *
070   * menu 类型:
071   * type:此参数将决定 menu 是否显示在导航中或tabs之上等等,Drupal 定义了几个常量
072   *  MENU_CALLBACK:只是注册一个地址,访问页面时,回调函数显示。不显示在其它任何地方。
073   *  MENU_NORMAL_ITEM:做为一个普通菜单,管理员可以在菜单中移动或隐藏等
074   *  MENU_SUGGESTED_ITEM:做为一个普通菜单,默认隐藏,管理员可启用
075   *  MENU_LOCAL_TASK:做为一个 tabs 选项
076   *  MENU_DEFAULT_LOCAL_TASK:做为  tabs 的默认页面
077   * 留空则默认为 MENU_NORMAL_ITEM
078   *
079   * 其它参数:
080   * description:路径描述,可选
081   * weight:路径权重,如果两个模块定义了相同的路径,以权重来决定使用谁的配置,可选。
082   * menu_name:设置为自定义菜单,该路径将不会出现在导航列表中
083   *
084   * 以上就几乎是一个 menu 的全部参数,几乎,也就是说还有几个参数,api 上没有列出来,实际开发中也很少用到
085   * 比如:load_functions、load_arguments、to_arg_functions,这几个都是和占位符、回调函数传递参数有关
086   *
087   * 回调函数传递的参数,实际上也是 hook_menu 的一大难点,理解了回调函数的参数传递,基本就算熟悉 hook_menu 了。
088   * 参数可以是字符串、对象、数组,但注意:
089   * 1、不能是变量。所有模块的 hook_menu 配置都会缓存, 所以,如果是变量,下一次从数据库中读取出来时,就会出现差异。
090   *    更严重的就是安全问题,假设使用变量做为参数:$user->uid,在清除缓存时当前用户是管理员,
091   *    在下一次访问该页面时,参数仍然是管理员 uid
092   * 2、不能用正整数(int),因为默认将正整数当成通配符处理,对应路径中的层级
093   *    比如:$item['test/abcd'],回调函数中传递参数:array(0, 1),实际上传递过去的就是  array('test', 'abcd')
094   *    关于 Drupal 中的路径层级处理,请参见 arg() 函数。
095   *   
096   *    这是较为常见的 hook_menu 定义方式,比如:$item['node/%node']
097   *
098   * 以下是一些实例
099   *
100   */
101   
102  // demo 1:使用 user_access() 来判断权限
103  $item['mymenu'] = array(
104    'description' => 'test1',
105    'page callback' => 'mymenu_test',
106    'access arguments' => array('mymenu add'), // 使用 user_access(),权限必须存在,用 hook_perm 定义一个权限
107    'type' => MENU_CALLBACK,
108  );
109   
110  // demo 2:使用自定义权限回调函数
111  $item['mymenu/access'] = array(
112    'description' => 'test1',
113    'page callback' => 'mymenu_test_access',
114    'access callback' => 'mymenu_is_test_access', // 自定义 回调函数
115    'type' => MENU_CALLBACK,
116  );
117   
118  // demo 3:定义为菜单
119  $item['mymenu/menu'] = array(
120    'description' => 'test1',
121    'page callback' => 'mymenu_test_access',
122    'access callback' => 'mymenu_is_test_access',
123    'type' => MENU_NORMAL_ITEM, // 菜单
124  );
125   
126  // demo 4:使用通配符
127  $item['mymenu/user/%user'] = array(
128    'description' => '我的管理中心',
129    'page callback' => 'mymenu_test_user',
130    'page arguments' => array(2), // 注意 mymenu_test_user 函数
131    'access callback' => 'mymenu_is_test_user', // 权限验证函数,假设只允许浏览自己的页面
132    'access arguments' => array(2), // 传递 $ac 给回调函数
133    'type' => MENU_NORMAL_ITEM, // 菜单
134  );
135   
136  return $item;
137}
138 
139/**
140 * @Implement of hook_perm()
141 * 自定义权限,启用后,在用户权限里,就可以自由分配,拥有该权限的用户,即可访问 mymenu
142 */
143function mymenu_perm() {
144  return array(
145    'mymenu add'
146  );
147}
148 
149/**
150 * 自定义回调函数
151 * 假设允许登录用户访问,实际上有现成的函数
152 */
153function mymenu_is_test_access() {
154  return $GLOBALS['user']->uid > 0;
155}
156 
157/**
158 * 验证函数
159 * @param (object) $ac
160 */
161function mymenu_is_test_user($ac) {
162  return $GLOBALS['user']->uid == $ac->uid;
163}
164 
165/**
166 * mymenu
167 */
168function mymenu_test() {
169  $output = '你拥有  mymenu add 权限';
170  return $output;
171}
172 
173/**
174 * mymenu/access
175 */
176function mymenu_test_access() {
177  $output = '你已登录';
178  return $output;
179}
180 
181/**
182 * 传递过来的参数是一个用户对象
183 * @param (object) $ac
184 */
185function mymenu_test_user($ac) {
186  $output = '欢迎你,'.$ac->name;
187  return $output;
188}


以上就是简单的 hook_menu 应用,一时之间难以理解的话,可以先试着定义较为简单的 menu,即只需要页面回调函数和权限验证函数的 menu,可以将上两个教程中的路径,加上权限控制,慢慢尝试各个参数的作用。下一篇教程将具体介绍 hook_menu 的读取顺序以及覆写方法。

最后,再次提醒,hook_menu 之内的代码,有任何更改,请清除缓存。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值