你现在的位置:首页 > PHP网站建设知识库 > Drupal > 正文

Drupal 7 模块开发Module Development(3)

drupal主题层

在接下来的两章 我们先讲module如何与theme层整合,第三章我们主要讲述体系架构,主题函数,模板,渲染元素,主题注册。第四章我们讲实例。

业务逻辑与表现逻辑

drupal分离了业务和表现,所以我们不用写诸如这样的代码

 

return '<div class="wrapper">' . $data . '</div>';

 

传统的分离为了:

 

  • 代码容易维护
  • 代码复用

 

drupal却把”swap-ability“用到了极致

你也许会想 主题是给网站提供html和css的,那么在drupal官网有成百上千的贡献模块,这些主题能照顾到每一个模块的外观么??当然不

因为模块本身是最知道该如何排列的,模块随时可以覆写默认主题样式来达到目的

 

回头看第二章的代码

 

$variables = array('items' => $list, 'type' => 'ol');
$content = theme('item_list', $variables)

 

通过调用theme(),我们确认了委托并用了合适的接口,我们实际在告诉drupal:

 

“hey theme()! 我想要把我的数据标记成item_list形状,你能帮我么?我不太知道细节~谢谢”

 

我们的模块仅仅需要决定用哪一个主题钩子来标记数据,数据被显示为一个无序列表 一个表格 还是一个字母表。

 

除了API钩子,drupal也提供了theme钩子,一个主题钩子是一个简单的标记数据命名法,如 用item_list等不同参数来标记数据将会有不同的效果,不过要记住,跟以前一样,一个模块只能有一个主题钩子

当你调用theme()时,实际调用的是缺省主题function theme_HOOKNAME ,覆写的主题function为 THEMENAME_HOOKNAME,在drupal内部机制中,你可以看到一个theme_item_list()在 includes.inc或 theme.inc中,这个是缺省主题下面的item_list。如果我们启用了另一个主题,如Bartik,它可以用bartik_item_list()来覆写原先的function,这样theme()就用这个代替了原先的函数了。

数据粒度

 

drupal的颗粒性注定了它的强大,每一个通过主题系统处理过的内容都是单独分开处理的。每个data都是独立主题化的,然后组成越来越大的块儿,在聚合过程中,它再次主题化,下图可以清晰的展现:

 

 

 

这样做有两个优点

 

  • 每个模块负责主题化自己的data,可以制作非常特殊化的主题,也可以复用缺省主题,同时还允许自定义css
  • 对开发者很友好,颗粒化使得开发者能根据自己的意图更好的改写界面。

主题引擎

theme_[theme hook name]

 

主题函数只有一个参数 如下所示

 

function theme_THEME_HOOK_NAME($variables) {…}

 

其中这个$variables是一个数组,里面包含了我们需要的data和我们传递进去的option。为什么不用多个参数传递呢?事实上,以前的drupal是采用多参数的,具体原因,当我们看到预处理功能时再讲

 

theme_item_list()里面的$variables定义参数如下:

 

一个在列表中显示的条目数组。如果一个条目是一个string,那么用的时候取出即可,如果条目是个数组,那么data元素就是列表项的内容。如果条目是一个有子元素的数组,那么这些子元素将作为下级列表项显示,所有其他元素将作为列表项的属性出现。
Title: 列表项的titile
Type: 返回的列表类型 (e.g. ul, ol).
Attributes:应用于列表元素的属性。

 

items和title获取的是实际data,type和attributes是选择项 
 

主题函数与大多数函数的最大不同就是你从不直接调用主题函数。它试图通过调用theme_item_list($vars)得到你的数据,而你要做的是调用theme("item_list",
$vars)。

 

预处理函数

现在我们将看到主题系统真正的灵活性 当一个模块调用一个主题钩子时,预处理函数能够通过一个模块来更改另一个模块的变量值。在实际主题钩子接口调用以前,预处理函数将被调用来更改data,采用如下步骤进行: