drupal 7 render arrays详解

drupal 7 render arrays详解

什么是渲染(rendering)?

drupal中rendering,简单来说就是把具有特定结构的关联数组转换为HTML页面的过程。从drupal 7开始,render arrays(中文翻译渲染数组)为drupal页面渲染的最基本元素,render arrays也叫rendable arrays,意为’可渲染的数据‘。
其实render array就是一个php关联数组,但符合drupal页面渲染过程中的标准和数据结构。

大多数情况下,用来渲染页面的数据一直保存在关联数组里,直到页面的最后渲染阶段才被调用,这种机制为页面的布局和内容显示提供了极大的灵活性,也有益于系统以后的性能提升。

注意:虽然render arrays和form api中使用的数组具有某些共同的元素,属性以及结构,但许多表单属性的意义仅限于FORM API,不能等同于render API.简单来说,form API的数组必须通过drupal_get_form这个函数的处理后才能变为标准的render arrays.如果直接把未经该函数处理的form api数组传递给render API,最后的效果可能不能如你所愿。

DRUPAL的页面的渲染都是根据render array中的各种数据来进行的,这些数据包括各类属性,如#type。下面就是一个用来渲染页面的render array例子:

<?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(
    ...
  ),
  ...
);
?>

上面的关联数组中,我们看到的带‘#’的key即为render array中的属性,以‘#theme' = ’page'为例,它的值为page,就这是说render api看到这个属性后将使用theme_page的函数(即page.tpl.php)来渲染。
其中的content是它的子元素,具有自己的render array数据结构

为什么需要render arrays?

在drupal 7之前,修改drupal页面的渲染方式和内容一般通过hook_form_alter这些钩子来实现,但在渲染的这个阶段,大部分元素已经转换为为HTML代码,想要修改已经很难。

而drupal 7及以后的版本提供了诸如hook_page_alter的钩子,借助这些钩子,开发者可以轻松在页面的最后渲染阶段对页面进行处理,就是说,只需在主题中加一小段PHP代码就能改变页面的布局。

下面是使用hook_page_alter对页进行更改的例子:

<?php
function mytheme_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']);
}
?>

把这段代码添加到你主题目录中的template.php里,mytheme改成你主题相应的名字。

render array与元素(elements)之前的关系

这里的元素是指drupal系统中预先定义好的具有‘#type'及其它属性的render array,在system_element_info的函数里可以找到这些elements的原型。开发者也可在定制的模块中使用hook_element_info来定义自己的元素。
当render api处理render array时,会根据render array中的‘#type'属性值从预先定义好的元素中加载默认各类属性,如#theme,#method这些。

用render array来完成HTML代码的生成

与之前的drupal版本不一样,定制模块需要输出内容时都应以render array的形式来完成。使用hook_men页面回调函数应该返回一个render array而不是drupal 6中的HTML代码。
hook_block_view()的$block['content']就是一个例子,这样做的一个优势就是在最后渲染之前,你的模块和其它drupal模块都能够轻松对数据进行处理

下面是使用hook_men返回render array的例子(drupal 6中直接返回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;
}
// drupal 7的方法
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;
}
?>

定义render array的例子

以下是定义一个render arrays的例子,来自于drupal官方的render array模块例子中的代码

<?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',
  ),
);
?>

翻译自drupal官方文档

添加新评论

个人信息
评论内容
提交该页面即表示您接受Mollon的隐私政策