diff options
author | Dries Buytaert <dries@buytaert.net> | 2007-07-03 18:48:41 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2007-07-03 18:48:41 +0000 |
commit | 435f3154f9c347f35a4685d6456b9aded4171bc2 (patch) | |
tree | 2b12de72d697709b9904765313a242e1a71ba162 | |
parent | b5cdf535f4a233cd4156e6c091e6aa1f3f28800a (diff) | |
download | brdo-435f3154f9c347f35a4685d6456b9aded4171bc2.tar.gz brdo-435f3154f9c347f35a4685d6456b9aded4171bc2.tar.bz2 |
- Patch #141730 by Earl: allow theming system to use wildcards. I promised in the issue that this patch would still go in, so here goes.
-rw-r--r-- | CHANGELOG.txt | 1 | ||||
-rw-r--r-- | includes/theme.inc | 125 | ||||
-rw-r--r-- | themes/chameleon/chameleon.theme | 11 | ||||
-rw-r--r-- | themes/engines/phptemplate/phptemplate.engine | 32 |
4 files changed, 127 insertions, 42 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 6674295e8..f512f69ee 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -62,7 +62,6 @@ Drupal 6.0, xxxx-xx-xx (development version) - Added support for OpenID. - Added support for configurable actions. - Made user profiles easier to theme by using array rendering and supplying template files. -- Added Deletion API to allow modules to alter and respond to any delete operation. Drupal 5.0, 2007-01-15 ---------------------- diff --git a/includes/theme.inc b/includes/theme.inc index e8c0a8832..d53f4d840 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -416,24 +416,31 @@ function list_theme_engines($refresh = FALSE) { * This function should only be implemented by theme engines and exists * so that the theme engine can set necessary variables. It is commonly * used to set global variables such as $directory and $is_front_page. + * * ENGINE_engine_preprocess_HOOK(&$variables) * This is the same as the previous function, but is called only per hook. + * * ENGINE_preprocess_HOOK(&$variables) + * * ENGINE_preprocess(&$variables) * This is meant to be used by themes that utilize a theme engine; as it is * good practice for these themes to use the theme engine's name for * their functions so that they may share code. In PHPTemplate, these * functions will appear in template.php + * * THEME_preprocess_HOOK(&$variables) + * * THEME_preprocess(&$variables) * These functions are based upon the raw theme; they should primarily be * used by themes that do not use an engine or by themes that need small * changes to what has already been established in the theme engine version * of the function. + * * template_preprocess(&$variables) * This function will only be called for theme functions registered by * the named module. In general it is preferred to use the following * function if possible, but it may not always be the case. + * * template_preprocess_HOOK(&$variables) * This is the same as the previous function, but is called only per hook. * @@ -445,7 +452,12 @@ function list_theme_engines($refresh = FALSE) { * files, one at a time, and use the first one * that exists. * @param $hook - * The name of the theme function to call. + * The name of the theme function to call. May be an array, in which + * case the first hook that actually has an implementation registered + * will be used. This can be used to choose 'fallback' theme implementations, + * so that if the specific theme hook isn't implemented anywhere, a more + * generic one will be used. This can allow themes to create specific theme + * implementations for named objects. * @param ... * Additional arguments to pass along to the theme function. * @return @@ -461,6 +473,15 @@ function theme() { $hooks = theme_get_registry(); } + if (is_array($hook)) { + foreach ($hook as $candidate) { + if (isset($hooks[$candidate])) { + break; + } + } + $hook = $candidate; + } + if (!isset($hooks[$hook])) { return; } @@ -587,6 +608,100 @@ function path_to_theme() { } /** + * Find overridden theme functions. Called by themes and/or theme engines to + * easily discover theme functions. + * + * @param $cache + * The existing cache of theme hooks to test against. + * @param $prefixes + * An array of prefixes to test, in reverse order of importance. + * + * @return $templates + * The functions found, suitable for returning from hook_theme; + */ +function drupal_find_theme_functions($cache, $prefixes) { + $templates = array(); + $functions = get_defined_functions(); + + foreach ($cache as $hook => $info) { + foreach ($prefixes as $prefix) { + if (!empty($info['pattern'])) { + $matches = preg_grep('/^'. $prefix .'_'. $info['pattern'] .'/', $functions['user']); + if ($matches) { + foreach ($matches as $match) { + $new_hook = str_replace($prefix . '_', '', $match); + $templates[$new_hook] = array( + 'function' => $match, + 'arguments' => $info['arguments'], + ); + } + } + } + if (function_exists($prefix .'_'. $hook)) { + $templates[$hook] = array( + 'function' => $prefix .'_'. $hook, + ); + } + } + } + + return $templates; +} + +/** + * Find overridden theme templates. Called by themes and/or theme engines to + * easily discover templates. + * + * @param $cache + * The existing cache of theme hooks to test against. + * @param $extension + * The extension that these templates will have. + * @param $path + * The path to search. + */ +function drupal_find_theme_templates($cache, $extension, $path) { + $templates = array(); + + // Escape the dots in the extension. + $regex = str_replace('.', '\.', $extension) . '$'; + + // Because drupal_system_listing works the way it does, we check for real + // templates separately from checking for patterns. + $files = drupal_system_listing($regex, $path, 'name', 0); + foreach ($files as $template => $file) { + // Chop off the extension. We do it this way because $template will + // have one extension chopped off, but there might be more than one, + // such as with .tpl.php + $template = substr($template, 0, strpos($template, '.')); + if (isset($cache[$template])) { + $templates[$template] = array( + 'file' => $template, + 'path' => dirname($file->filename), + ); + } + } + + $patterns = array_keys($files); + + foreach ($cache as $hook => $info) { + if (!empty($info['pattern'])) { + $matches = preg_grep('/^'. $info['pattern'] .'/', $patterns); + if ($matches) { + foreach ($matches as $match) { + $file = substr($match, 0, strpos($match, '.')); + $templates[$file] = array( + 'file' => $file, + 'path' => dirname($files[$match]->filename), + 'arguments' => $info['arguments'], + ); + } + } + } + } + return $templates; +} + +/** * Retrieve an associative array containing the settings for a theme. * * The final settings are arrived at by merging the default settings, @@ -736,6 +851,14 @@ function theme_render_template($file, $variables) { * Inside Drupal, the theme layer is utilized by the use of the theme() * function, which is passed the name of a component (the theme hook) * and several arguments. For example, theme('table', $header, $rows); + * Additionally, the theme() function can take an array of theme + * hooks, which can be used to provide 'fallback' implementations to + * allow for more specific control of output. For example, the function: + * theme(array('table__foo', 'table), $header, $rows) would look to see if + * 'table__foo' is registered anywhere; if it is not, it would 'fall back' + * to the generic 'table' implementation. This can be used to attach specific + * theme functions to named objects, allowing the themer more control over + * specific types of output. * * As of Drupal 6, every theme hook is required to be registered by the * module that owns it, so that Drupal can tell what to do with it and diff --git a/themes/chameleon/chameleon.theme b/themes/chameleon/chameleon.theme index 7433ed8ef..7ba6d71f8 100644 --- a/themes/chameleon/chameleon.theme +++ b/themes/chameleon/chameleon.theme @@ -10,16 +10,7 @@ * Implementation of hook_theme. Auto-discover theme functions. */ function chameleon_theme($existing, $type, $theme, $path) { - $templates = array(); - // Check for function overrides. - foreach ($existing as $hook => $info) { - if (function_exists($theme .'_'. $hook)) { - $templates[$hook] = array( - 'function' => $theme .'_'. $hook, - ); - } - } - return $templates; + return drupal_find_theme_functions($existing, array($theme)); } function chameleon_page($content, $show_blocks = TRUE, $show_messages = TRUE) { diff --git a/themes/engines/phptemplate/phptemplate.engine b/themes/engines/phptemplate/phptemplate.engine index 4e9c065af..48f620838 100644 --- a/themes/engines/phptemplate/phptemplate.engine +++ b/themes/engines/phptemplate/phptemplate.engine @@ -20,36 +20,8 @@ function phptemplate_init($template) { * we need to. */ function phptemplate_theme($existing, $type, $theme, $path) { - $templates = array(); - - // Check for template overrides. - $files = drupal_system_listing('\.tpl\.php$', $path, 'name', 0); - - foreach ($files as $template => $file) { - // chop off the .tpl - $template = substr($template, 0, -4); - if (isset($existing[$template])) { - $templates[$template] = array( - 'file' => $template, - 'path' => dirname($file->filename), - ); - } - } - - // Check for function overrides. - foreach ($existing as $hook => $info) { - if (function_exists($theme .'_'. $hook)) { - $templates[$hook] = array( - 'function' => $theme .'_'. $hook, - ); - } - else if (function_exists('phptemplate_'. $hook)) { - $templates[$hook] = array( - 'function' => 'phptemplate_'. $hook, - ); - } - } - + $templates = drupal_find_theme_functions($existing, array('phptemplate', $theme)); + $templates += drupal_find_theme_templates($existing, '.tpl.php', $path); return $templates; } |