Index: includes/theme.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/theme.inc,v retrieving revision 1.622 diff -u -p -r1.622 theme.inc --- includes/theme.inc 30 Oct 2010 03:57:20 -0000 1.622 +++ includes/theme.inc 16 Nov 2010 23:13:16 -0000 @@ -758,6 +758,7 @@ function theme($hook, $variables = array break; } } + $suggestions = $hook; $hook = $candidate; } @@ -767,6 +768,7 @@ function theme($hook, $variables = array // Iteratively strip everything after the last '__' delimiter, until an // implementation is found. while ($pos = strrpos($hook, '__')) { + $suggestions[] = $hook; $hook = substr($hook, 0, $pos); if (isset($hooks[$hook])) { break; @@ -829,13 +831,34 @@ function theme($hook, $variables = array $base_hook = $info['base hook']; $base_hook_info = $hooks[$base_hook]; if (isset($base_hook_info['preprocess functions']) || isset($base_hook_info['process functions'])) { + // Retain the requested suggestion as the highest priority one, even if + // the base hook's preprocess functions add to the + // 'theme_hook_suggestions' array. $variables['theme_hook_suggestion'] = $hook; + + // Enable the base hook's preprocess functions to know all implicit + // suggestions requested by the calling context. For base theme hooks that + // use the default pattern of '__' to delimit suggestions, include all + // implicit intermediary suggestions. For example, for + // 'links__node__comment', ensure that 'link__node' is added as an + // implicit suggestion. + if ((!isset($base_hook_info['pattern']) || $base_hook_info['pattern'] == ($base_hook . '__')) && (strpos($hook, $base_hook . '__') === 0)) { + while ($hook != $base_hook && $pos = strrpos($hook, '__')) { + $suggestions[] = $hook; + $hook = substr($hook, 0, $pos); + } + } + elseif ($hook != $base_hook) { + $suggestions[] = $hook; + } + $hook = $base_hook; $info = $base_hook_info; } } if (isset($info['preprocess functions']) || isset($info['process functions'])) { - $variables['theme_hook_suggestions'] = array(); + // 'theme_hook_suggestions' is defined to be in FILO order (see below). + $variables['theme_hook_suggestions'] = isset($suggestions) ? array_reverse($suggestions) : array(); foreach (array('preprocess functions', 'process functions') as $phase) { if (!empty($info[$phase])) { foreach ($info[$phase] as $processor_function) {