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 /includes | |
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.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/theme.inc | 125 |
1 files changed, 124 insertions, 1 deletions
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 |