6 * Contains theme override functions and preprocess functions for the Zen theme.
8 * IMPORTANT WARNING: DO NOT MODIFY THIS FILE.
10 * The base Zen theme is designed to be easily extended by its sub-themes. You
11 * shouldn't modify this or any of the CSS or PHP files in the root zen/ folder.
12 * See the online documentation for more information:
13 * http://drupal.org/node/193318
16 // Auto-rebuild the theme registry during theme development.
17 if (theme_get_setting('zen_rebuild_registry')) {
18 drupal_rebuild_theme_registry();
22 * Add stylesheets only needed when Zen is the active theme. Don't do something
23 * this dumb in your sub-theme; see how wireframes.css is handled instead.
25 if ($GLOBALS['theme'] == 'zen') { // If we're in the main theme
26 if (theme_get_setting('zen_layout') == 'border-politics-fixed') {
27 drupal_add_css(drupal_get_path('theme', 'zen') .
'/layout-fixed.css', 'theme', 'all');
30 drupal_add_css(drupal_get_path('theme', 'zen') .
'/layout-liquid.css', 'theme', 'all');
35 * Implements HOOK_theme().
37 function zen_theme(&$existing, $type, $theme, $path) {
38 include_once
'./' .
drupal_get_path('theme', 'zen') .
'/template.theme-registry.inc';
39 return _zen_theme($existing, $type, $theme, $path);
43 * Return a themed breadcrumb trail.
46 * An array containing the breadcrumb links.
48 * A string containing the breadcrumb output.
50 function zen_breadcrumb($breadcrumb) {
51 // Determine if we are to display the breadcrumb
52 $show_breadcrumb = theme_get_setting('zen_breadcrumb');
53 if ($show_breadcrumb == 'yes' || $show_breadcrumb == 'admin' && arg(0) == 'admin') {
55 // Optionally get rid of the homepage link
56 $show_breadcrumb_home = theme_get_setting('zen_breadcrumb_home');
57 if (!$show_breadcrumb_home) {
58 array_shift($breadcrumb);
61 // Return the breadcrumb with separators
62 if (!empty($breadcrumb)) {
63 $breadcrumb_separator = theme_get_setting('zen_breadcrumb_separator');
64 $trailing_separator = (theme_get_setting('zen_breadcrumb_trailing') || theme_get_setting('zen_breadcrumb_title')) ?
$breadcrumb_separator : '';
65 return '<div class="breadcrumb">' .
implode($breadcrumb_separator, $breadcrumb) .
"$trailing_separator</div>";
68 // Otherwise, return an empty string
73 * Implements theme_menu_item_link()
75 function zen_menu_item_link($link) {
76 if (empty($link['localized_options'])) {
77 $link['localized_options'] = array();
80 // If an item is a LOCAL TASK, render it as a tab
81 if ($link['type'] & MENU_IS_LOCAL_TASK
) {
82 $link['title'] = '<span class="tab">' .
check_plain($link['title']) .
'</span>';
83 $link['localized_options']['html'] = TRUE
;
86 return l($link['title'], $link['href'], $link['localized_options']);
90 * Duplicate of theme_menu_local_tasks() but adds clear-block to tabs.
92 function zen_menu_local_tasks() {
95 if ($primary = menu_primary_local_tasks()) {
96 $output .
= '<ul class="tabs primary clear-block">' .
$primary .
'</ul>';
98 if ($secondary = menu_secondary_local_tasks()) {
99 $output .
= '<ul class="tabs secondary clear-block">' .
$secondary .
'</ul>';
107 * Override or insert variables into the page templates.
110 * An array of variables to pass to the theme template.
112 * The name of the template being rendered ("page" in this case.)
114 function zen_preprocess_page(&$vars, $hook) {
115 // Add an optional title to the end of the breadcrumb.
116 if (theme_get_setting('zen_breadcrumb_title') && $vars['breadcrumb']) {
117 $vars['breadcrumb'] = substr($vars['breadcrumb'], 0, -6) .
$vars['title'] .
'</div>';
120 // Add conditional stylesheets.
121 if (!module_exists('conditional_styles')) {
122 $vars['styles'] .
= $vars['conditional_styles'] = variable_get('conditional_styles_' .
$GLOBALS['theme'], '');
125 // Classes for body element. Allows advanced theming based on context
126 // (home page, node of certain type, etc.)
127 $classes = split(' ', $vars['body_classes']);
128 if (!$vars['is_front']) {
129 // Add unique class for each page.
130 $path = drupal_get_path_alias($_GET['q']);
131 $classes[] = zen_id_safe('page-' .
$path);
132 // Add unique class for each website section.
133 list($section, ) = explode('/', $path, 2);
134 if (arg(0) == 'node') {
135 if (arg(1) == 'add') {
136 $section = 'node-add';
138 elseif (is_numeric(arg(1)) && (arg(2) == 'edit' || arg(2) == 'delete')) {
139 $section = 'node-' .
arg(2);
142 $classes[] = zen_id_safe('section-' .
$section);
144 if (theme_get_setting('zen_wireframes')) {
145 $classes[] = 'with-wireframes'; // Optionally add the wireframes style.
147 $vars['body_classes'] = implode(' ', $classes); // Concatenate with spaces.
151 * Override or insert variables into the node templates.
154 * An array of variables to pass to the theme template.
156 * The name of the template being rendered ("node" in this case.)
158 function zen_preprocess_node(&$vars, $hook) {
159 // Special classes for nodes
160 $classes = array('node');
161 if ($vars['sticky']) {
162 $classes[] = 'sticky';
164 if (!$vars['status']) {
165 $classes[] = 'node-unpublished';
166 $vars['unpublished'] = TRUE
;
169 $vars['unpublished'] = FALSE
;
171 if ($vars['uid'] && $vars['uid'] == $GLOBALS['user']->uid
) {
172 $classes[] = 'node-mine'; // Node is authored by current user.
174 if ($vars['teaser']) {
175 $classes[] = 'node-teaser'; // Node is displayed as teaser.
177 // Class for node type: "node-type-page", "node-type-story", "node-type-my-custom-type", etc.
178 $classes[] = 'node-type-' .
$vars['type'];
179 $vars['classes'] = implode(' ', $classes); // Concatenate with spaces
183 * Override or insert variables into the comment templates.
186 * An array of variables to pass to the theme template.
188 * The name of the template being rendered ("comment" in this case.)
190 function zen_preprocess_comment(&$vars, $hook) {
191 include_once
'./' .
drupal_get_path('theme', 'zen') .
'/template.comment.inc';
192 _zen_preprocess_comment($vars, $hook);
196 * Override or insert variables into the block templates.
199 * An array of variables to pass to the theme template.
201 * The name of the template being rendered ("block" in this case.)
203 function zen_preprocess_block(&$vars, $hook) {
204 $block = $vars['block'];
206 // Special classes for blocks.
207 $classes = array('block');
208 $classes[] = 'block-' .
$block->module
;
209 $classes[] = 'region-' .
$vars['block_zebra'];
210 $classes[] = $vars['zebra'];
211 $classes[] = 'region-count-' .
$vars['block_id'];
212 $classes[] = 'count-' .
$vars['id'];
214 $vars['edit_links_array'] = array();
215 $vars['edit_links'] = '';
216 if (theme_get_setting('zen_block_editing') && user_access('administer blocks')) {
217 include_once
'./' .
drupal_get_path('theme', 'zen') .
'/template.block-editing.inc';
218 zen_preprocess_block_editing($vars, $hook);
219 $classes[] = 'with-block-editing';
222 // Render block classes.
223 $vars['classes'] = implode(' ', $classes);
227 * Converts a string to a suitable html ID attribute.
229 * http://www.w3.org/TR/html4/struct/global.html#h-7.5.2 specifies what makes a
230 * valid ID attribute in HTML. This function:
232 * - Ensure an ID starts with an alpha character by optionally adding an 'id'.
233 * - Replaces any character except A-Z, numbers, and underscores with dashes.
234 * - Converts entire string to lowercase.
239 * The converted string
241 function zen_id_safe($string) {
242 // Replace with dashes anything that isn't A-Z, numbers, dashes, or underscores.
243 $string = strtolower(preg_replace('/[^a-zA-Z0-9_-]+/', '-', $string));
244 // If the first character is not a-z, add 'n' in front.
245 if (!ctype_lower($string{0})) { // Don't use ctype_alpha since its locale aware.
246 $string = 'id' .
$string;