• 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("
    ", $patterns['admin']);
        $patterns['non_admin'] = implode("
    ", $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。

  • 相关阅读:
    libevent(十)bufferevent 2
    libevent(九)bufferevent
    maven本地库更新失败
    IDEA常用快捷键
    ELASTIC SEARCH 安装
    Hbase建模选择
    ElasticSearch关键概念
    Nginx+tomcat 负载均衡
    MapReduce (MRV1)设计理念与基本架构
    Kafka安装验证及其注意
  • 原文地址:https://www.cnblogs.com/eastson/p/3747369.html
Copyright © 2020-2023  润新知