diff options
-rw-r--r-- | includes/theme.inc | 264 | ||||
-rw-r--r-- | includes/theme.maintenance.inc | 22 | ||||
-rw-r--r-- | modules/block/block.module | 4 | ||||
-rw-r--r-- | modules/block/block.tpl.php | 12 | ||||
-rw-r--r-- | modules/comment/comment-folded.tpl.php | 20 | ||||
-rw-r--r-- | modules/comment/comment-wrapper.tpl.php | 13 | ||||
-rw-r--r-- | modules/comment/comment.module | 42 | ||||
-rw-r--r-- | modules/comment/comment.tpl.php | 21 | ||||
-rw-r--r-- | modules/field/modules/number/number.module | 4 | ||||
-rw-r--r-- | modules/field/modules/options/options.module | 12 | ||||
-rw-r--r-- | modules/field/modules/text/text.module | 8 | ||||
-rw-r--r-- | modules/node/node.module | 19 | ||||
-rw-r--r-- | modules/node/node.tpl.php | 18 | ||||
-rw-r--r-- | modules/system/maintenance-page.tpl.php | 2 | ||||
-rw-r--r-- | modules/system/page.tpl.php | 28 | ||||
-rw-r--r-- | themes/garland/block.tpl.php | 2 | ||||
-rw-r--r-- | themes/garland/comment.tpl.php | 2 | ||||
-rw-r--r-- | themes/garland/maintenance-page.tpl.php | 2 | ||||
-rw-r--r-- | themes/garland/node.tpl.php | 2 | ||||
-rw-r--r-- | themes/garland/page.tpl.php | 2 | ||||
-rw-r--r-- | themes/garland/style.css | 4 |
21 files changed, 364 insertions, 139 deletions
diff --git a/includes/theme.inc b/includes/theme.inc index 3dd681033..c5e8d91a4 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -287,6 +287,7 @@ function drupal_theme_rebuild() { * _theme_process_registry() is called for this theme hook, either the * 'path' key from hook_theme() (if defined) or $path is added. * - 'preprocess functions': See theme() for detailed documentation. + * - 'process functions': See theme() for detailed documentation. * @param $name * The name of the module, theme engine, base theme engine, theme or base * theme implementing hook_theme(). @@ -311,6 +312,14 @@ function drupal_theme_rebuild() { function _theme_process_registry(&$cache, $name, $type, $theme, $path) { $result = array(); $function = $name . '_theme'; + + // Template functions work in two distinct phases with the process + // functions always being executed after the preprocess functions. + $template_phases = array( + 'preprocess functions' => 'preprocess', + 'process functions' => 'process', + ); + if (function_exists($function)) { $result = $function($cache, $type, $theme, $path); @@ -335,87 +344,96 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) { include_once DRUPAL_ROOT . '/' . $info['path'] . '/' . $info['file']; } - if (isset($info['template']) && !isset($info['path'])) { - $result[$hook]['template'] = $path . '/' . $info['template']; - } // If 'arguments' have been defined previously, carry them forward. // This should happen if a theme overrides a Drupal defined theme // function, for example. if (!isset($info['arguments']) && isset($cache[$hook])) { $result[$hook]['arguments'] = $cache[$hook]['arguments']; } - // Likewise with theme paths. These are used for template naming suggestions. - // Theme implementations can occur in multiple paths. Suggestions should follow. - if (!isset($info['theme paths']) && isset($cache[$hook])) { - $result[$hook]['theme paths'] = $cache[$hook]['theme paths']; - } - // Check for sub-directories. - $result[$hook]['theme paths'][] = isset($info['path']) ? $info['path'] : $path; - - // Check for default _preprocess_ functions. Ensure arrayness. - if (!isset($info['preprocess functions']) || !is_array($info['preprocess functions'])) { - $info['preprocess functions'] = array(); - $prefixes = array(); - if ($type == 'module') { - // Default preprocessor prefix. - $prefixes[] = 'template'; - // Add all modules so they can intervene with their own preprocessors. This allows them - // to provide preprocess functions even if they are not the owner of the current hook. - $prefixes += module_list(); - } - elseif ($type == 'theme_engine' || $type == 'base_theme_engine') { - // Theme engines get an extra set that come before the normally named preprocessors. - $prefixes[] = $name . '_engine'; - // The theme engine also registers on behalf of the theme. The theme or engine name can be used. - $prefixes[] = $name; - $prefixes[] = $theme; - } - else { - // This applies when the theme manually registers their own preprocessors. - $prefixes[] = $name; + + // The following apply only to theming hooks implemented as templates. + if (isset($info['template'])) { + // Prepend the current theming path when none is set. + if (!isset($info['path'])) { + $result[$hook]['template'] = $path . '/' . $info['template']; } - foreach ($prefixes as $prefix) { - if (function_exists($prefix . '_preprocess')) { - $info['preprocess functions'][] = $prefix . '_preprocess'; + // These are used for template naming suggestions. Theme implementations + // can occur in multiple paths. Suggestions should follow. + if (!isset($info['theme paths']) && isset($cache[$hook])) { + $result[$hook]['theme paths'] = $cache[$hook]['theme paths']; + } + // Check for sub-directories. + $result[$hook]['theme paths'][] = isset($info['path']) ? $info['path'] : $path; + + foreach ($template_phases as $phase_key => $template_phase) { + // Check for existing variable processors. Ensure arrayness. + if (!isset($info[$phase_key]) || !is_array($info[$phase_key])) { + $info[$phase_key] = array(); + $prefixes = array(); + if ($type == 'module') { + // Default variable processor prefix. + $prefixes[] = 'template'; + // Add all modules so they can intervene with their own variable processors. This allows them + // to provide variable processors even if they are not the owner of the current hook. + $prefixes += module_list(); + } + elseif ($type == 'theme_engine' || $type == 'base_theme_engine') { + // Theme engines get an extra set that come before the normally named variable processors. + $prefixes[] = $name . '_engine'; + // The theme engine also registers on behalf of the theme. The theme or engine name can be used. + $prefixes[] = $name; + $prefixes[] = $theme; + } + else { + // This applies when the theme manually registers their own variable processors. + $prefixes[] = $name; + } + foreach ($prefixes as $prefix) { + if (function_exists($prefix . '_' . $template_phase)) { + $info[$phase_key][] = $prefix . '_' . $template_phase; + } + if (function_exists($prefix . '_' . $template_phase . '_' . $hook)) { + $info[$phase_key][] = $prefix . '_' . $template_phase . '_' . $hook; + } + } } - if (function_exists($prefix . '_preprocess_' . $hook)) { - $info['preprocess functions'][] = $prefix . '_preprocess_' . $hook; + // Check for the override flag and prevent the cached variable processors from being used. + // This allows themes or theme engines to remove variable processors set earlier in the registry build. + if (!empty($info['override ' . $phase_key])) { + // Flag not needed inside the registry. + unset($result[$hook]['override ' . $phase_key]); } + elseif (isset($cache[$hook][$phase_key]) && is_array($cache[$hook][$phase_key])) { + $info[$phase_key] = array_merge($cache[$hook][$phase_key], $info[$phase_key]); + } + $result[$hook][$phase_key] = $info[$phase_key]; } } - // Check for the override flag and prevent the cached preprocess functions from being used. - // This allows themes or theme engines to remove preprocessors set earlier in the registry build. - if (!empty($info['override preprocess functions'])) { - // Flag not needed inside the registry. - unset($result[$hook]['override preprocess functions']); - } - elseif (isset($cache[$hook]['preprocess functions']) && is_array($cache[$hook]['preprocess functions'])) { - $info['preprocess functions'] = array_merge($cache[$hook]['preprocess functions'], $info['preprocess functions']); - } - $result[$hook]['preprocess functions'] = $info['preprocess functions']; } // Merge the newly created theme hooks into the existing cache. $cache = array_merge($cache, $result); } - // Let themes have preprocess functions even if they didn't register a template. + // Let themes have variable processors even if they didn't register a template. if ($type == 'theme' || $type == 'base_theme') { foreach ($cache as $hook => $info) { // Check only if it's a template and not registered by the theme or engine. if (!empty($info['template']) && empty($result[$hook])) { - if (!isset($info['preprocess functions'])) { - $cache[$hook]['preprocess functions'] = array(); - } - if (function_exists($name . '_preprocess')) { - $cache[$hook]['preprocess functions'][] = $name . '_preprocess'; - } - if (function_exists($name . '_preprocess_' . $hook)) { - $cache[$hook]['preprocess functions'][] = $name . '_preprocess_' . $hook; + foreach ($template_phases as $phase_key => $template_phase) { + if (!isset($info[$phase_key])) { + $cache[$hook][$phase_key] = array(); + } + if (function_exists($name . '_' . $template_phase)) { + $cache[$hook][$phase_key][] = $name . '_' . $template_phase; + } + if (function_exists($name . '_' . $template_phase . '_' . $hook)) { + $cache[$hook][$phase_key][] = $name . '_' . $template_phase . '_' . $hook; + } + // Ensure uniqueness. + $cache[$hook][$phase_key] = array_unique($cache[$hook][$phase_key]); } - // Ensure uniqueness. - $cache[$hook]['preprocess functions'] = array_unique($cache[$hook]['preprocess functions']); } } } @@ -558,7 +576,8 @@ function list_themes($refresh = FALSE) { * $variables array. This array is then modified by the module implementing * the hook, theme engine (if applicable) and the theme. The following * functions may be used to modify the $variables array. They are processed in - * this order when available: + * two distinct phases; "preprocess" and "process" functions. The order it is + * listed here is the order in which it will execute. * * - template_preprocess(&$variables) * This sets a default set of variables for all template implementations. @@ -611,6 +630,57 @@ function list_themes($refresh = FALSE) { * The same applies from the previous function, but it is called for a * specific hook. * + * - template_process(&$variables) + * This sets a default set of variables for all template implementations. + * + * - template_process_HOOK(&$variables) + * This is the first processor called specific to the hook; it should be + * implemented by the module that registers it. + * + * - MODULE_process(&$variables) + * This will be called for all templates; it should only be used if there + * is a real need. It's purpose is similar to template_process(). + * + * - MODULE_process_HOOK(&$variables) + * This is for modules that want to alter or provide extra variables for + * theming hooks not registered to itself. For example, if a module named + * "foo" wanted to alter the $submitted variable for the hook "node" a + * process function of foo_process_node() can be created to intercept + * and alter the variable. + * + * - ENGINE_engine_process(&$variables) + * This function should only be implemented by theme engines and exists + * so that it can set necessary variables for all hooks. + * + * - ENGINE_engine_process_HOOK(&$variables) + * This is the same as the previous function, but it is called for a single + * theming hook. + * + * - ENGINE_process(&$variables) + * This is meant to be used by themes that utilize a theme engine. It is + * provided so that the processor is not locked into a specific theme. + * This makes it easy to share and transport code but theme authors must be + * careful to prevent fatal re-declaration errors when using sub-themes that + * have their own processor named exactly the same as its base theme. In + * the default theme engine (PHPTemplate), sub-themes will load their own + * template.php file in addition to the one used for its parent theme. This + * increases the risk for these errors. A good practice is to use the engine + * name for the base theme and the theme name for the sub-themes to minimize + * this possibility. + * + * - ENGINE_process_HOOK(&$variables) + * The same applies from the previous function, but it is called for a + * specific hook. + * + * - THEME_process(&$variables) + * These functions are based upon the raw theme; they should primarily be + * used by themes that do not use an engine or by sub-themes. It serves the + * same purpose as ENGINE_process(). + * + * - THEME_process_HOOK(&$variables) + * The same applies from the previous function, but it is called for a + * specific hook. + * * There are two special variables that these hooks can set: * 'template_file' and 'template_files'. These will be merged together * to form a list of 'suggested' alternate template files to use, in @@ -659,7 +729,7 @@ function theme() { // point path_to_theme() to the currently used theme path: $theme_path = $info['theme path']; - // Include a file if the theme function or preprocess function is held elsewhere. + // Include a file if the theme function or variable processor is held elsewhere. if (!empty($info['file'])) { $include_file = $info['file']; if (isset($info['path'])) { @@ -706,13 +776,14 @@ function theme() { } } - if (isset($info['preprocess functions']) && is_array($info['preprocess functions'])) { - // This construct ensures that we can keep a reference through - // call_user_func_array. - $args = array(&$variables, $hook); - foreach ($info['preprocess functions'] as $preprocess_function) { - if (drupal_function_exists($preprocess_function)) { - call_user_func_array($preprocess_function, $args); + // This construct ensures that we can keep a reference through + // call_user_func_array. + $args = array(&$variables, $hook); + // Template functions in two phases. + foreach (array('preprocess functions', 'process functions') as $template_phase) { + foreach ($info[$template_phase] as $template_function) { + if (drupal_function_exists($template_function)) { + call_user_func_array($template_function, $args); } } } @@ -1064,7 +1135,7 @@ function theme_get_setting($setting_name, $refresh = FALSE) { * * @param $template_file * The filename of the template to render. Note that this will overwrite - * anything stored in $variables['template_file'] if using a preprocess hook. + * anything stored in $variables['template_file'] if using a variable processor hook. * @param $variables * A keyed array of variables that will appear in the output. * @@ -1786,10 +1857,9 @@ function _theme_table_cell($cell, $header = FALSE) { } /** - * Adds a default set of helper variables for preprocess functions and - * templates. This comes in before any other preprocess function which makes - * it possible to be used in default theme implementations (non-overriden - * theme functions). + * Adds a default set of helper variables for variable processors and templates. + * This comes in before any other preprocess function which makes it possible to + * be used in default theme implementations (non-overriden theme functions). */ function template_preprocess(&$variables, $hook) { global $user; @@ -1804,6 +1874,9 @@ function template_preprocess(&$variables, $hook) { // Tell all templates where they are located. $variables['directory'] = path_to_theme(); + // Initialize html class attribute for the current hook. + $variables['classes_array'] = array($hook); + // Set default variables that depend on the database. $variables['is_admin'] = FALSE; $variables['is_front'] = FALSE; @@ -1823,6 +1896,14 @@ function template_preprocess(&$variables, $hook) { } /** + * A default process function used to alter variables as late as possible. + */ +function template_process(&$variables, $hook) { + // Flatten out classes. + $variables['classes'] = implode(' ', $variables['classes_array']); +} + +/** * Process variables for page.tpl.php * * Most themes utilize their own copy of page.tpl.php. The default is located @@ -1916,26 +1997,10 @@ function template_preprocess_page(&$variables) { // Compile a list of classes that are going to be applied to the body element. // This allows advanced theming based on context (home page, node of certain type, etc.). - $body_classes = array(); // Add a class that tells us whether we're on the front page or not. - $body_classes[] = $variables['is_front'] ? 'front' : 'not-front'; + $variables['classes_array'][] = $variables['is_front'] ? 'front' : 'not-front'; // Add a class that tells us whether the page is viewed by an authenticated user or not. - $body_classes[] = $variables['logged_in'] ? 'logged-in' : 'not-logged-in'; - - // If on an individual node page, add the node type to body classes. - if (isset($variables['node']) && $variables['node']->type) { - $body_classes[] = 'node-type-' . form_clean_id($variables['node']->type); - } - // Add information about the number of sidebars. - if ($variables['layout'] == 'both') { - $body_classes[] = 'two-sidebars'; - } - elseif ($variables['layout'] == 'none') { - $body_classes[] = 'no-sidebars'; - } - else { - $body_classes[] = 'one-sidebar sidebar-' . $variables['layout']; - } + $variables['classes_array'][] = $variables['logged_in'] ? 'logged-in' : 'not-logged-in'; // Populate the page template suggestions. if ($suggestions = template_page_suggestions(arg())) { @@ -1947,13 +2012,25 @@ function template_preprocess_page(&$variables) { // more specific data like node-12 or node-edit. To avoid illegal characters in // the class, we're removing everything disallowed. We are not using 'a-z' as // that might leave in certain international characters (e.g. German umlauts). - $body_classes[] = preg_replace('![^abcdefghijklmnopqrstuvwxyz0-9-_]+!s', '', form_clean_id(drupal_strtolower($suggestion))); + $variables['classes_array'][] = preg_replace('![^abcdefghijklmnopqrstuvwxyz0-9-_]+!s', '', form_clean_id(drupal_strtolower($suggestion))); } } } - // Implode with spaces. - $variables['body_classes'] = implode(' ', $body_classes); + // If on an individual node page, add the node type to body classes. + if (isset($variables['node']) && $variables['node']->type) { + $variables['classes_array'][] = 'node-type-' . form_clean_id($variables['node']->type); + } + // Add information about the number of sidebars. + if ($variables['layout'] == 'both') { + $variables['classes_array'][] = 'two-sidebars'; + } + elseif ($variables['layout'] == 'none') { + $variables['classes_array'][] = 'no-sidebars'; + } + else { + $variables['classes_array'][] = 'one-sidebar sidebar-' . $variables['layout']; + } } /** @@ -1994,4 +2071,3 @@ function template_page_suggestions($args) { return $suggestions; } - diff --git a/includes/theme.maintenance.inc b/includes/theme.maintenance.inc index 0dba734b5..915a5794b 100644 --- a/includes/theme.maintenance.inc +++ b/includes/theme.maintenance.inc @@ -114,8 +114,11 @@ function theme_install_page($content) { $variables['content'] = $content; // Delay setting the message variable so it can be processed below. $variables['show_messages'] = FALSE; - // The maintenance preprocess function is recycled here. + // Variable processors invoked manually since this function and theme_update_page() + // are exceptions in how it works within the theme system. + template_preprocess($variables, 'install_page'); template_preprocess_maintenance_page($variables); + template_process($variables, 'install_page'); // Special handling of error messages $messages = drupal_set_message(); @@ -167,8 +170,11 @@ function theme_update_page($content, $show_messages = TRUE) { // Assign content and show message flag. $variables['content'] = $content; $variables['show_messages'] = $show_messages; - // The maintenance preprocess function is recycled here. + // Variable processors invoked manually since this function and theme_install_page() + // are exceptions in how it works within the theme system. + template_preprocess($variables, 'update_page'); template_preprocess_maintenance_page($variables); + template_process($variables, 'update_page'); // Special handling of warning messages. $messages = drupal_set_message(); @@ -270,21 +276,19 @@ function template_preprocess_maintenance_page(&$variables) { $variables['closure'] = ''; // Compile a list of classes that are going to be applied to the body element. - $body_classes = array(); - $body_classes[] = 'in-maintenance'; + $variables['classes_array'][] = 'in-maintenance'; if (isset($variables['db_is_active']) && !$variables['db_is_active']) { - $body_classes[] = 'db-offline'; + $variables['classes_array'][] = 'db-offline'; } if ($variables['layout'] == 'both') { - $body_classes[] = 'two-sidebars'; + $variables['classes_array'][] = 'two-sidebars'; } elseif ($variables['layout'] == 'none') { - $body_classes[] = 'no-sidebars'; + $variables['classes_array'][] = 'no-sidebars'; } else { - $body_classes[] = 'one-sidebar sidebar-' . $variables['layout']; + $variables['classes_array'][] = 'one-sidebar sidebar-' . $variables['layout']; } - $variables['body_classes'] = implode(' ', $body_classes); // Dead databases will show error messages so supplying this template will // allow themers to override the page and the content completely. diff --git a/modules/block/block.module b/modules/block/block.module index 8eb78e825..18a20af22 100644 --- a/modules/block/block.module +++ b/modules/block/block.module @@ -787,7 +787,9 @@ function template_preprocess_block(&$variables) { $variables['block']->content = drupal_render($variables['block']->content); } + $variables['classes_array'][] = '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; -}
\ No newline at end of file +} diff --git a/modules/block/block.tpl.php b/modules/block/block.tpl.php index 459a94034..c89d04ef3 100644 --- a/modules/block/block.tpl.php +++ b/modules/block/block.tpl.php @@ -11,8 +11,17 @@ * - $block->module: Module that generated the block. * - $block->delta: An ID for the block, unique within each module. * - $block->region: The block region embedding the current block. + * - $classes: String of classes that can be used to style contextually through + * CSS. It can be manipulated through the variable $classes_array from + * preprocess functions. The default values can be one or more of the following: + * - block: The current template type, i.e., "theming hook". + * - block-[module]: The module generating the block. For example, the user module + * is responsible for handling the default user navigation block. In that case + * the class would be "block-user". * * Helper variables: + * - $classes_array: Array of html class attribute values. It is flattened + * into a string within the variable $classes. * - $block_zebra: Outputs 'odd' and 'even' dependent on each block region. * - $zebra: Same output as $block_zebra but independent of any block region. * - $block_id: Counter dependent on each block region. @@ -23,9 +32,10 @@ * * @see template_preprocess() * @see template_preprocess_block() + * @see template_process() */ ?> -<div id="block-<?php print $block->module . '-' . $block->delta; ?>" class="block block-<?php print $block->module ?>"> +<div id="block-<?php print $block->module . '-' . $block->delta; ?>" class="<?php print $classes; ?>"> <?php if ($block->subject): ?> <h2><?php print $block->subject ?></h2> <?php endif;?> diff --git a/modules/comment/comment-folded.tpl.php b/modules/comment/comment-folded.tpl.php index 3f52f0bbb..a582720f0 100644 --- a/modules/comment/comment-folded.tpl.php +++ b/modules/comment/comment-folded.tpl.php @@ -11,11 +11,29 @@ * - $author: Comment author. Can be link or plain text. * - $date: Date and time of posting. * - $comment: Full comment object. + * - $classes: String of classes that can be used to style contextually through + * CSS. It can be manipulated through the variable $classes_array from + * preprocess functions. The default values can be one or more of the following: + * - comment-folded: The current template type, i.e., "theming hook". + * - comment-by-anonymous: Comment by an unregistered user. + * - comment-by-node-author: Comment by the author of the parent node. + * The following applies only to viewers who are registered users: + * - comment-unpublished: An unpublished comment visible only to administrators. + * - comment-by-viewer: Comment by the user currently viewing the page. + * - comment-new: New comment since last the visit. + * + * These two variables are provided for context: + * - $comment: Full comment object. + * - $node: Node object the comments are attached to. + * + * Other variables: + * - $classes_array: Array of html class attribute values. It is flattened + * into a string within the variable $classes. * * @see template_preprocess_comment_folded() * @see theme_comment_folded() */ ?> -<div class="comment-folded"> +<div class="<?php print $classes; ?>"> <span class="subject"><?php print $title . ' ' . $new; ?></span><span class="credit"><?php print t('by') . ' ' . $author; ?></span> </div> diff --git a/modules/comment/comment-wrapper.tpl.php b/modules/comment/comment-wrapper.tpl.php index 1b19be335..99d4708d2 100644 --- a/modules/comment/comment-wrapper.tpl.php +++ b/modules/comment/comment-wrapper.tpl.php @@ -8,6 +8,10 @@ * Available variables: * - $content: All comments for a given page. Also contains comment form * if enabled. + * - $classes: String of classes that can be used to style contextually through + * CSS. It can be manipulated through the variable $classes_array from + * preprocess functions. The default value has the following: + * - comment-wrapper: The current template type, i.e., "theming hook". * * The following variables are provided for contextual information. * - $node: Node object the comments are attached to. @@ -18,14 +22,15 @@ * - COMMENT_MODE_FLAT_EXPANDED * - COMMENT_MODE_THREADED_COLLAPSED * - COMMENT_MODE_THREADED_EXPANDED - * - $display_order - * - COMMENT_ORDER_NEWEST_FIRST - * - COMMENT_ORDER_OLDEST_FIRST + * + * Other variables: + * - $classes_array: Array of html class attribute values. It is flattened + * into a string within the variable $classes. * * @see template_preprocess_comment_wrapper() * @see theme_comment_wrapper() */ ?> -<div id="comments"> +<div id="comments" class="<?php print $classes; ?>"> <?php print $content; ?> </div> diff --git a/modules/comment/comment.module b/modules/comment/comment.module index ae67b5d94..80f008450 100644 --- a/modules/comment/comment.module +++ b/modules/comment/comment.module @@ -128,7 +128,7 @@ function comment_theme() { ), 'comment_folded' => array( 'template' => 'comment-folded', - 'arguments' => array('comment' => NULL), + 'arguments' => array('comment' => NULL, 'node' => NULL), ), 'comment_flat_collapsed' => array( 'arguments' => array('comment' => NULL, 'node' => NULL), @@ -1833,7 +1833,7 @@ function theme_comment_view($comment, $node, $links = array(), $visible = TRUE) $output .= theme('comment', $comment, $node, $links); } else { - $output .= theme('comment_folded', $comment); + $output .= theme('comment_folded', $comment, $node); } return $output; @@ -1865,6 +1865,25 @@ function template_preprocess_comment(&$variables) { else { $variables['status'] = ($comment->status == COMMENT_NOT_PUBLISHED) ? 'comment-unpublished' : 'comment-published'; } + // Gather comment classes. + if ($comment->uid === 0) { + $variables['classes_array'][] = 'comment-by-anonymous'; + } + else { + // Published class is not needed. It is either 'comment-preview' or 'comment-unpublished'. + if ($variables['status'] != 'comment-published') { + $variables['classes_array'][] = $variables['status']; + } + if ($comment->uid === $variables['node']->uid) { + $variables['classes_array'][] = 'comment-by-node-author'; + } + if ($comment->uid === $variables['user']->uid) { + $variables['classes_array'][] = 'comment-by-viewer'; + } + if ($comment->new) { + $variables['classes_array'][] = 'comment-new'; + } + } } /** @@ -1879,6 +1898,25 @@ function template_preprocess_comment_folded(&$variables) { $variables['date'] = format_date($comment->timestamp); $variables['new'] = $comment->new ? t('new') : ''; $variables['title'] = l($comment->subject, comment_node_url() . '/' . $comment->cid, array('fragment' => "comment-$comment->cid")); + // Gather comment classes. + if ($comment->uid === 0) { + $variables['classes_array'][] = 'comment-by-anonymous'; + } + else { + if ($comment->status == COMMENT_NOT_PUBLISHED) { + $variables['classes_array'][] = 'comment-unpublished'; + } + if ($comment->uid === $variables['node']->uid) { + $variables['classes_array'][] = 'comment-by-node-author'; + } + if ($comment->uid === $variables['user']->uid) { + $variables['classes_array'][] = 'comment-by-viewer'; + } + if ($comment->new) { + $variables['classes_array'][] = 'comment-new'; + } + } + } /** diff --git a/modules/comment/comment.tpl.php b/modules/comment/comment.tpl.php index 7d8be3b03..07360a044 100644 --- a/modules/comment/comment.tpl.php +++ b/modules/comment/comment.tpl.php @@ -17,16 +17,33 @@ * comment-unpublished, comment-published or comment-preview. * - $submitted: By line with date and time. * - $title: Linked title. + * - $classes: String of classes that can be used to style contextually through + * CSS. It can be manipulated through the variable $classes_array from + * preprocess functions. The default values can be one or more of the following: + * - comment: The current template type, i.e., "theming hook". + * - comment-by-anonymous: Comment by an unregistered user. + * - comment-by-node-author: Comment by the author of the parent node. + * - comment-preview: When previewing a new or edited comment. + * The following applies only to viewers who are registered users: + * - comment-unpublished: An unpublished comment visible only to administrators. + * - comment-by-viewer: Comment by the user currently viewing the page. + * - comment-new: New comment since last the visit. * - * These two variables are provided for context. + * These two variables are provided for context: * - $comment: Full comment object. * - $node: Node object the comments are attached to. * + * Other variables: + * - $classes_array: Array of html class attribute values. It is flattened + * into a string within the variable $classes. + * + * @see template_preprocess() * @see template_preprocess_comment() + * @see template_process() * @see theme_comment() */ ?> -<div class="comment<?php print ($comment->new) ? ' comment-new' : ''; print ' ' . $status ?> clearfix"> +<div class="<?php print $classes; ?> clearfix"> <?php print $picture ?> <?php if ($comment->new): ?> diff --git a/modules/field/modules/number/number.module b/modules/field/modules/number/number.module index 15daaa504..108ed65f7 100644 --- a/modules/field/modules/number/number.module +++ b/modules/field/modules/number/number.module @@ -239,7 +239,7 @@ function number_elements() { 'number' => array( '#input' => TRUE, '#columns' => array('value'), '#delta' => 0, - '#process' => array('number_process'), + '#process' => array('number_elements_process'), ), ); } @@ -296,7 +296,7 @@ function number_field_widget_error($element, $error) { * * The $field and $instance arrays are in $form['#fields'][$element['#field_name']]. */ -function number_process($element, $form_state, $form) { +function number_elements_process($element, $form_state, $form) { $field_name = $element['#field_name']; $field = field_info_field($element['#field_name']); $instance = field_info_instance($element['#field_name'], $element['#bundle']); diff --git a/modules/field/modules/options/options.module b/modules/field/modules/options/options.module index 05f02d1ba..6489ebb56 100644 --- a/modules/field/modules/options/options.module +++ b/modules/field/modules/options/options.module @@ -83,17 +83,17 @@ function options_elements() { 'options_select' => array( '#input' => TRUE, '#columns' => array('value'), '#delta' => 0, - '#process' => array('options_select_process'), + '#process' => array('options_select_elements_process'), ), 'options_buttons' => array( '#input' => TRUE, '#columns' => array('value'), '#delta' => 0, - '#process' => array('options_buttons_process'), + '#process' => array('options_buttons_elements_process'), ), 'options_onoff' => array( '#input' => TRUE, '#columns' => array('value'), '#delta' => 0, - '#process' => array('options_onoff_process'), + '#process' => array('options_onoff_elements_process'), ), ); } @@ -125,7 +125,7 @@ function options_field_widget_error($element, $error) { * * The $field and $instance arrays are in $form['#fields'][$element['#field_name']]. */ -function options_buttons_process($element, &$form_state, $form) { +function options_buttons_elements_process($element, &$form_state, $form) { $field = $form['#fields'][$element['#field_name']]['field']; $instance = $form['#fields'][$element['#field_name']]['instance']; $field_key = $element['#columns'][0]; @@ -182,7 +182,7 @@ function options_buttons_process($element, &$form_state, $form) { * * The $field and $instance arrays are in $form['#fields'][$element['#field_name']]. */ -function options_select_process($element, &$form_state, $form) { +function options_select_elements_process($element, &$form_state, $form) { $field = $form['#fields'][$element['#field_name']]['field']; $instance = $form['#fields'][$element['#field_name']]['instance']; $field_key = $element['#columns'][0]; @@ -223,7 +223,7 @@ function options_select_process($element, &$form_state, $form) { * Build the form element. When creating a form using FAPI #process, * note that $element['#value'] is already set. */ -function options_onoff_process($element, &$form_state, $form) { +function options_onoff_elements_process($element, &$form_state, $form) { $field = $form['#fields'][$element['#field_name']]['field']; $instance = $form['#fields'][$element['#field_name']]['instance']; $field_key = $element['#columns'][0]; diff --git a/modules/field/modules/text/text.module b/modules/field/modules/text/text.module index 709c31185..b6eba9f12 100644 --- a/modules/field/modules/text/text.module +++ b/modules/field/modules/text/text.module @@ -238,13 +238,13 @@ function text_elements() { 'text_textfield' => array( '#input' => TRUE, '#columns' => array('value'), '#delta' => 0, - '#process' => array('text_textfield_process'), + '#process' => array('text_textfield_elements_process'), '#autocomplete_path' => FALSE, ), 'text_textarea' => array( '#input' => TRUE, '#columns' => array('value', 'format'), '#delta' => 0, - '#process' => array('text_textarea_process'), + '#process' => array('text_textarea_elements_process'), '#filter_value' => FILTER_FORMAT_DEFAULT, ), ); @@ -310,7 +310,7 @@ function text_field_widget_error($element, $error) { * information needed to adjust the behavior of the 'element' should be * extracted in hook_field_widget() above. */ -function text_textfield_process($element, $form_state, $form) { +function text_textfield_elements_process($element, $form_state, $form) { $field = $form['#fields'][$element['#field_name']]['field']; $instance = $form['#fields'][$element['#field_name']]['instance']; $field_key = $element['#columns'][0]; @@ -353,7 +353,7 @@ function text_textfield_process($element, $form_state, $form) { * * The $field and $instance arrays are in $form['#fields'][$element['#field_name']]. */ -function text_textarea_process($element, $form_state, $form) { +function text_textarea_elements_process($element, $form_state, $form) { $field = $form['#fields'][$element['#field_name']]['field']; $instance = $form['#fields'][$element['#field_name']]['instance']; $field_key = $element['#columns'][0]; diff --git a/modules/node/node.module b/modules/node/node.module index 6504aa78f..c190d2609 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -1387,6 +1387,25 @@ function template_preprocess_node(&$variables) { $variables['submitted'] = ''; $variables['picture'] = ''; } + + // Gather node classes. + $variables['classes_array'][] = 'node-' . $node->type; + if ($variables['promote']) { + $variables['classes_array'][] = 'node-promoted'; + } + if ($variables['sticky']) { + $variables['classes_array'][] = 'node-sticky'; + } + if (!$variables['status']) { + $variables['classes_array'][] = 'node-unpublished'; + } + if ($variables['teaser']) { + $variables['classes_array'][] = 'node-teaser'; + } + if (isset($variables['preview'])) { + $variables['classes_array'][] = 'node-preview'; + } + // Clean up name so there are no underscores. $variables['template_files'][] = 'node-' . str_replace('_', '-', $node->type); $variables['template_files'][] = 'node-' . $node->nid; diff --git a/modules/node/node.tpl.php b/modules/node/node.tpl.php index d2c7ec4df..92e6c128e 100644 --- a/modules/node/node.tpl.php +++ b/modules/node/node.tpl.php @@ -20,6 +20,19 @@ * - $terms: the themed list of taxonomy term links output from theme_links(). * - $submitted: themed submission information output from * theme_node_submitted(). + * - $classes: String of classes that can be used to style contextually through + * CSS. It can be manipulated through the variable $classes_array from + * preprocess functions. The default values can be one or more of the following: + * - node: The current template type, i.e., "theming hook". + * - node-[type]: The current node type. For example, if the node is a + * "Blog entry" it would result in "node-blog". Note that the machine + * name will often be in a short form of the human readable label. + * - node-teaser: Nodes in teaser form. + * - node-preview: Nodes in preview mode. + * The following are controlled through the node publishing options. + * - node-promoted: Nodes promoted to the front page. + * - node-sticky: Nodes ordered above other non-sticky nodes in teaser listings. + * - node-unpublished: Unpublished nodes visible only to administrators. * TODO D7 : document $FIELD_NAME_rendered variables. * * Other variables: @@ -28,6 +41,8 @@ * - $comment_count: Number of comments attached to the node. * - $uid: User ID of the node author. * - $created: Time the node was published formatted in Unix timestamp. + * - $classes_array: Array of html class attribute values. It is flattened + * into a string within the variable $classes. * - $zebra: Outputs either "even" or "odd". Useful for zebra striping in * teaser listings. * - $id: Position of the node. Increments each time it's output. @@ -47,9 +62,10 @@ * * @see template_preprocess() * @see template_preprocess_node() + * @see template_process() */ ?> -<div id="node-<?php print $node->nid; ?>" class="node<?php if ($sticky) { print ' sticky'; } ?><?php if (!$status) { print ' node-unpublished'; } ?> clearfix"> +<div id="node-<?php print $node->nid; ?>" class="<?php print $classes ?> clearfix"> <?php print $picture ?> diff --git a/modules/system/maintenance-page.tpl.php b/modules/system/maintenance-page.tpl.php index 41ab3f13d..e411afd11 100644 --- a/modules/system/maintenance-page.tpl.php +++ b/modules/system/maintenance-page.tpl.php @@ -23,7 +23,7 @@ <?php print $scripts; ?> <script type="text/javascript"><?php /* Needed to avoid Flash of Unstyled Content in IE */ ?> </script> </head> -<body class="<?php print $body_classes; ?>"> +<body class="<?php print $classes; ?>"> <div id="page"> <div id="header"> <div id="logo-title"> diff --git a/modules/system/page.tpl.php b/modules/system/page.tpl.php index 7c4fff9d6..e55789a9a 100644 --- a/modules/system/page.tpl.php +++ b/modules/system/page.tpl.php @@ -13,6 +13,8 @@ * - $css: An array of CSS files for the current page. * - $directory: The directory the template is located in, e.g. modules/system * or themes/garland. + * - $classes_array: Array of html class attribute values. It is flattened + * into a string within the variable $classes. * - $is_front: TRUE if the current page is the front page. Used to toggle the mission statement. * - $logged_in: TRUE if the user is registered and signed in. * - $is_admin: TRUE if the user has permission to access administration pages. @@ -29,9 +31,26 @@ * - $styles: Style tags necessary to import all CSS files for the page. * - $scripts: Script tags necessary to load the JavaScript files and settings * for the page. - * - $body_classes: A set of CSS classes for the BODY tag. This contains flags - * indicating the current layout (multiple columns, single column), the current - * path, whether the user is logged in, and so on. + * - $classes: String of classes that can be used to style contextually through + * CSS. It should be placed within the <body> tag. When selecting through CSS + * it's recommended that you use the body tag, e.g., "body.front". It can be + * manipulated through the variable $classes_array from preprocess functions. + * The default values can be one or more of the following: + * - page: The current template type, i.e., "theming hook". + * - front: Page is the home page. + * - not-front: Page is not the home page. + * - logged-in: The current viewer is logged in. + * - not-logged-in: The current viewer is not logged in. + * - page-[level 1 path]: The internal first level path. For example, viewing + * example.com/user/2 would result in "page-user". Path aliases do not apply. + * - node-type-[node type]: When viewing a single node, the type of that node. + * For example, if the node is a "Blog entry" it would result in "node-type-blog". + * Note that the machine name will often be in a short form of the human readable label. + * The following only apply with the default 'left' and 'right' block regions: + * - two-sidebars: When both sidebars have content. + * - no-sidebars: When no sidebar content exists. + * - one-sidebar and sidebar-left or sidebar-right: A combination of the two classes + * when only one of the two sidebars have content. * * Site identity: * - $front_page: The URL of the front page. Use this instead of $base_path, @@ -69,6 +88,7 @@ * * @see template_preprocess() * @see template_preprocess_page() + * @see template_process() */ ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" @@ -82,7 +102,7 @@ <?php print $styles; ?> <?php print $scripts; ?> </head> -<body class="<?php print $body_classes; ?>"> +<body class="<?php print $classes; ?>"> <div id="page-wrapper"><div id="page"> diff --git a/themes/garland/block.tpl.php b/themes/garland/block.tpl.php index a14afe4d6..730b2d4b2 100644 --- a/themes/garland/block.tpl.php +++ b/themes/garland/block.tpl.php @@ -1,7 +1,7 @@ <?php // $Id$ ?> -<div id="block-<?php print $block->module . '-' . $block->delta; ?>" class="clearfix block block-<?php print $block->module ?>"> +<div id="block-<?php print $block->module . '-' . $block->delta; ?>" class="<?php print $classes; ?> clearfix"> <?php if (!empty($block->subject)): ?> <h2><?php print $block->subject ?></h2> diff --git a/themes/garland/comment.tpl.php b/themes/garland/comment.tpl.php index 3f96b1e2d..e2edf0dc0 100644 --- a/themes/garland/comment.tpl.php +++ b/themes/garland/comment.tpl.php @@ -1,7 +1,7 @@ <?php // $Id$ ?> -<div class="comment<?php print ($comment->new) ? ' comment-new' : ''; print ' ' . $status; print ' ' . $zebra; ?>"> +<div class="<?php print $classes . ' ' . $zebra; ?>"> <div class="clearfix"> <?php if ($submitted): ?> diff --git a/themes/garland/maintenance-page.tpl.php b/themes/garland/maintenance-page.tpl.php index 5a86d1e65..74dc026cd 100644 --- a/themes/garland/maintenance-page.tpl.php +++ b/themes/garland/maintenance-page.tpl.php @@ -24,7 +24,7 @@ <?php print garland_get_ie_styles(); ?> <![endif]--> </head> - <body class="<?php print $body_classes ?>"> + <body class="<?php print $classes ?>"> <!-- Layout --> <div id="header-region" class="clearfix"><?php print $header; ?></div> diff --git a/themes/garland/node.tpl.php b/themes/garland/node.tpl.php index 993a0fe6f..919f9a5d1 100644 --- a/themes/garland/node.tpl.php +++ b/themes/garland/node.tpl.php @@ -1,7 +1,7 @@ <?php // $Id$ ?> -<div id="node-<?php print $node->nid; ?>" class="node<?php if ($sticky) { print ' sticky'; } ?><?php if (!$status) { print ' node-unpublished'; } ?>"> +<div id="node-<?php print $node->nid; ?>" class="<?php print $classes ?>"> <?php print $picture ?> diff --git a/themes/garland/page.tpl.php b/themes/garland/page.tpl.php index feda682ca..782532ad3 100644 --- a/themes/garland/page.tpl.php +++ b/themes/garland/page.tpl.php @@ -13,7 +13,7 @@ <?php print $ie_styles ?> <![endif]--> </head> - <body class="<?php print $body_classes ?>"> + <body class="<?php print $classes ?>"> <div id="header-region" class="clearfix"><?php print $header ?></div> diff --git a/themes/garland/style.css b/themes/garland/style.css index 0085cdbd4..a4ad47f50 100644 --- a/themes/garland/style.css +++ b/themes/garland/style.css @@ -690,14 +690,14 @@ ul.links li, ul.inline li { float: right; /* LTR */ } -.preview .node, .preview .comment, .sticky { +.preview .node, .preview .comment, .node-sticky { margin: 0; padding: 0.5em 0; border: 0; background: 0; } -.sticky { +.node-sticky { padding: 1em; background-color: #fff; border: 1px solid #e0e5fb; |