导航

解析drupal_render()

Posted on 2014-04-30 08:26  eastson  阅读(675)  评论(0编辑  收藏  举报

drupal_render()函数接收一个结构化的数组作为参数,然后调用theme()输出HTML。

function drupal_render(&$elements) {
  ... ...
}


$elements['#printed']控制是否已经执行过,避免重复执行。在drupal_render()的开头检查它是否有设置,对应的,在drupal_render()的结尾设置它。

// Do not print elements twice.
if (!empty($elements['#printed'])) {
  return '';
}

// 在drupal_render()结尾会设置#printed
$elements['#printed'] = TRUE;

 

$elements['#cache']控制是否允许使用缓存。如果有缓存,就直接返回,不用再重复执行后面的代码。|

// Try to fetch the element's markup from cache and return.
if (isset($elements['#cache'])) {
  $cached_output = drupal_render_cache_get($elements);
  if ($cached_output !== FALSE) {
    return $cached_output;
  }
}

// 在drupal_render()结尾保存缓存
if (isset($elements['#cache'])) {
  drupal_render_cache_set($output, $elements);
}

 

$elements['#pre_render']是一个function数组,drupal_render()会依次执行其中的function,这样可以在render之前对$elements再做一些修改。

// Make any final changes to the element before it is rendered. This means
// that the $element or the children can be altered or corrected before the
// element is rendered into the final text.
if (isset($elements['#pre_render'])) {
  foreach ($elements['#pre_render'] as $function) {
    if (function_exists($function)) {
      $elements = $function($elements);
    }
  }
}


$elements包含两类项目:properties和children。properties以#开头,其它都是children。

// Get the children of the element, sorted by weight.
$children = element_children($elements, TRUE);


$elements['#children']是一个字符串,临时保存drupal_render()输出的内容。

// Initialize this element's #children, unless a #pre_render callback already
// preset #children.
if (!isset($elements['#children'])) {
  $elements['#children'] = '';
}


$elements['#theme']控制调用的theme function,结果保存在临时变量$elements['#children']。

// Call the element's #theme function if it is set. Then any children of the
// element have to be rendered there.
if (isset($elements['#theme'])) {
  $elements['#children'] = theme($elements['#theme'], $elements);
}

 
如果$elements['#theme']没有被处理,对应的$elements['#children']就为空。这个时候,drupal_render()就循环$children,递归调用drupal_render()。注意这里返回的结果是串联在$elements['#children']。

// If #theme was not set and the element has children, render them now.
// This is the same process as drupal_render_children() but is inlined
// for speed.
if ($elements['#children'] == '') {
  foreach ($children as $key) {
    $elements['#children'] .= drupal_render($elements[$key]);
  }
}


$elements['#theme_wrappers']是一个function数组,循环依次传入到theme()。注意这里返回的结果每次都会覆盖掉$elements['#children']。

// Let the theme functions in #theme_wrappers add markup around the rendered
// children.
if (isset($elements['#theme_wrappers'])) {
  foreach ($elements['#theme_wrappers'] as $theme_wrapper) {
    $elements['#children'] = theme($theme_wrapper, $elements);
  }
}


$elements['#post_render']也是一个function数组,可以对生成的$elements['#children']做二次处理。注意这里返回的结果每次都会覆盖掉$elements['#children']。

// Filter the outputted content and make any last changes before the
// content is sent to the browser. The changes are made on $content
// which allows the output'ed text to be filtered.
if (isset($elements['#post_render'])) {
  foreach ($elements['#post_render'] as $function) {
    if (function_exists($function)) {
      $elements['#children'] = $function($elements['#children'], $elements);
    }
  }
}


$elements['#prefix']和$elements['#suffix']允许对输出HTML做最后修饰。

$prefix = isset($elements['#prefix']) ? $elements['#prefix'] : '';
$suffix = isset($elements['#suffix']) ? $elements['#suffix'] : '';
$output = $prefix . $elements['#children'] . $suffix;