作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
到目前为止,我们仅仅定义了一个静态菜单项。让我们再添加一个与它相关的子项:
function menu_abc_menu() {
$items['menu_abc'] = array(
'title' => '菜单ABC',
'title callback' => 'menu_abc_my_title',
'description' => '一个简单的菜单项.',
'page callback' => 'menu_abc_callback_page',
'file' => 'menu_abc.pages.inc',
'access callback' => 'user_access',
'access arguments' => array('access abc'),
'weight' => 10,
'menu_name' => 'main-menu',
);
$items['menu_abc/sub'] = array(
'title' => '菜单ABC子项',
'description' => '菜单ABC的子项.',
'page callback' => 'menu_abc_sub_callback_page',
'file' => 'menu_abc.pages.inc',
'access callback' => TRUE,
'weight' => 10,
'menu_name' => 'main-menu',
);
return $items;
}
然后向menu_abc.pages.inc文件中添加以下代码:
/**
* 菜单项menu_abc/sub的回调函数.
*/
function menu_abc_sub_callback_page(){
$render_array = array();
$render_array['#markup'] = t('菜单ABC子页面内容');
return $render_array;
}
Drupal将会把第2个菜单项(menu_abc/sub)看作是第一个菜单(menu_abc)的孩子。因此,我们导航到主菜单的管理界面,在显示菜单项时,Drupal将会缩进第2个菜单项,如图3-9所示。
图 3-9.嵌套菜单
Drupal还在页面的正文上面,正确的设置了面包屑,用来表示页面之间的嵌套关系。当然,根据设计的要求,可在主题层将菜单或面包屑定义成所要的各种样式。
图 3-10. 子菜单项页面和及其面包屑
为了关联另一个数据库表,我们可以使用方法join()、innerJoin()、leftJoin()、或rightJoin(),下面的代码是一个具体示例:
<?php
$table_alias = $query->join('user', 'u', 'n.uid = u.uid AND u.uid = :uid', array(':uid' => 5));
?>
上述指令,将会对"user"表使用INNER JOIN(默认的关联类型),这里"user"表的别名为"u"。关联的条件为" n.uid = u.uid AND u.uid = :uid",其中:uid的值为5。注意,这里预备语句(prepared statement)片断的具体用法。采用这种方式,在关联语句中添加变量,就可以避免潜在的SQL注入了。即便是对于查询语句片断,也不要直接在里面使用字面值或者变量,这和静态查询中,不能使用字面值或者变量,性质是一样的。innerJoin()、leftJoin()、rightJoin()对应于各自的关联类型,除此以外,它们的用法完全相同。
关联方法的返回值是对应表的别名。如果指定了别名,那么就会使用这个别名,除非这个别名已被其它表使用。在这种情况下,系统将会为其分配一个不同的别名。
注意,在表名的位置上,比如上例中的'user'位置,所有的关联方法都可以接收一个选择查询作为它们的第一个参数。例如:
<?php
$myselect = db_select('mytable')
->fields('mytable')
->condition('myfield', 'myvalue');
$alias = $query->join($myselect, 'myalias', 'n.nid = myalias.nid');
?>