#678714 by effulgentsia: Unify use of theme hook / template suggestions, fix clobbering problems, and improve suggestion discovery performance.
parent
5d2cdb6ba9
commit
02d2f6e04a
|
@ -719,23 +719,18 @@ function list_themes($refresh = FALSE) {
|
|||
* need to be fast, and calling the non-hook-specific preprocess and process
|
||||
* functions for them would incur a noticeable performance penalty.
|
||||
*
|
||||
* For template-implemented theme hooks, there are two special variables that
|
||||
* these preprocess and process functions can set:
|
||||
* 'template_file' and 'template_files'. These will be merged together
|
||||
* to form a list of 'suggested' alternate template files to use, in
|
||||
* reverse order of priority. template_file will always be a higher
|
||||
* priority than items in template_files. theme() will then look for these
|
||||
* files, one at a time, and use the first one that exists. If none exists,
|
||||
* theme() will use the original registered file for the theme hook.
|
||||
*
|
||||
* For function-implemented theme hooks, there are two special variables that
|
||||
* these preprocess and process functions can set:
|
||||
* 'theme_function' and 'theme_functions'. These will be merged together
|
||||
* to form a list of 'suggested' alternate functions to use, in
|
||||
* reverse order of priority. theme_function will always be a higher
|
||||
* priority than items in theme_functions. theme() will then call the
|
||||
* highest priority function that exists. If none exists, theme() will call
|
||||
* the original registered function for the theme hook.
|
||||
* There are two special variables that these preprocess and process functions
|
||||
* can set:
|
||||
* 'theme_hook_suggestion' and 'theme_hook_suggestions'. These will be merged
|
||||
* together to form a list of 'suggested' alternate hooks to use, in
|
||||
* reverse order of priority. theme_hook_suggestion will always be a higher
|
||||
* priority than items in theme_hook_suggestions. theme() will use the
|
||||
* highest priority implementation that exists. If none exists, theme() will
|
||||
* use the implementation for the theme hook it was called with. These
|
||||
* suggestions are similar to and are used for similar reasons as calling
|
||||
* theme() with an array as the $hook parameter (see below). The difference
|
||||
* is whether the suggestions are determined by the code that calls theme() or
|
||||
* by a preprocess or process function.
|
||||
*
|
||||
* @param $hook
|
||||
* The name of the theme hook to call. If the name contains a
|
||||
|
@ -840,10 +835,9 @@ function theme($hook, $variables = array()) {
|
|||
}
|
||||
|
||||
// Invoke the variable processors, if any. The processors may specify
|
||||
// alternate suggestions for which function/template should be used.
|
||||
// alternate suggestions for which hook's template/function to use.
|
||||
if (isset($info['preprocess functions']) || isset($info['process functions'])) {
|
||||
$variables['theme_functions'] = array();
|
||||
$variables['template_files'] = array();
|
||||
$variables['theme_hook_suggestions'] = array();
|
||||
foreach (array('preprocess functions', 'process functions') as $phase) {
|
||||
if (!empty($info[$phase])) {
|
||||
foreach ($info[$phase] as $processor_function) {
|
||||
|
@ -855,21 +849,28 @@ function theme($hook, $variables = array()) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Function suggestion takes priority over template suggestion.
|
||||
// theme_function takes priority over theme_functions.
|
||||
// theme_functions are in FILO order (least appropriate to most appropriate).
|
||||
// Here, just look for function suggestions. Deal with template
|
||||
// suggestions only after determining that the theme call is a template.
|
||||
// If the preprocess/process functions specified hook suggestions, and the
|
||||
// suggestion exists in the theme registry, use it instead of the hook that
|
||||
// theme() was called with. This allows the preprocess/process step to
|
||||
// route to a more specific theme hook. For example, a function may call
|
||||
// theme('node', ...), but a preprocess function can add 'node__article' as
|
||||
// a suggestion, enabling a theme to have an alternate template file for
|
||||
// article nodes. Suggestions are checked in the following order:
|
||||
// - The 'theme_hook_suggestion' variable is checked first. It overrides
|
||||
// all others.
|
||||
// - The 'theme_hook_suggestions' variable is checked in FILO order, so the
|
||||
// last suggestion added to the array takes precedence over suggestions
|
||||
// added earlier.
|
||||
$suggestions = array();
|
||||
if (!empty($variables['theme_functions'])) {
|
||||
$suggestions = $variables['theme_functions'];
|
||||
if (!empty($variables['theme_hook_suggestions'])) {
|
||||
$suggestions = $variables['theme_hook_suggestions'];
|
||||
}
|
||||
if (!empty($variables['theme_function'])) {
|
||||
$suggestions[] = $variables['theme_function'];
|
||||
if (!empty($variables['theme_hook_suggestion'])) {
|
||||
$suggestions[] = $variables['theme_hook_suggestion'];
|
||||
}
|
||||
foreach (array_reverse($suggestions) as $suggestion) {
|
||||
if (function_exists($suggestion)) {
|
||||
$info['function'] = $suggestion;
|
||||
if (isset($hooks[$suggestion])) {
|
||||
$info = $hooks[$suggestion];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -886,11 +887,9 @@ function theme($hook, $variables = array()) {
|
|||
$render_function = 'theme_render_template';
|
||||
$extension = '.tpl.php';
|
||||
|
||||
// Run through the theme engine variables, if necessary
|
||||
// The theme engine may use a different extension and a different renderer.
|
||||
global $theme_engine;
|
||||
if (isset($theme_engine)) {
|
||||
// If theme or theme engine is implementing this, it may have
|
||||
// a different extension and a different renderer.
|
||||
if ($info['type'] != 'module') {
|
||||
if (function_exists($theme_engine . '_render_template')) {
|
||||
$render_function = $theme_engine . '_render_template';
|
||||
|
@ -902,29 +901,11 @@ function theme($hook, $variables = array()) {
|
|||
}
|
||||
}
|
||||
|
||||
// Find which template file exists and can be used. Priority order is:
|
||||
// 1. $variables['template_file'].
|
||||
// 2. $variables['template_files'] in FILO order (later in array is higher
|
||||
// priority).
|
||||
// 3. $info['template'].
|
||||
$suggestions = array();
|
||||
if (isset($variables['template_files'])) {
|
||||
$suggestions = $variables['template_files'];
|
||||
// Render the output using the template file.
|
||||
$template_file = $info['template'] . $extension;
|
||||
if (isset($info['path'])) {
|
||||
$template_file = $info['path'] . '/' . $template_file;
|
||||
}
|
||||
if (isset($variables['template_file'])) {
|
||||
$suggestions[] = $variables['template_file'];
|
||||
}
|
||||
if ($suggestions) {
|
||||
$template_file = drupal_discover_template($info['theme paths'], $suggestions, $extension);
|
||||
}
|
||||
if (empty($template_file)) {
|
||||
$template_file = $info['template'] . $extension;
|
||||
if (isset($info['path'])) {
|
||||
$template_file = $info['path'] . '/' . $template_file;
|
||||
}
|
||||
}
|
||||
|
||||
// Render the output using the found template file.
|
||||
$output = $render_function($template_file, $variables);
|
||||
}
|
||||
|
||||
|
@ -933,53 +914,6 @@ function theme($hook, $variables = array()) {
|
|||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine and return which template file will generate the output.
|
||||
*
|
||||
* This helper allows the theme system to pick the template at runtime instead
|
||||
* of build time.
|
||||
*
|
||||
* @see template_page_suggestions()
|
||||
* @see template_preprocess_block()
|
||||
*
|
||||
* @param $paths
|
||||
* The paths where templates can be found. See _theme_process_registry()
|
||||
* 'theme paths' for more information.
|
||||
* @param $suggestions
|
||||
* The possible template names. These are derived from
|
||||
* $variables['template_files'] and $variables['template_file], defined by
|
||||
* preprocess functions. Each file is checked on every path in the order of
|
||||
* precedence defined by theme().
|
||||
* @return
|
||||
* The filepath to the template that will generate the output. If none is
|
||||
* found, then theme() will use the 'template' as set by
|
||||
* _theme_process_registry().
|
||||
*
|
||||
* @see _theme_process_registry()
|
||||
* @see theme()
|
||||
*/
|
||||
function drupal_discover_template($paths, $suggestions, $extension = '.tpl.php') {
|
||||
global $theme_engine;
|
||||
|
||||
// Remove slashes or null to prevent files from being included from
|
||||
// an unexpected location (especially on Windows servers).
|
||||
$extension = str_replace(array("/", "\\", "\0"), '', $extension);
|
||||
|
||||
// Loop through all paths and suggestions in FIFO order.
|
||||
$suggestions = array_reverse($suggestions);
|
||||
$paths = array_reverse($paths);
|
||||
foreach ($suggestions as $suggestion) {
|
||||
if (!empty($suggestion)) {
|
||||
$suggestion = str_replace(array("/", "\\", "\0"), '', $suggestion);
|
||||
foreach ($paths as $path) {
|
||||
if (file_exists($file = $path . '/' . $suggestion . $extension)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the path to the current themed element.
|
||||
*
|
||||
|
@ -1253,8 +1187,7 @@ function theme_get_setting($setting_name, $theme = NULL) {
|
|||
* Render a system default template, which is essentially a PHP template.
|
||||
*
|
||||
* @param $template_file
|
||||
* The filename of the template to render. Note that this will overwrite
|
||||
* anything stored in $variables['template_file'] if using a variable processor hook.
|
||||
* The filename of the template to render.
|
||||
* @param $variables
|
||||
* A keyed array of variables that will appear in the output.
|
||||
*
|
||||
|
@ -2346,7 +2279,7 @@ function template_preprocess_html(&$variables) {
|
|||
}
|
||||
|
||||
// Populate the body classes.
|
||||
if ($suggestions = template_page_suggestions(arg(), 'page')) {
|
||||
if ($suggestions = theme_get_suggestions(arg(), 'page', '-')) {
|
||||
foreach ($suggestions as $suggestion) {
|
||||
if ($suggestion != 'page-front') {
|
||||
// Add current suggestion to page classes to make it possible to theme
|
||||
|
@ -2390,8 +2323,8 @@ function template_preprocess_html(&$variables) {
|
|||
$variables['head_title'] = implode(' | ', $head_title);
|
||||
|
||||
// Populate the page template suggestions.
|
||||
if ($suggestions = template_page_suggestions(arg(), 'html')) {
|
||||
$variables['template_files'] = $suggestions;
|
||||
if ($suggestions = theme_get_suggestions(arg(), 'html')) {
|
||||
$variables['theme_hook_suggestions'] = $suggestions;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2452,8 +2385,8 @@ function template_preprocess_page(&$variables) {
|
|||
}
|
||||
|
||||
// Populate the page template suggestions.
|
||||
if ($suggestions = template_page_suggestions(arg(), 'page')) {
|
||||
$variables['template_files'] = $suggestions;
|
||||
if ($suggestions = theme_get_suggestions(arg(), 'page')) {
|
||||
$variables['theme_hook_suggestions'] = $suggestions;
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
@ -2481,26 +2414,39 @@ function template_process_html(&$variables) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Generate an array of page template suggestions.
|
||||
* Generate an array of suggestions from path arguments.
|
||||
*
|
||||
* This is typically called for adding to the 'theme_hook_suggestions' or
|
||||
* 'classes_array' variables from within preprocess functions, when wanting to
|
||||
* base the additional suggestions on the path of the current page.
|
||||
*
|
||||
* @param $args
|
||||
* An array of path arguments, such as from function arg().
|
||||
* @param $base
|
||||
* A string identifying the base 'thing' from which more specific suggestions
|
||||
* are derived. For example, 'page' or 'html'.
|
||||
* @param $delimiter
|
||||
* The string used to delimit increasingly specific information. The default
|
||||
* of '__' is appropriate for theme hook suggestions. '-' is appropriate for
|
||||
* extra classes.
|
||||
*
|
||||
* @return
|
||||
* An array of suggested template files.
|
||||
* An array of suggestions, suitable for adding to
|
||||
* $variables['theme_hook_suggestions'] within a preprocess function or to
|
||||
* $variables['classes_array'] if the suggestions represent extra CSS classes.
|
||||
*/
|
||||
function template_page_suggestions($args, $suggestion) {
|
||||
function theme_get_suggestions($args, $base, $delimiter = '__') {
|
||||
|
||||
// Build a list of suggested template files and body classes in order of
|
||||
// Build a list of suggested theme hooks or body classes in order of
|
||||
// specificity. One suggestion is made for every element of the current path,
|
||||
// though numeric elements are not carried to subsequent suggestions. For
|
||||
// example, http://www.example.com/node/1/edit would result in the following
|
||||
// suggestions and body classes:
|
||||
// example, for $base='page', http://www.example.com/node/1/edit would result
|
||||
// in the following suggestions and body classes:
|
||||
//
|
||||
// page-node-edit.tpl.php page-node-edit
|
||||
// page-node-1.tpl.php page-node-1
|
||||
// page-node.tpl.php page-node
|
||||
// page.tpl.php
|
||||
// page__node page-node
|
||||
// page__node__% page-node-%
|
||||
// page__node__1 page-node-1
|
||||
// page__node__edit page-node-edit
|
||||
|
||||
$suggestions = array();
|
||||
foreach ($args as $arg) {
|
||||
|
@ -2509,15 +2455,15 @@ function template_page_suggestions($args, $suggestion) {
|
|||
// The percent acts as a wildcard for numeric arguments since
|
||||
// asterisks are not valid filename characters on many filesystems.
|
||||
if (is_numeric($arg)) {
|
||||
$suggestions[] = $suggestion . '-%';
|
||||
$suggestions[] = $base . $delimiter . '%';
|
||||
}
|
||||
$suggestions[] = $suggestion . '-' . $arg;
|
||||
$suggestions[] = $base . $delimiter . $arg;
|
||||
if (!is_numeric($arg)) {
|
||||
$suggestion .= '-' . $arg;
|
||||
$base .= $delimiter . $arg;
|
||||
}
|
||||
}
|
||||
if (drupal_is_front_page()) {
|
||||
$suggestions[] = $suggestion . '-front';
|
||||
$suggestions[] = $base . $delimiter . 'front';
|
||||
}
|
||||
|
||||
return $suggestions;
|
||||
|
@ -2529,7 +2475,7 @@ function template_page_suggestions($args, $suggestion) {
|
|||
* invoked. It is also used in theme_install_page() and theme_update_page() to
|
||||
* keep all the variables consistent.
|
||||
*
|
||||
* An alternate template file of "maintenance-page-offline.tpl.php" can be
|
||||
* An alternate template file of "maintenance-page--offline.tpl.php" can be
|
||||
* used when the database is offline to hide errors and completely replace the
|
||||
* content.
|
||||
*
|
||||
|
@ -2617,7 +2563,7 @@ function template_preprocess_maintenance_page(&$variables) {
|
|||
// Dead databases will show error messages so supplying this template will
|
||||
// allow themers to override the page and the content completely.
|
||||
if (isset($variables['db_is_active']) && !$variables['db_is_active']) {
|
||||
$variables['template_file'] = 'maintenance-page-offline';
|
||||
$variables['theme_hook_suggestion'] = 'maintenance_page__offline';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2638,5 +2584,5 @@ function template_preprocess_region(&$variables) {
|
|||
|
||||
$region = drupal_region_class($variables['region']);
|
||||
$variables['classes_array'][] = $region;
|
||||
$variables['template_files'][] = $region;
|
||||
$variables['theme_hook_suggestions'][] = 'region__' . $region;
|
||||
}
|
||||
|
|
|
@ -871,9 +871,9 @@ function template_preprocess_block(&$variables) {
|
|||
|
||||
$variables['classes_array'][] = drupal_html_class('block-' . $variables['block']->module);
|
||||
|
||||
$variables['template_files'][] = 'block-' . $variables['block']->region;
|
||||
$variables['template_files'][] = 'block-' . $variables['block']->module;
|
||||
$variables['template_files'][] = 'block-' . $variables['block']->module . '-' . $variables['block']->delta;
|
||||
$variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->region;
|
||||
$variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->module;
|
||||
$variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->module . '__' . $variables['block']->delta;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2126,7 +2126,7 @@ function template_preprocess_comment(&$variables) {
|
|||
// Preprocess fields.
|
||||
field_attach_preprocess('comment', $comment, $variables['elements'], $variables);
|
||||
|
||||
$variables['template_files'][] = 'comment-' . $variables['node']->type;
|
||||
$variables['theme_hook_suggestions'][] = 'comment__' . $variables['node']->type;
|
||||
|
||||
// Helpful $content variable for templates.
|
||||
foreach (element_children($variables['elements']) as $key) {
|
||||
|
@ -2217,7 +2217,7 @@ function template_preprocess_comment_wrapper(&$variables) {
|
|||
// Provide contextual information.
|
||||
$variables['node'] = $variables['content']['#node'];
|
||||
$variables['display_mode'] = variable_get('comment_default_mode_' . $variables['node']->type, COMMENT_MODE_THREADED);
|
||||
$variables['template_files'][] = 'comment-wrapper-' . $variables['node']->type;
|
||||
$variables['theme_hook_suggestions'][] = 'comment_wrapper__' . $variables['node']->type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -777,11 +777,11 @@ function template_preprocess_field(&$variables) {
|
|||
'field-type-' . $field_type_css,
|
||||
'field-label-' . $element['#label_display'],
|
||||
),
|
||||
'template_files' => array(
|
||||
'theme_hook_suggestions' => array(
|
||||
'field',
|
||||
'field-' . $element['#field_name'],
|
||||
'field-' . $element['#bundle'],
|
||||
'field-' . $element['#field_name'] . '-' . $element['#bundle'],
|
||||
'field__' . $element['#field_name'],
|
||||
'field__' . $element['#bundle'],
|
||||
'field__' . $element['#field_name'] . '__' . $element['#bundle'],
|
||||
),
|
||||
);
|
||||
$variables = array_merge($variables, $additions);
|
||||
|
|
|
@ -948,17 +948,17 @@ function template_preprocess_forums(&$variables) {
|
|||
// Provide separate template suggestions based on what's being output. Topic id is also accounted for.
|
||||
// Check both variables to be safe then the inverse. Forums with topic ID's take precedence.
|
||||
if ($variables['forums'] && !$variables['topics']) {
|
||||
$variables['template_files'][] = 'forums-containers';
|
||||
$variables['template_files'][] = 'forums-' . $variables['tid'];
|
||||
$variables['template_files'][] = 'forums-containers-' . $variables['tid'];
|
||||
$variables['theme_hook_suggestions'][] = 'forums__containers';
|
||||
$variables['theme_hook_suggestions'][] = 'forums__' . $variables['tid'];
|
||||
$variables['theme_hook_suggestions'][] = 'forums__containers__' . $variables['tid'];
|
||||
}
|
||||
elseif (!$variables['forums'] && $variables['topics']) {
|
||||
$variables['template_files'][] = 'forums-topics';
|
||||
$variables['template_files'][] = 'forums-' . $variables['tid'];
|
||||
$variables['template_files'][] = 'forums-topics-' . $variables['tid'];
|
||||
$variables['theme_hook_suggestions'][] = 'forums__topics';
|
||||
$variables['theme_hook_suggestions'][] = 'forums__' . $variables['tid'];
|
||||
$variables['theme_hook_suggestions'][] = 'forums__topics__' . $variables['tid'];
|
||||
}
|
||||
else {
|
||||
$variables['template_files'][] = 'forums-' . $variables['tid'];
|
||||
$variables['theme_hook_suggestions'][] = 'forums__' . $variables['tid'];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1382,8 +1382,8 @@ function template_preprocess_node(&$variables) {
|
|||
}
|
||||
|
||||
// Clean up name so there are no underscores.
|
||||
$variables['template_files'][] = 'node-' . str_replace('_', '-', $node->type);
|
||||
$variables['template_files'][] = 'node-' . $node->nid;
|
||||
$variables['theme_hook_suggestions'][] = 'node__' . $node->type;
|
||||
$variables['theme_hook_suggestions'][] = 'node__' . $node->nid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,7 +38,7 @@ function poll_init() {
|
|||
* Implements hook_theme().
|
||||
*/
|
||||
function poll_theme() {
|
||||
return array(
|
||||
$theme_hooks = array(
|
||||
'poll_vote' => array(
|
||||
'template' => 'poll-vote',
|
||||
'render element' => 'form',
|
||||
|
@ -55,6 +55,21 @@ function poll_theme() {
|
|||
'variables' => array('title' => NULL, 'votes' => NULL, 'total_votes' => NULL, 'vote' => NULL, 'block' => NULL),
|
||||
),
|
||||
);
|
||||
// The theme system automatically discovers the theme's functions and
|
||||
// templates that implement more targeted "suggestions" of generic theme
|
||||
// hooks. But suggestions implemented by a module must be explicitly
|
||||
// registered.
|
||||
$theme_hooks += array(
|
||||
'poll_results__block' => array(
|
||||
'template' => 'poll-results--block',
|
||||
'variables' => $theme_hooks['poll_results']['variables'],
|
||||
),
|
||||
'poll_bar__block' => array(
|
||||
'template' => 'poll-bar--block',
|
||||
'variables' => $theme_hooks['poll_bar']['variables'],
|
||||
),
|
||||
);
|
||||
return $theme_hooks;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -733,9 +748,8 @@ function template_preprocess_poll_vote(&$variables) {
|
|||
$variables['vote'] = drupal_render($form['vote']);
|
||||
$variables['rest'] = drupal_render_children($form);
|
||||
$variables['block'] = $form['#block'];
|
||||
// If this is a block, allow a different tpl.php to be used.
|
||||
if ($variables['block']) {
|
||||
$variables['template_files'][] = 'poll-vote-block';
|
||||
$variables['theme_hook_suggestions'][] = 'poll_vote__block';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -833,9 +847,8 @@ function template_preprocess_poll_results(&$variables) {
|
|||
}
|
||||
$variables['title'] = check_plain($variables['raw_title']);
|
||||
|
||||
// If this is a block, allow a different tpl.php to be used.
|
||||
if ($variables['block']) {
|
||||
$variables['template_files'][] = 'poll-results-block';
|
||||
$variables['theme_hook_suggestions'][] = 'poll_results__block';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -850,7 +863,7 @@ function template_preprocess_poll_results(&$variables) {
|
|||
*/
|
||||
function template_preprocess_poll_bar(&$variables) {
|
||||
if ($variables['block']) {
|
||||
$variables['template_files'][] = 'poll-bar-block';
|
||||
$variables['theme_hook_suggestions'][] = 'poll_bar__block';
|
||||
}
|
||||
$variables['title'] = check_plain($variables['title']);
|
||||
$variables['percentage'] = round($variables['votes'] * 100 / max($variables['total_votes'], 1));
|
||||
|
|
|
@ -585,8 +585,7 @@ function template_preprocess_profile_wrapper(&$variables) {
|
|||
$variables['current_field'] = '';
|
||||
if ($field = arg(1)) {
|
||||
$variables['current_field'] = $field;
|
||||
// Supply an alternate template suggestion based on the browsable field.
|
||||
$variables['template_files'][] = 'profile-wrapper-' . $field;
|
||||
$variables['theme_hook_suggestions'][] = 'profile_wrapper__' . $field;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,8 +77,7 @@ function template_preprocess_search_results(&$variables) {
|
|||
$variables['search_results'] .= theme('search_result', array('result' => $result, 'type' => $variables['type']));
|
||||
}
|
||||
$variables['pager'] = theme('pager', array('tags' => NULL));
|
||||
// Provide alternate search results template.
|
||||
$variables['template_files'][] = 'search-results-' . $variables['type'];
|
||||
$variables['theme_hook_suggestions'][] = 'search_results__' . $variables['type'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -113,8 +112,7 @@ function template_preprocess_search_result(&$variables) {
|
|||
// Provide separated and grouped meta information..
|
||||
$variables['info_split'] = $info;
|
||||
$variables['info'] = implode(' - ', $info);
|
||||
// Provide alternate search result template.
|
||||
$variables['template_files'][] = 'search-result-' . $variables['type'];
|
||||
$variables['theme_hook_suggestions'][] = 'search_result__' . $variables['type'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,36 +19,25 @@ class TemplateUnitTest extends DrupalWebTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Test function template_page_suggestions() for SA-CORE-2009-003.
|
||||
* Test function theme_get_suggestions() for SA-CORE-2009-003.
|
||||
*/
|
||||
function testTemplateSuggestions() {
|
||||
function testThemeSuggestions() {
|
||||
// Set the front page as something random otherwise the CLI
|
||||
// test runner fails.
|
||||
variable_set('site_frontpage', 'nobody-home');
|
||||
$args = array('node', '1', 'edit');
|
||||
$suggestions = template_page_suggestions($args, 'page');
|
||||
$this->assertEqual($suggestions, array('page-node', 'page-node-%', 'page-node-1', 'page-node-edit'), t('Found expected node edit page template suggestions'));
|
||||
$suggestions = theme_get_suggestions($args, 'page');
|
||||
$this->assertEqual($suggestions, array('page__node', 'page__node__%', 'page__node__1', 'page__node__edit'), t('Found expected node edit page suggestions'));
|
||||
// Check attack vectors.
|
||||
$args = array('node', '\\1');
|
||||
$suggestions = template_page_suggestions($args, 'page');
|
||||
$this->assertEqual($suggestions, array('page-node', 'page-node-%', 'page-node-1'), t('Removed invalid \\ from template suggestions'));
|
||||
$suggestions = theme_get_suggestions($args, 'page');
|
||||
$this->assertEqual($suggestions, array('page__node', 'page__node__%', 'page__node__1'), t('Removed invalid \\ from suggestions'));
|
||||
$args = array('node', '1/');
|
||||
$suggestions = template_page_suggestions($args, 'page');
|
||||
$this->assertEqual($suggestions, array('page-node', 'page-node-%', 'page-node-1'), t('Removed invalid / from template suggestions'));
|
||||
$suggestions = theme_get_suggestions($args, 'page');
|
||||
$this->assertEqual($suggestions, array('page__node', 'page__node__%', 'page__node__1'), t('Removed invalid / from suggestions'));
|
||||
$args = array('node', "1\0");
|
||||
$suggestions = template_page_suggestions($args, 'page');
|
||||
$this->assertEqual($suggestions, array('page-node', 'page-node-%', 'page-node-1'), t('Removed invalid \\0 from template suggestions'));
|
||||
// Tests for drupal_discover_template()
|
||||
$suggestions = array('page');
|
||||
$this->assertEqual(drupal_discover_template(array('themes/garland'), $suggestions), 'themes/garland/page.tpl.php', t('Safe template discovered'));
|
||||
$suggestions = array('page');
|
||||
$this->assertEqual(drupal_discover_template(array('themes/garland'), $suggestions, '\\.tpl.php'), 'themes/garland/page.tpl.php', t('Unsafe extension fixed'));
|
||||
$suggestions = array('page\\');
|
||||
$this->assertEqual(drupal_discover_template(array('themes/garland'), $suggestions), 'themes/garland/page.tpl.php', t('Unsafe template suggestion fixed'));
|
||||
$suggestions = array('page/');
|
||||
$this->assertEqual(drupal_discover_template(array('themes/garland'), $suggestions), 'themes/garland/page.tpl.php', t('Unsafe template suggestion fixed'));
|
||||
$suggestions = array("page\0");
|
||||
$this->assertEqual(drupal_discover_template(array('themes/garland'), $suggestions), 'themes/garland/page.tpl.php', t('Unsafe template suggestion fixed'));
|
||||
$suggestions = theme_get_suggestions($args, 'page');
|
||||
$this->assertEqual($suggestions, array('page__node', 'page__node__%', 'page__node__1'), t('Removed invalid \\0 from suggestions'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue