解析drupal_render()
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;
解析drupal_render()的更多相关文章
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- .NET Core中的认证管理解析
.NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...
- Html Agility Pack 解析Html
Hello 好久不见 哈哈,今天给大家分享一个解析Html的类库 Html Agility Pack.这个适用于想获取某网页里面的部分内容.今天就拿我的Csdn的博客列表来举例. 打开页面 用Fir ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
- Asp.Net WebApi核心对象解析(下篇)
在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...
- 【知识必备】内存泄漏全解析,从此拒绝ANR,让OOM远离你的身边,跟内存泄漏say byebye
一.写在前面 对于C++来说,内存泄漏就是new出来的对象没有delete,俗称野指针:而对于java来说,就是new出来的Object放在Heap上无法被GC回收:而这里就把我之前的一篇内存泄漏的总 ...
- SQL Server 数据加密功能解析
SQL Server 数据加密功能解析 转载自: 腾云阁 https://www.qcloud.com/community/article/194 数据加密是数据库被破解.物理介质被盗.备份被窃取的最 ...
随机推荐
- 清北学堂学习总结 day1 数据结构 练习
1.二叉搜索树 STL set直接做就可以了 2.树状数组+差分数列: codevs 1081 线段树练习 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Maste ...
- 【提醒】使用 iptables 时,特别注意 规则的顺序
在 centos 上安装 redis 服务器,很快就搞定了,服务器上使用 redis-cl 测试都没有问题了. 但到宿主机上测试,怎么测试都不通过,关键是:关闭了 centos 的 Iptables ...
- 【资料】wod烟草
注意: 1. 所有效果持续时间是整个地城 2. 某几样菸草在使用 烟雾的祝福 的时候效果只有LV1 (技能 -25), 表示该物品设计上主要是自己使用而非加给团队. SL = 技能等级 HL = 英雄 ...
- [翻译] AnimatedTransitionGallery
AnimatedTransitionGallery 转场动画回廊 https://github.com/shu223/AnimatedTransitionGallery Collection of i ...
- 从两个TIMESTAMP中获取时间差(秒)
When you subtract two variables of type TIMESTAMP, you get an INTERVAL DAY TO SECOND which includes ...
- 用JavaScript修改Canvas图片的分辨率(DPI)
应用场景: 仓库每次发货需要打印标签, Canvas根据从数据库读取的产品信息可以生成标签JPG, 但是这个JPG图片的默认分辨率(DPI)是72 这个DPI太低, 导致打印出来的图片会很模糊. 修改 ...
- Ajax技术——与服务器通信
1. 发送请求 Ajax可以通过XMLHttpRequest对象实现采用异步方式在后台发送请求.通常情况下,Ajax发送请求有两种,一种是发送GET请求,另一种是发送POST请求.但是无论发送哪种请求 ...
- 3 cocos2dx 3.0 源码分析-mainLoop详细
简述: 我靠上面图是不是太大了, 有点看不清了. 总结一下过程: 之前说过的appController 之后经过了若干初始化, 最后调用了displayLinker 的定时调用, 这里调用了函数 ...
- 如何更换Office 2013的product key?
第一步 第二步 第三步 ... ... ... ... ^_^ 参考资料 ======================== Change Product Key Office 2013 Home ...
- PHP的错误处理方式(开发和上线)
对于PHP开发人员来说,一旦某个产品投入使用.应该马上将 display_errors选项关闭.以免由于这些错误所透露的路径.数据库连接.数据表等信息而遭到黑客攻击. 可是.不论什么一个产品在投入使用 ...