Drupal China
菜单(Menu)
前面曾经简单提到过Drupal的菜单, 今天稍微深入来探讨一下. 菜单能用来显示导航信息, 我们安装的系统, 默认安装有3个菜单, 让我们查看一下数据库吧, 以menu_开头的总共有三张表: menu_custom, menu_links, menu_router. 其中menu_custom表存放菜单定义信息, 但想知道他们都是由哪个模块定义的麽? 别忘记了菜单如果要显示就是区块哦, 打开区块表(blocks)看看吧. Here it is! 用户模块(User Module)定义了Navigation菜单(没看数据库我以为是系统模块(System Module)定义的呢), 菜单模块(Menu Module)定义了Primary links和Secondary links两个空菜单. 所以从表现层来看, 一个菜单就对应一个区块(Block), 它被放置在页面的某个区域(Region)来显示给用户进行导航.
其实Drupal的菜单机制不仅要能把导航显示给用户, 更重要的是在用户点击这些导航的时候, 能够准确快速定位到相应的业务逻辑. 有人会问, 难道这也是个问题吗? 要知道导航其实都对应他们具体的URI, 而传统的URI的定位是先按目录结构找处理文件, 然后根据Request参数对应业务逻辑,同时还要在业务逻辑中判断用户权限; 而Drupal有一套自己的内部路径, 它是基于模块化构建的, 与目录结构一点关系也没有了, 所以必须要有一套机制能在URI和业务逻辑间进行映射, 而Drupal的菜单机制就是完成这项工作的, 用户点击菜单项链接时, Drupal解析出内部路径, 并根据内部路径找到对应的业务逻辑, 并再完成判断权限后转交给业务逻辑进行处理, 这个过程Drupal称之为分发.
Drupal核心框架中的菜单api(includes/menu.inc文件)实现了上述功能, 它成功地解决了动态URL路径到具体执行函数间映射, 对用户屏蔽了系统预定义的Request参数的复杂处理, 在路径和功能建立了必由之路. 啥也别说了, 看看分发函数的实现:
<?php
>
function menu_execute_active_handler($path = NULL) {
if (_menu_site_is_offline()) {
return MENU_SITE_OFFLINE;
}
if (variable_get('menu_rebuild_needed', FALSE)) {
menu_rebuild();
}
if ($router_item = menu_get_item($path)) {
if ($router_item['access']) {
if ($router_item['file']) {
require_once($router_item['file']);
}
return <strong>call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);</strong>
}
else {
return MENU_ACCESS_DENIED;
}
}
return MENU_NOT_FOUND;
}
?>用户URL请求到达后, Drupal先进行Bootstrap初始化, 然后调用分发函数menu_execute_active_handler, 该函数根据解析出的内部路径, 在系统构建出的菜单路由表中查找, 如果找到则判断可访问权限, 然后调用路由表中对应路径注册的Pange_callback回调函数, 这样就完成一个URL请求到具体页面逻辑的过程. 流程非常简单清晰, 学过计算机原理, 熟悉中断调用的对这流程应该都非常熟悉.
菜单路由(Menu Router)
Drupal系统主要依据menu_router表构建系统菜单路由, 而menu_router表的内容则是基于各模块的hook_menu钩子来获得, 这个钩子较少被调用, 一般都在模块初始化或其他菜单需要重建的情况. 下面我们选一段Book模块的menu钩子代码来看看:
<?php
function book_menu() {
$items = array();
$items['admin/content/book/%node'] = array(
'title' => 'Re-order book pages and change titles',
'page callback' => 'drupal_get_form',
'page arguments' => array('book_admin_edit', 3),
'access callback' => '_book_outline_access',
'access arguments' => array(3),
'type' => MENU_CALLBACK,
'file' => 'book.admin.inc',
);
}
?>菜单项(Menu Item)
保存在menu _links表中, 定义了每个条目的名字, 条目间父子关系, 对应路径, 所属模块等等很多属性, 它应不像菜单路由项一样隐藏在背后干活, 它是可见的; 同时由于有通配符的存在, 它与菜单路由项并不是一一对应关系. (比较奇怪的是默认的Navigation菜单是用户模块创建的, 但它里面的所有菜单项却是系统模块定义的.) 既然router表的数据从钩子函数而来, 那link表是否也有对应的钩子呢, 实际上菜单项是由菜单模块(Menu Moudle)进行管理, 通过GUI界面直接配置, 当然菜单API也有对应接口,比如menu_link_save(). ( 实在不行你直接写数据库也行, 那不就是hack菜单模块了麽)
Drupal6.x增加了两个alter钩子函数对应这两张表, 它们是hook_menu_alter()<--->menu_router, hook_menu_link_alter()<--->menu_links, 它们主要处理内容变化时的处理逻辑, 由Drupal_alter()函数调用, 看代码注释说这个函数非常Ugly, 要在7中把它解决掉. 头晕了一天, 今天也没有心思再看下去了.
总结:
现在我们有点明白Drupal的菜单机制了吧, 它主要由菜单api和菜单模块组成, 提供一种框架, 使得其他功能模块能过注册菜单路由项, 并在分发过程中, 通过该菜单路由表完成用户页面请求(具体URL)到功能模块业务逻辑的映射. 当然Drupal的菜单机制还有很多复杂特性, 来日方长, 有空继续钻研.
另:有一点不明白的是menu_router为啥要用钩子函数, 不能直接用初始数据库脚本麽, 不过我也没研究过安装过程, 似乎好像没有一个地方用了数据库脚本, 有人清楚这一块麽?
对menu系统研究很少,6
对menu系统研究很少,6.x的变化更大,随便胡说两句。。。
drupal_alter() 是比较 ugly ,我觉得主要是 PHP 本身的 func_get_args 对参数 pass-by-value 还是 pass-by-reference 的处理就比较 ugly
对不起最后一点又不太明白,hook_menu 好像只在模块启用的时候调用吧,应该可以放到安装脚本中。哦,menu_rebuild 时是不是会用?没看code....
因为我当前还没看那
因为我当前还没看那么深入, 今天这个menu把我给整够戗; 原来的疑惑是以为没有单独的安装脚本(与业务逻辑分开), 后来发现Drupal的模块是热插拔的, 它的模块安装也是通过钩子来实现的, 有hook_install, hook_uninstall, 还有更新, 使能去使能. 比我想的要强多了, 不过它要是能再支持版本升级和失败自动回滚就好了, 健壮系统都要这个.
这年头炒股, 股票跌得象白菜; 这年纪Drupal, 莫名其妙成小白;
-------------
这年头炒股, 股票跌得象白菜; 这年纪Drupal, 莫名其妙成小白;
我觉得当前更适合一
我觉得当前更适合一些实战操作的讲解,像我这样菜鸟水平的drupal爱好者有很多很多,很多基本的操作都不熟悉,再加上语言上的障碍,这些基本的东西就显得尤为重要。
可以通俗的说,你不要给我讲这些低层的关系和概念,我只需要我该怎样才能实现这个效果。
我没有说这样的文章写的不好,我从头看完了,我只是看不懂。可能有一天我会发觉着篇文章的重要性,但不是现在。
drupal、joomla!等内容管理系统之所以在中国没有普及,都和操作有很大关系,国内很多站长水平有限,最好是拿来就用,而drupal不是,为什么不能多写一些新手引导的内容,我相信肯定会很受欢迎
我说的可能不合适,但是这是我的感受,说出来和大家交流,总比一声不吭泡在坛子里好。
--------------AD-----------------
新转drupal5.x站 http://www.zbcpet.com
########## AD ################
主要以学习为主,欢迎大家来交流
http://playts.com
呵呵, 这位兄弟,
呵呵, 这位兄弟, 其实我也是Drupal的新手, 我总共看Druapl不超过4天, 我记录的是我学习的一个过程, 而我的学习线索是沿着开发路线走的, 先理论后实践, 再理论再实践这样一个过程, 也就是我们常说的原型法了, 先构建一个初始原型, 然后实现验证它, 再推翻重构一个原型, 再实现再验证... :)
我一样也很多操作不熟悉, 而且很害怕去接触那些复杂的模块的使用, 那很容易迷失方向, 所以我也希望论坛大拿能够有一些这方面的系统指导. 比如推出几个典型站范例, 某某风格应用了那些模块, 呵呵, 相当于盒饭打包了.
- - - - - - - -
这年头炒股, 股票跌得象白菜; 这年纪Drupal, 莫名其妙成小白;
-------------
这年头炒股, 股票跌得象白菜; 这年纪Drupal, 莫名其妙成小白;
我很欣赏你的学习态
我很欣赏你的学习态度,令我非常羡慕,或许我也考虑一下自己的学习方向以及学习计划。
近期我在整理一些对新手帮助的资料,尽自己一份能力。
--------------AD-----------------
新转drupal5.x站 http://www.zbcpet.com
########## AD ################
主要以学习为主,欢迎大家来交流
http://playts.com
嗯,普及性文章也很
嗯,普及性文章也很重要,特别是drupal这样入门比较难,学习曲线比较陡的。Drupal 的易用性的确还差一些,也限制了drupal的普及,希望d7, d8 在这方面能越来越好。 Drupal Recipe 或者一些简单的套餐设置介绍,估计是很多新手站长最需要的吧?
说到心里去了
没错,我们都是新手,刚开始Drupal不久。
我们刚开始的时候就是想快点动手做点什么出来,哪怕是个最简单的几个效果。更多人不是为Drupal而Drupal,它只是个工具而已。我们希望看到基本操作过程的教程,详尽的教程。至于理论性的东西应该发到 “深入研究Drupal” 栏目而不是 “新手专区”。
毛主席的最大本事就是把深奥的道理用最简单的话说出来,说得每个农民都明白。这样广大的老百姓就都来参加革命了。
xeopn辛苦了,你的辛苦
xeopn辛苦了,你的辛苦让大家了解了更多!
------------------------------------
Drupal小站:http://www.boygj.com/
Drupal小站:http://boygj.com/
你研究的是d6吧?如果
你研究的是d6吧?如果自己开发我建议你用d5;d6搞的太复杂,越来越通俗化了;其实drupal的菜单是很简单的,在模块里定义好基本不需要存入数据库;你看看d5的数据库吧,里面只有一个menu表,如果你不打算用menu模块的话,这个表基本上也用不到.
说到我心里去了
我是个新手,新PHP手,新的编程手。但被要求来学drupal。现在真的很困难,看了大虾们的帖子真的收获挺大。希望你们写出更多通俗易懂的文章,小弟感激不尽。辛苦辛苦。
有的时候越看帖子越迷茫,总产生怀疑,我想问问大家,像我这样一个新手,从drupal5开始学还是从drupal6啊。我是想从浅入深的学,先学会使用,慢慢再学着操纵模块这样来学这个drupal.
冒似,drupal5和drupal6有
冒似,drupal5和drupal6有很多地方大不同呢,网上的中文翻译也是冲着5.x去的,6的还没有出来吧,要学就从drupal6.x开始好了,都是新的一页,不是。
Drupal
个人觉得Drupal跟Joomla比还是比较复杂了些,不过Drupal集成的功能模块比较好,不用花钱另外去买,模板官方网站也发布了很多不错的
http://www.kziz.cn