所谓【渲染数组】是从Drupal7开始导入的一种生成页面的数组。生成页面(或其中一部分)所使用的数据,在模板机制中截止到被实际渲染出来会保持一种结构化的数组形态。当更改页面的布局以及内容时,它不仅仅带来了灵活性,而且将来对于性能的提升被寄予厚望。
什么是渲染?
Drupal中的所谓渲染,就是把渲染数组变成HTML。
什么是渲染数组?
渲染数组是典型的Drupal结构化的数组,它包含了其自身是如何被渲染的信息。例如页面的渲染数组如下所示。
<?php $page = array( '#show_messages' => TRUE, '#theme' => 'page', '#type' => 'page', 'content' => array( 'system_main' => array(...), 'another_block' => array(...), '#sorted' => TRUE, ), 'sidebar_first' => array( ... ), 'footer' => array( ... ), ... ); ?>
历史演变
Drupal7之前的版本,比如表单可以通过hook_form_alter()等钩子对结构事后进行更改。但是其他以外的很多情况即使通过模块或主题进行更改,此时已经被渲染成HTML了。
Drupal7以后在模块或主题中利用hook_page_alter() 进行更改时,页面布局以及内容的更改可以在相当最后的阶段实现。比如在一个页面的右侧添加区块时,只要在主题中稍微添加PHP代码就能做到。
渲染数组的更改操作
诸如可以在页面生成的过程中更改表单的此类操作,区块和页面可以进行变更。其他类型也同样。可以利用hook_page_alter()在模块和主题中进行以下操作。
<?php function mymodule_page_alter(&$page) { // 搜索表单移动到页脚 $page['footer']['search_form'] = $page['sidebar_first']['search_form']; unset($page['sidebar_first']['search_form']); // 取消「powered by Drupal」 unset($page['footer']['system_powered-by']); } ?>
渲染数组和元素
与之前的drupal版本不同的是,使用模块生成内容时需要经常保持数据为渲染数组的形式。页面回调也不例外。要求类似hook_block_view() 中的 $block['content'] 一样进行描述。由此在页面生成的多个处理环节中,其他的模块可以利用此数据。
Drupa6的方法体中,页面回调函数获取HTML并进行渲染处理。新的方法如下所示。
<?php function mymodule_menu() { $items['mypage-html'] = array( 'title' => 'My page with HTML-style function', 'page callback' => 'mymodule_html_page', 'access callback' => TRUE, ); $items['mypage-ra'] = array( 'title' => 'My page with render array function', 'page callback' => 'mymodule_ra_page', 'access callback' => TRUE, ); return $items; } // 生成页面的旧方法(返回HTML,当然此方法还可以继续使用) function mymodule_html_page { $output = '<p>A paragraph about some stuff...</p>'; $output .= '<ul><li>first item</li><li>second item</li><li>third item</li></ul>'; return $output; } // 生成渲染数组的新方法 function mymodule_ra_page { $output = array( 'first_para' => array( '#type' => 'markup', '#markup' => '<p>A paragraph about some stuff...</p>', ), 'second_para' => array( '#items' => array('first item', 'second item', 'third item'), '#theme' => 'item_list', ), ); return $output; } ?>
元素类型
如上所示Drupal中存在各种元素(参照hook_element_info()。Drupal6中为hook_elements()),这些元素被定义为元素类型。这些元素有内核提供的也有模块提供的。可以阅读system_element_info() ,定义了诸如页面,表单,html标签,值,markup,链接,字段组合等等都被定义为元素类型。根据规定,这些要素类型中所使用的属性【#-属性】(#开头的属性)的相关说明,都描述在各个要素类型所使用的主题函数文档中。例如#type => 'html_tag' 所定义的属性说明在theme_html_tag() 的文档中有描述。开发人员也可以定义独自的要素类型和属性。
以下是Examples Project's中的渲染实例。
<?php $demos = array( t('Super simple #markup') => array( '#markup' => t('Some basic text in a #markup (shows basic markup and how it is rendered)'), ), 'prefix_suffix' => array( '#markup' => t('This one adds a prefix and suffix, which put a div around the item'), '#prefix' => '<div><br/>(prefix)<br/>', '#suffix' => '<br/>(suffix)</div>', ), 'theme for an element' => array( 'child' => array( t('This is some text that should be put together'), t('This is some more text that we need'), ), '#separator' => ' | ', // Made up for this theme function. '#theme' => 'render_example_aggregate', ), ); ?>
属性的示例
渲染数组中可以根据需要定义非常多的属性。这里列举说明使用频度非常高的属性。其中很多可以在Form API Reference中找到。这是因为Form API经常需要渲染API,以及渲染API也是经常用于Form的渲染。
属性 |
说明 |
#type |
元素类型。hook_element_info()中所设置的信息中各个类型的默认属性。 |
#markup |
最简单的属性。其仅仅提供了#type == 'markup'的mark up字符串。 |
#prefix/#suffix |
渲染时所用到的前缀和后缀的文本。 |
#pre_render |
渲染数组被执行前可以更改其结构的函数数组。更改调整,某些页面元素的撤销以及通过设置#printed = TRUE使其标识为已渲染完毕之类的操作等等。 |
#post_render |
针对渲染后所生成的HTML进行操作的函数数组。这些函数可以获取生成的HTML以及原有的渲染函数。除了使用了主体化的子系统以外,它的作用和 #theme_wrappers非常相似。 |
#theme |
渲染数组执行本身渲染的主题钩子。(通常为1个,有时也存在多个函数的数组)Drupal7的#theme和Drupal6的#theme是完全不同的产物。关于Drupal6中的#theme 我们就不考虑了。基本上'#theme' = 'function_name'表示调用theme_function_name(),其主题函数的参数为'#var_name' = $value 所组成的渲染数组。 所有的默认的主题钩子可以参考http://api.drupal.org/api/drupal/modules--system--theme.api.php/group/themeable/7 |
#theme_wrappers |
子孙数组在渲染并配置后,在渲染数组中可以实现添加操作的主题钩子数组。通常用于在已渲染的子孙数组中递归渲染时所用到。一般不大会和#theme 一起使用。 |
#cache |
可以指定渲染数组是否可以缓存以及其期限。渲染数组一旦被渲染完成后,在指定期限内不会再次被渲染。缓存机制使用了Drupal中的cache_get()和cache_set()。其数组结构如下。 'keys' =>缓存ID 表示构成生成素材的key数组 'bin' => 存储缓存的数据库表名称(如'cache' 、'cache_page'等等) 'expire' =>表示缓存期限的UNIX时间戳。 'granularity'=> 表示缓存的位掩码。需要使用DRUPAL_CACHE_PER_PAGE, DRUPAL_CACHE_PER_ROLE, 或DRUPAL_CACHE_PER_USER 之类的常量。 需要注意的是即使指定了期限,在未执行cron之前也不会过期。 |
|
|
所有的元素也可以通过自己定义属性。实际上除此以外还存在很多。其大部分都在Form API Reference handbook page中有详细收录。
原文:http://customfield.jp/translation/content/28