Drupal如何解析主题继承关系?
Drupal中,主题是可以继承的,或者说是扩展。例如,要创建一个新的名为custom的主题,该主题与名为default的主题只有某些细小的差别。这个时候,不需要复制一份default到custom,可以在custom声明该主题继承自default就可以了。
主题的继承关系在info文件中说明。首先,default主题的info文件不需要修改:
name = Default Theme
custom主题的info文件需要特别地声明base theme属性:
name = Custom Theme
base theme = default
Drupal内部是如何解析这种继承关系的呢?解析的过程发生在system_list()函数中:
$result = db_query("SELECT * FROM {system} WHERE type = 'theme' OR (type = 'module' AND status = 1) ORDER BY weight ASC, name ASC");
foreach ($result as $record) {
$record->info = unserialize($record->info);
// Build a list of themes.
if ($record->type == 'theme') {
$lists['theme'][$record->name] = $record;
}
}
foreach ($lists['theme'] as $key => $theme) {
if (!empty($theme->info['base theme'])) {
// Make a list of the theme's base themes.
require_once DRUPAL_ROOT . '/includes/theme.inc';
$lists['theme'][$key]->base_themes = drupal_find_base_themes($lists['theme'], $key);
// Don't proceed if there was a problem with the root base theme.
if (!current($lists['theme'][$key]->base_themes)) {
continue;
}
// Determine the root base theme.
$base_key = key($lists['theme'][$key]->base_themes);
// Add to the list of sub-themes for each of the theme's base themes.
foreach (array_keys($lists['theme'][$key]->base_themes) as $base_theme) {
$lists['theme'][$base_theme]->sub_themes[$key] = $lists['theme'][$key]->info['name'];
}
// Add the base theme's theme engine info.
$lists['theme'][$key]->info['engine'] = isset($lists['theme'][$base_key]->info['engine']) ? $lists['theme'][$base_key]->info['engine'] : 'theme';
}
else {
// A plain theme is its own engine.
$base_key = $key;
if (!isset($lists['theme'][$key]->info['engine'])) {
$lists['theme'][$key]->info['engine'] = 'theme';
}
}
// Set the theme engine prefix.
$lists['theme'][$key]->prefix = ($lists['theme'][$key]->info['engine'] == 'theme') ? $base_key : $lists['theme'][$key]->info['engine'];
}
首先,从系统表system中读取出主题信息,记录到$lists['theme']数组:
$result = db_query("SELECT * FROM {system} WHERE type = 'theme' OR (type = 'module' AND status = 1) ORDER BY weight ASC, name ASC");
foreach ($result as $record) {
$record->info = unserialize($record->info);
// Build a list of themes.
if ($record->type == 'theme') {
$lists['theme'][$record->name] = $record;
}
}
然后,遍历$lists['theme']数组。如果声明了base theme属性,则通过drupal_find_base_themes()函数获取父主题:
require_once DRUPAL_ROOT . '/includes/theme.inc';
$lists['theme'][$key]->base_themes = drupal_find_base_themes($lists['theme'], $key);
// Don't proceed if there was a problem with the root base theme.
if (!current($lists['theme'][$key]->base_themes)) {
continue;
}
drupal_find_base_theme()返回的是一个数组。在当前例子中,返回的数组是array('default' => 'Default Theme')。主题也是可以多重继承的,假设default主题再继承自top主题,drupal_find_base_theme()返回的数组则是array('top' => 'Top Theme', 'default' => 'Default Theme')。base_themes数组是有序的,最顶层的主题在最前面,然后依次下来。
function drupal_find_base_themes($themes, $key, $used_keys = array()) {
$base_key = $themes[$key]->info['base theme'];
// Does the base theme exist?
if (!isset($themes[$base_key])) {
return array($base_key => NULL);
}
$current_base_theme = array($base_key => $themes[$base_key]->info['name']);
// Is the base theme itself a child of another theme?
if (isset($themes[$base_key]->info['base theme'])) {
// Do we already know the base themes of this theme?
if (isset($themes[$base_key]->base_themes)) {
return $themes[$base_key]->base_themes + $current_base_theme;
}
// Prevent loops.
if (!empty($used_keys[$base_key])) {
return array($base_key => NULL);
}
$used_keys[$base_key] = TRUE;
return drupal_find_base_themes($themes, $base_key, $used_keys) + $current_base_theme;
}
// If we get here, then this is our parent theme.
return $current_base_theme;
}
接下来得到root base theme,base_themes数组中的第一个key,上例中是top。
// Determine the root base theme.
$base_key = key($lists['theme'][$key]->base_themes);
再后,更新每个base theme的sub_themes属性。sub_themes是无序的,取决于于主题加载顺序。
// Add to the list of sub-themes for each of the theme's base themes.
foreach (array_keys($lists['theme'][$key]->base_themes) as $base_theme) {
$lists['theme'][$base_theme]->sub_themes[$key] = $lists['theme'][$key]->info['name'];
}
最后,设置引擎前缀engine prefix,就是主题解析函数都是以什么开头的。注意变量$base_key,当有继承存在,$base_key代表root base theme,否则就是current theme。当前主题有声明engine属性时,prefix就是engine属性,否则就是$base_key。
if (!empty($theme->info['base theme'])) {
// Determine the root base theme.
$base_key = key($lists['theme'][$key]->base_themes);
// Add the base theme's theme engine info.
$lists['theme'][$key]->info['engine'] = isset($lists['theme'][$base_key]->info['engine']) ? $lists['theme'][$base_key]->info['engine'] : 'theme';
}
else {
// A plain theme is its own engine.
$base_key = $key;
if (!isset($lists['theme'][$key]->info['engine'])) {
$lists['theme'][$key]->info['engine'] = 'theme';
}
}
// Set the theme engine prefix.
$lists['theme'][$key]->prefix = ($lists['theme'][$key]->info['engine'] == 'theme') ? $base_key : $lists['theme'][$key]->info['engine'];
Drupal如何解析主题继承关系?的更多相关文章
- Jaxb 解析 带有继承关系的bean与xml
具体方法: 1. 在jaxb的setClasstobebounds中,只需要子类的class,无需父类. 2. 父类的前面加如下声明: @XmlAccessorType(XmlAccessType.F ...
- Java类继承关系中的初始化顺序
Java类初始化的顺序经常让人犯迷糊,现在本文尝试着从JVM的角度,对Java非继承和继承关系中类的初始化顺序进行试验,尝试给出JVM角度的解释. 非继承关系中的初始化顺序 对于非继承关系,主类Ini ...
- HandlerMethodReturnValueHandler SpringMVC 参数解析 继承关系以及各解析器解析类型
I HandlerMethodReturnValueHandler (org.springframework.web.method.support) AbstractMessageConverterM ...
- HandlerMethodArgumentResolver SpringMVC 参数解析 继承关系以及各解析器解析类型
HandlerMethodArgumentResolver SpringMVC 参数解析 继承关系以及各解析器解析类型 I HandlerMethodArgumentResolver (org.spr ...
- 深入Spring Boot:ClassLoader的继承关系和影响
前言 对spring boot本身启动原理的分析, Spring boot里的ClassLoader继承关系 可以运行下面提供的demo,分别在不同的场景下运行,可以知道不同场景下的Spring bo ...
- Style在Android中的继承关系
Style在Android中的继承关系 Android的Styles(样式)和Themes(主题)非常类似Web开发里的CSS,方便开发者将页面内容和布局呈现分开.Style和Theme在Androi ...
- drf:restful概念,类继承关系,drf请求封装,drf请求流程,版本控制组件,认证组件(token),权限组件
1.restful规范 resfful规范的概念最重要: 是一套规范,规则,用于程序之间进行数据交换的约定. 他规定了一些协议,对我们感受最直接的就是,以前写增删改查的时候需要些四个视图寒素,rest ...
- C++类继承关系视图的自动生成
原创文章,转载请注明出处. 工欲善其事,必先利其器.阅读大型C++工程项目,如果有一些自动化的分析工具支持,学习的效率将大大提升.在前文中介绍了Source Insight在Linux下的安装方法,本 ...
- Hibernate注解方式配置-继承关系
在JPA中,实体继承关系的映射策略共有三种:单表继承策略(table per class).Joined策略(table per subclass)和Table_PER_Class策略. 1.单表继承 ...
随机推荐
- hdu 6047 Maximum Sequence 贪心
Description Steph is extremely obsessed with “sequence problems” that are usually seen on magazines: ...
- go环境变量配置liteide配置
1.go环境变量配置 http://download.csdn.net/detail/defonds/9408855下载后直接安装如果都选默认就只要添加一个gopath就可以了 不是默认添加goroo ...
- Problem E: 零起点学算法34——3n+1问题
#include<stdio.h> #include<math.h> int main() { int n; n<=pow(,); ; scanf("%d&qu ...
- redis源码解析之dict数据结构
dict 是redis中最重要的数据结构,存放结构体redisDb中. typedef struct dict { dictType *type; void *privdata; dictht ht[ ...
- python的dict和set
dict dict是dictionary的缩写,python内置了字典,在其他语言中也称为map,使用键值对储存,具有极快的查找速度. 如果是只用list来实现,就需要两个list,先在第一个list ...
- 连接mysql时1045错误的解决办法
重装系统后,今天mysql提示1045错误无法连接上,找了很久得出方法如下: 修改root密码即可正常. 1,进入mysql控制台选择: 2,use mysql; 3,update user set ...
- iOS \U6b3e转字符串
-(NSString *)replaceUnicode:(NSString *)unicodeStr { NSString *tempStr1 = [unicodeStr stringByReplac ...
- [转]SSIS ADO.NET vs OLEDB
本文转自:http://social.msdn.microsoft.com/Forums/sqlserver/en-US/1a9e3670-9685-4943-913b-123ecf248a9c/ol ...
- Oracle 10g数据库备份与恢复操作手册
Oracle 10g数据库备份与恢复操作手册 目录 Oracle 10g数据库备份与恢复操作手册... 前言... 文档目的... 文档范围... 目标读者... 其他说明... 冷备份... 热备份 ...
- python 调试模式pdb(转)
标准库的pdb pdb是Python自带的一个库,为Python程序提供了一种交互式的源代码调试功能,包含了现代调试器应有的功能,包括设置断点.单步调试.查看源码.查看程序堆栈等.如果读者具有C或C+ ...