diff --git a/includes/module.inc b/includes/module.inc index 2e25108..a068569 100644 --- a/includes/module.inc +++ b/includes/module.inc @@ -193,8 +193,11 @@ function system_list($type) { 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'; + // Add the base theme's theme engine info only when subtheme does not + // define one, this allows to use different theme engines. + if (!isset($lists['theme'][$key]->info['engine'])) { + $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. diff --git a/includes/theme.inc b/includes/theme.inc index 9b606e9..05ea943 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -139,7 +139,7 @@ function drupal_theme_initialize() { * The callback to invoke to set the theme registry. */ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callback = '_theme_load_registry') { - global $theme_info, $base_theme_info, $theme_engine, $theme_path; + global $theme_info, $base_theme_info, $theme_path; $theme_info = $theme; $base_theme_info = $base_theme; @@ -201,37 +201,28 @@ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callb drupal_add_js($script, array('group' => JS_THEME, 'every_page' => TRUE)); } - $theme_engine = NULL; - - // Initialize the theme. - if (isset($theme->engine)) { - // Include the engine. - include_once DRUPAL_ROOT . '/' . $theme->owner; + // Initialize all themes and engines. + // Make sure we do not load the same theme engine twice. + $theme_init = array(); + foreach (list_themes() as $current) { + $key = $current->owner . ' ' . $current->engine; + if (isset($theme_init[$key])) { + continue; + } - $theme_engine = $theme->engine; - if (function_exists($theme_engine . '_init')) { - foreach ($base_theme as $base) { - call_user_func($theme_engine . '_init', $base); - } - call_user_func($theme_engine . '_init', $theme); + if (isset($current->owner)) { + include_once DRUPAL_ROOT . '/' . $current->owner; } - } - else { - // include non-engine theme files - foreach ($base_theme as $base) { - // Include the theme file or the engine. - if (!empty($base->owner)) { - include_once DRUPAL_ROOT . '/' . $base->owner; + if (isset($current->engine)) { + if (function_exists($current->engine . '_init')) { + call_user_func($current->engine . '_init', $current); } } - // and our theme gets one too. - if (!empty($theme->owner)) { - include_once DRUPAL_ROOT . '/' . $theme->owner; - } + $theme_init[$key] = $current; } if (isset($registry_callback)) { - _theme_registry_callback($registry_callback, array($theme, $base_theme, $theme_engine)); + _theme_registry_callback($registry_callback, array($theme, $base_theme)); } } @@ -304,8 +295,6 @@ function _theme_registry_callback($callback = NULL, array $arguments = array()) * @param $base_theme * An array of loaded $theme objects representing the ancestor themes in * oldest first order. - * @param $theme_engine - * The name of the theme engine. * @param $complete * Whether to load the complete theme registry or an instance of the * ThemeRegistry class. @@ -313,7 +302,7 @@ function _theme_registry_callback($callback = NULL, array $arguments = array()) * @return * The theme registry array, or an instance of the ThemeRegistry class. */ -function _theme_load_registry($theme, $base_theme = NULL, $theme_engine = NULL, $complete = TRUE) { +function _theme_load_registry($theme, $base_theme = NULL, $complete = TRUE) { if ($complete) { // Check the theme registry cache; if it exists, use it. $cached = cache_get("theme_registry:$theme->name"); @@ -322,7 +311,7 @@ function _theme_load_registry($theme, $base_theme = NULL, $theme_engine = NULL, } else { // If not, build one and cache it. - $registry = _theme_build_registry($theme, $base_theme, $theme_engine); + $registry = _theme_build_registry($theme, $base_theme); // Only persist this registry if all modules are loaded. This assures a // complete set of theme hooks. if (module_load_all(NULL)) { @@ -672,10 +661,8 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) { * @param $base_theme * An array of loaded $theme objects representing the ancestor themes in * oldest first order. - * @param $theme_engine - * The name of the theme engine. */ -function _theme_build_registry($theme, $base_theme, $theme_engine) { +function _theme_build_registry($theme, $base_theme) { $cache = array(); // First, process the theme hooks advertised by modules. This will // serve as the basic registry. Since the list of enabled modules is the same @@ -698,15 +685,15 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) { foreach ($base_theme as $base) { // If the base theme uses a theme engine, process its hooks. $base_path = dirname($base->filename); - if ($theme_engine) { - _theme_process_registry($cache, $theme_engine, 'base_theme_engine', $base->name, $base_path); + if (isset($base->engine)) { + _theme_process_registry($cache, $base->engine, 'base_theme_engine', $base->name, $base_path); } _theme_process_registry($cache, $base->name, 'base_theme', $base->name, $base_path); } // And then the same thing, but for the theme. - if ($theme_engine) { - _theme_process_registry($cache, $theme_engine, 'theme_engine', $theme->name, dirname($theme->filename)); + if (isset($theme->engine)) { + _theme_process_registry($cache, $theme->engine, 'theme_engine', $theme->name, dirname($theme->filename)); } // Finally, hooks provided by the theme itself. @@ -1167,8 +1154,8 @@ function theme($hook, $variables = array()) { $extension = '.tpl.php'; // The theme engine may use a different extension and a different renderer. - global $theme_engine; - if (isset($theme_engine)) { + if (isset($info['engine'])) { + $theme_engine = $info['engine']; if ($info['type'] != 'module') { if (function_exists($theme_engine . '_render_template')) { $render_function = $theme_engine . '_render_template'; @@ -1309,10 +1296,21 @@ function drupal_find_theme_templates($cache, $extension, $path) { // used for filtering. This allows base themes to have sub-themes in its // folder hierarchy without affecting the base themes template discovery. $theme_paths = array(); - foreach (list_themes() as $theme_info) { + $current_theme = NULL; + $current_engine = NULL; + foreach (list_themes() as $key => $theme_info) { if (!empty($theme_info->base_theme)) { $theme_paths[$theme_info->base_theme][$theme_info->name] = dirname($theme_info->filename); } + $theme_path = dirname($theme_info->filename); + if ($path === $theme_path) { + $current_theme = $current_theme; + $current_engine = isset($theme_info->engine) ? $theme_info->engine : NULL; + } + else if (!$current_theme && 0 === strpos($theme_path, $current_theme)) { + $current_theme = $current_theme; + $current_engine = isset($theme_info->engine) ? $theme_info->engine : NULL; + } } foreach ($theme_paths as $basetheme => $subthemes) { foreach ($subthemes as $subtheme => $subtheme_path) { @@ -1349,6 +1347,7 @@ function drupal_find_theme_templates($cache, $extension, $path) { if (isset($cache[$hook])) { $implementations[$hook] = array( 'template' => $template, + 'engine' => $current_engine, 'path' => dirname($file->uri), ); } @@ -1375,6 +1374,7 @@ function drupal_find_theme_templates($cache, $extension, $path) { $arg_name = isset($info['variables']) ? 'variables' : 'render element'; $implementations[strtr($file, '-', '_')] = array( 'template' => $file, + 'engine' => $current_engine, 'path' => dirname($files[$match]->uri), $arg_name => $info[$arg_name], 'base hook' => $hook, diff --git a/includes/theme.maintenance.inc b/includes/theme.maintenance.inc index 6baf219..df8d446 100644 --- a/includes/theme.maintenance.inc +++ b/includes/theme.maintenance.inc @@ -87,8 +87,8 @@ function _drupal_maintenance_theme() { /** * Builds the registry when the site needs to bypass any database calls. */ -function _theme_load_offline_registry($theme, $base_theme = NULL, $theme_engine = NULL) { - return _theme_build_registry($theme, $base_theme, $theme_engine); +function _theme_load_offline_registry($theme, $base_theme = NULL) { + return _theme_build_registry($theme, $base_theme); } /** diff --git a/modules/system/system.module b/modules/system/system.module index 59087c8..c988f3b 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -2606,12 +2606,12 @@ function _system_rebuild_theme_data() { $themes[$base_theme]->sub_themes[$key] = $themes[$key]->info['name']; } // Copy the 'owner' and 'engine' over if the top level theme uses a theme - // engine. - if (isset($themes[$base_key]->owner)) { + // engine and the current theme has no engine itself. + if (isset($themes[$base_key]->owner) && !isset($themes[$key]->owner)) { if (isset($themes[$base_key]->info['engine'])) { - $themes[$key]->info['engine'] = $themes[$base_key]->info['engine']; - $themes[$key]->owner = $themes[$base_key]->owner; - $themes[$key]->prefix = $themes[$base_key]->prefix; + $themes[$key]->info['engine'] = $themes[$base_key]->info['engine']; + $themes[$key]->owner = $themes[$base_key]->owner; + $themes[$key]->prefix = $themes[$base_key]->prefix; } else { $themes[$key]->prefix = $key;