zoukankan      html  css  js  c++  java
  • 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'];
  • 相关阅读:
    pip源配置
    Linux:supervisor命令的使用
    uWSGI+Nginx+Flask在Linux下的部署
    MongoDB的使用[转]
    用python获取服务器硬件信息[转]
    python:virtualenv的使用
    Django笔记:常见故障排除
    常用资源网站链接
    Scrapy笔记:持久化,Feed exports的使用
    Scrapy笔记:使用代理ip
  • 原文地址:https://www.cnblogs.com/eastson/p/3372119.html
Copyright © 2011-2022 走看看