Drupal administration theme
Drupal允许为管理后台设置独立的theme,保存在系统变量variable_get('admin_theme')。
Drupal使用全局变量$theme来保存当前请求对应的主题。Drupal在启动时初始化$theme变量:
function _drupal_bootstrap_full() {
... ...
menu_set_custom_theme();
drupal_theme_initialize();
module_invoke_all('init');
} function menu_set_custom_theme() {
menu_get_custom_theme(TRUE);
} function menu_get_custom_theme($initialize = FALSE) {
$custom_theme = &drupal_static(__FUNCTION__);
// Skip this if the site is offline or being installed or updated, since the
// menu system may not be correctly initialized then.
if ($initialize && !_menu_site_is_offline(TRUE) && (!defined('MAINTENANCE_MODE') || (MAINTENANCE_MODE != 'update' && MAINTENANCE_MODE != 'install'))) {
// First allow modules to dynamically set a custom theme for the current
// page. Since we can only have one, the last module to return a valid
// theme takes precedence.
// 调用hook_custom_theme()获取自定义theme
$custom_themes = array_filter(module_invoke_all('custom_theme'), 'drupal_theme_access');
if (!empty($custom_themes)) {
$custom_theme = array_pop($custom_themes);
}
// If there is a theme callback function for the current page, execute it.
// If this returns a valid theme, it will override any theme that was set
// by a hook_custom_theme() implementation above.
// 在hook_menu()定义时也可以用theme callback/theme arguments定义theme
$router_item = menu_get_item();
if (!empty($router_item['access']) && !empty($router_item['theme_callback']) && function_exists($router_item['theme_callback'])) {
$theme_name = call_user_func_array($router_item['theme_callback'], $router_item['theme_arguments']);
if (drupal_theme_access($theme_name)) {
$custom_theme = $theme_name;
}
}
}
return $custom_theme;
} function drupal_theme_initialize() {
global $theme, $user, $theme_key; // If $theme is already set, assume the others are set, too, and do nothing
if (isset($theme)) {
return;
} drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
$themes = list_themes(); // Only select the user selected theme if it is available in the
// list of themes that can be accessed.
// 检查有没有设置用户主题?
$theme = !empty($user->theme) && drupal_theme_access($user->theme) ? $user->theme : variable_get('theme_default', 'bartik'); // Allow modules to override the theme. Validation has already been performed
// inside menu_get_custom_theme(), so we do not need to check it again here.
// 检查有没有设置自定义主题?
$custom_theme = menu_get_custom_theme();
$theme = !empty($custom_theme) ? $custom_theme : $theme; ... ...
}
system模块实现了hook_custom_theme()钩子,检查当前请求menu是否属于admin:
function system_custom_theme() {
if (user_access('view the administration theme') && path_is_admin(current_path())) {
return variable_get('admin_theme');
}
} function path_is_admin($path) {
$path_map = &drupal_static(__FUNCTION__);
if (!isset($path_map['admin'][$path])) {
$patterns = path_get_admin_paths();
$path_map['admin'][$path] = drupal_match_path($path, $patterns['admin']);
$path_map['non_admin'][$path] = drupal_match_path($path, $patterns['non_admin']);
}
return $path_map['admin'][$path] && !$path_map['non_admin'][$path];
}
system_custom_theme()调用path_is_admin()检查请求是否属于admin。path_is_admin()再调用path_get_admin_paths()返回哪些请求是admin,哪些请求是non_admin。
function path_get_admin_paths() {
$patterns = &drupal_static(__FUNCTION__);
if (!isset($patterns)) {
$paths = module_invoke_all('admin_paths');
drupal_alter('admin_paths', $paths);
// Combine all admin paths into one array, and likewise for non-admin paths,
// for easier handling.
$patterns = array();
$patterns['admin'] = array();
$patterns['non_admin'] = array();
foreach ($paths as $path => $enabled) {
if ($enabled) {
$patterns['admin'][] = $path;
}
else {
$patterns['non_admin'][] = $path;
}
}
$patterns['admin'] = implode("\n", $patterns['admin']);
$patterns['non_admin'] = implode("\n", $patterns['non_admin']);
}
return $patterns;
}
path_get_admin_paths()如何判断请求是admin还是non_admin?这又要调用另外一个钩子hook_admin_paths()。system模块就实现了这个钩子:
function system_admin_paths() {
$paths = array(
'admin' => TRUE,
'admin/*' => TRUE,
'batch' => TRUE,
// This page should not be treated as administrative since it outputs its
// own content (outside of any administration theme).
'admin/reports/status/php' => FALSE,
);
return $paths;
}
总结一下:
1. system模块通过实现hook_admin_paths()钩子定义了所有以admin/开头的请求都属于admin请求。
2. system模块通过实现hook_custom_theme()钩子定义了所有admin请求都使用admin_theme。
Drupal administration theme的更多相关文章
- 使用Drush管理Drupal站点
Drush(Drush = Drupal + Shell)就是使用命令行命令来操作Drupal站点,它的命令格式与git类似,都是双字命令(drush + 实际的命令).既然是命令行命令,也就可以使用 ...
- 【转】为drupal初学者准备的12个精品课程
下面是一些网上免费的drupal教程,这些教程将对初学者和那些从别的CMS转向drupal的开发者非常有帮助.初级教程 1.在开始用drupal之前,你要知道一些基本的东西,内容很简单,但有些还是值得 ...
- Drupal中hook_theme函数用法
在开发的时候不免要使用到drupal theme 定义.举个简单的例子: 复制代码 代码如下: <?phpfunction modulename_theme() { //开始定义自己的theme ...
- ThinkPHP 3.2.3心得
个人还是蛮喜欢tp的比其他的php框架轻(只接触过drupal.tp),而且上手容易(struts这种action的方式,对于java程序员来说).目录结构也比较简单易懂,提供的一些函数也比较实用.对 ...
- drupal THEME主要文件
**.info 文件** .info 文件是一个必需的文件:Drupal 必须包括它,才干看到主题. .info 文件告诉 Drupal 主题的内部名称.比如,假设这个文件的名称是 ibmtheme. ...
- drupal module 自定义
01 <?php function mytracer_menu() { $items = array(); $items['admin/config/mytracer'] = array( 't ...
- 在CentOS 7下试验Drupal 7
按顺序安装好Apache.MariaDB和PHP,启动Apache和MariaDB,创建一个UTF-8字符集的数据库. > create database if not exists drupa ...
- Drupal常用的模块
CCK (Content Construction Kit ) : 添加字段模块 Views:生成列表 Tinymce:(Wysiwyg Editor) 常用的编辑器之一 Ajax Form Buil ...
- drupal基本知识介绍
2. Drupal 安装在安装Drupal前,你需要在服务器上先搭建一个PHP+MySQL环境.专业网站一般是安装LAMP(Linux+Apache+MySQL+PHP).环境的搭建可参考如下文章: ...
随机推荐
- 对话框上动态控件的创建、在Picture Control控件上显示图片
1 MFC对话框之上的动态控件的创建 对话框上的控件是MFC类的一个具体对象. 当在对话框之上使用静态控件时,可以根据类向导来为每个控件添加消息.响应函数以及变量. 当需要在对话框中动态的创建某个控 ...
- 禁用IE缓存
HTTP消息报头包括普通报头.请求报头.响应报头.实体报头. 普通报头中的Cache-Control用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的 ...
- python测试开发django-8.windows系统安装mysql8教程
前言 MySQL 是最流行的关系型数据库管理系统,可以在本地搭建一个mysql的环境,便于学习. windows7/windows10 mysql-8.0.11-winx64 下载安装包 mysql的 ...
- Spring Data Jpa 查询返回自定义对象
转载请注明出处:http://www.wangyongkui.com/java-jpa-query. 今天使用Jpa遇到一个问题,发现查询多个字段时返回对象不能自动转换成自定义对象.代码如下: //U ...
- Mac 在启动eclipse时 Failed to load JavaHL Library解决方法
在Mac 10.9.1系统里, 在Eclipse中安装svn的插件,出现如下提示 方法一: 1.根据提示进入链接 http://subclipse.tigris.org/wiki/JavaHL 2. ...
- 【BZOJ】【3611】【HEOI2014】大工程
虚树+树形DP 本题100W的点数……不用虚树真的好吗…… Orz ZYF 我的感悟: dp的过程跟SPOJ 1825 FTOUR2 的做法类似,依次枚举每个子树,从当前子树和之前的部分中各找一条最长 ...
- Objective-C:NSNumber类的常见用法
NSNumber基本数据类型包装类: // // main.m // 04-NSNumber // // Created by ma c on 15/8/17. // Copyright (c ...
- 删除在Godaddy注册的域名,申请退款的全过程
1,删除域名. 登录进 Godaddy ,进入域名管理(Domain Manager),点击你要删除的域名,把要删除的域名前面打上对勾,再点击“delete selected”,确认,稍等一会就删除了 ...
- 值得收藏的十二条Jquery随身笔记
1.关于页面元素的引用 通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用do ...
- 架构师书单 2nd Edition
了2007年的目标,列了下面待读或重读的书单. "其实中国程序员,现在最需要的是一张安静的书桌.",的确,中国架构师大多缺乏系统的基础知识,与其自欺欺人的宣扬"读书 ...