| Commit | Line | Data |
|---|---|---|
| 0c91c6b4 | 1 | <?php |
| 8c1acf80 | 2 | // $Id$ |
| 0c91c6b4 JR |
3 | |
| 4 | /** | |
| 8c1acf80 | 5 | * @file |
| 0b1037f4 | 6 | * Contains theme override functions and preprocess functions for the Zen theme. |
| 7c5fa196 | 7 | * |
| 0b1037f4 | 8 | * IMPORTANT WARNING: DO NOT MODIFY THIS FILE. |
| 28511ba8 J |
9 | * |
| 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 | |
| 960bac1c TS |
14 | */ |
| 15 | ||
| 89804871 J |
16 | // Auto-rebuild the theme registry during theme development. |
| 17 | if (theme_get_setting('zen_rebuild_registry')) { | |
| 18 | drupal_rebuild_theme_registry(); | |
| 19 | } | |
| 7c5fa196 | 20 | |
| 719059ea | 21 | |
| 4f5c1d0c J |
22 | /** |
| 23 | * Implements HOOK_theme(). | |
| 52521ba9 | 24 | */ |
| 4f5c1d0c | 25 | function zen_theme(&$existing, $type, $theme, $path) { |
| 3183d194 J |
26 | // When #341140 is fixed, replace _zen_path() with drupal_get_path(). |
| 27 | include_once './' . _zen_path() . '/zen-internals/template.theme-registry.inc'; | |
| 4f5c1d0c J |
28 | return _zen_theme($existing, $type, $theme, $path); |
| 29 | } | |
| 52521ba9 | 30 | |
| 7c5fa196 J |
31 | /** |
| 32 | * Return a themed breadcrumb trail. | |
| 7081db43 | 33 | * |
| 7c5fa196 J |
34 | * @param $breadcrumb |
| 35 | * An array containing the breadcrumb links. | |
| 36 | * @return | |
| 37 | * A string containing the breadcrumb output. | |
| 7081db43 | 38 | */ |
| bdf1d868 | 39 | function zen_breadcrumb($breadcrumb) { |
| d60c8c02 | 40 | // Determine if we are to display the breadcrumb. |
| 59794464 | 41 | $show_breadcrumb = theme_get_setting('zen_breadcrumb'); |
| 52521ba9 | 42 | if ($show_breadcrumb == 'yes' || $show_breadcrumb == 'admin' && arg(0) == 'admin') { |
| 59794464 | 43 | |
| d60c8c02 | 44 | // Optionally get rid of the homepage link. |
| 59794464 | 45 | $show_breadcrumb_home = theme_get_setting('zen_breadcrumb_home'); |
| 52521ba9 | 46 | if (!$show_breadcrumb_home) { |
| 52521ba9 J |
47 | array_shift($breadcrumb); |
| 48 | } | |
| 59794464 | 49 | |
| d60c8c02 | 50 | // Return the breadcrumb with separators. |
| 52521ba9 | 51 | if (!empty($breadcrumb)) { |
| 59794464 | 52 | $breadcrumb_separator = theme_get_setting('zen_breadcrumb_separator'); |
| d60c8c02 J |
53 | $trailing_separator = $title = ''; |
| 54 | if (theme_get_setting('zen_breadcrumb_title')) { | |
| 55 | $trailing_separator = $breadcrumb_separator; | |
| 101297cb | 56 | $title = drupal_get_title(); |
| d60c8c02 J |
57 | } |
| 58 | elseif (theme_get_setting('zen_breadcrumb_trailing')) { | |
| 59 | $trailing_separator = $breadcrumb_separator; | |
| 60 | } | |
| 61 | return '<div class="breadcrumb">' . implode($breadcrumb_separator, $breadcrumb) . "$trailing_separator$title</div>"; | |
| 52521ba9 | 62 | } |
| 7c5fa196 | 63 | } |
| d60c8c02 | 64 | // Otherwise, return an empty string. |
| 52521ba9 | 65 | return ''; |
| 7c5fa196 J |
66 | } |
| 67 | ||
| 4f5c1d0c J |
68 | /** |
| 69 | * Implements theme_menu_item_link() | |
| 70 | */ | |
| 71 | function zen_menu_item_link($link) { | |
| 72 | if (empty($link['localized_options'])) { | |
| 73 | $link['localized_options'] = array(); | |
| 74 | } | |
| 75 | ||
| 76 | // If an item is a LOCAL TASK, render it as a tab | |
| 77 | if ($link['type'] & MENU_IS_LOCAL_TASK) { | |
| 78 | $link['title'] = '<span class="tab">' . check_plain($link['title']) . '</span>'; | |
| 79 | $link['localized_options']['html'] = TRUE; | |
| 80 | } | |
| 81 | ||
| 82 | return l($link['title'], $link['href'], $link['localized_options']); | |
| 83 | } | |
| 84 | ||
| 85 | /** | |
| 86 | * Duplicate of theme_menu_local_tasks() but adds clear-block to tabs. | |
| 87 | */ | |
| 88 | function zen_menu_local_tasks() { | |
| 89 | $output = ''; | |
| 90 | ||
| 91 | if ($primary = menu_primary_local_tasks()) { | |
| 92 | $output .= '<ul class="tabs primary clear-block">' . $primary . '</ul>'; | |
| 93 | } | |
| 94 | if ($secondary = menu_secondary_local_tasks()) { | |
| 95 | $output .= '<ul class="tabs secondary clear-block">' . $secondary . '</ul>'; | |
| 96 | } | |
| 97 | ||
| 98 | return $output; | |
| 99 | } | |
| 960bac1c | 100 | |
| 94f89279 J |
101 | /** |
| 102 | * Return a set of blocks available for the current user. | |
| 103 | * | |
| 104 | * @param $region | |
| 105 | * Which set of blocks to retrieve. | |
| 106 | * @return | |
| 107 | * A string containing the themed blocks for this region. | |
| 108 | */ | |
| 109 | function zen_blocks($region) { | |
| 110 | $output = ''; | |
| 111 | ||
| 112 | if ($list = block_list($region)) { | |
| 113 | foreach ($list as $key => $block) { | |
| 114 | // $key == module_delta | |
| 115 | $output .= theme('block', $block); | |
| 116 | } | |
| 117 | } | |
| 118 | ||
| 119 | // Add any content assigned to this region through drupal_set_content() calls. | |
| 120 | $output .= drupal_get_content($region); | |
| 121 | ||
| 122 | $elements['#children'] = $output; | |
| 123 | $elements['#region'] = $region; | |
| 124 | ||
| 125 | return $output ? theme('region', $elements) : ''; | |
| 126 | } | |
| 7c5fa196 | 127 | |
| 960bac1c | 128 | /** |
| 0b1037f4 | 129 | * Override or insert variables into the page templates. |
| 87695e28 J |
130 | * |
| 131 | * @param $vars | |
| 0b1037f4 | 132 | * An array of variables to pass to the theme template. |
| e6f4a124 | 133 | * @param $hook |
| 0b1037f4 | 134 | * The name of the template being rendered ("page" in this case.) |
| 87695e28 | 135 | */ |
| fcf0b3cc | 136 | function zen_preprocess_page(&$vars, $hook) { |
| 78d8d215 J |
137 | // If the user is silly and enables Zen as the theme, add some styles. |
| 138 | if ($GLOBALS['theme'] == 'zen') { | |
| 3183d194 | 139 | include_once './' . _zen_path() . '/zen-internals/template.zen.inc'; |
| 78d8d215 J |
140 | _zen_preprocess_page($vars, $hook); |
| 141 | } | |
| 719059ea | 142 | // Add conditional stylesheets. |
| 78d8d215 | 143 | elseif (!module_exists('conditional_styles')) { |
| 719059ea J |
144 | $vars['styles'] .= $vars['conditional_styles'] = variable_get('conditional_styles_' . $GLOBALS['theme'], ''); |
| 145 | } | |
| 146 | ||
| e0a8f494 J |
147 | // Classes for body element. Allows advanced theming based on context |
| 148 | // (home page, node of certain type, etc.) | |
| ad0416cf | 149 | $classes = explode(' ', $vars['body_classes']); |
| 6930eb03 J |
150 | // Remove the mostly useless page-ARG0 class. |
| 151 | if ($index = array_search(preg_replace('![^abcdefghijklmnopqrstuvwxyz0-9-_]+!s', '', 'page-'. drupal_strtolower(arg(0))), $classes)) { | |
| 152 | unset($classes[$index]); | |
| 153 | } | |
| e0a8f494 | 154 | if (!$vars['is_front']) { |
| 363d1497 | 155 | // Add unique class for each page. |
| 9faf4798 | 156 | $path = drupal_get_path_alias($_GET['q']); |
| 363d1497 J |
157 | $classes[] = zen_id_safe('page-' . $path); |
| 158 | // Add unique class for each website section. | |
| 8357c010 | 159 | list($section, ) = explode('/', $path, 2); |
| 28511ba8 J |
160 | if (arg(0) == 'node') { |
| 161 | if (arg(1) == 'add') { | |
| 363d1497 | 162 | $section = 'node-add'; |
| 28511ba8 J |
163 | } |
| 164 | elseif (is_numeric(arg(1)) && (arg(2) == 'edit' || arg(2) == 'delete')) { | |
| 363d1497 | 165 | $section = 'node-' . arg(2); |
| 28511ba8 J |
166 | } |
| 167 | } | |
| 363d1497 | 168 | $classes[] = zen_id_safe('section-' . $section); |
| 960bac1c | 169 | } |
| 2041a7c1 | 170 | if (theme_get_setting('zen_wireframes')) { |
| 363d1497 | 171 | $classes[] = 'with-wireframes'; // Optionally add the wireframes style. |
| 2041a7c1 | 172 | } |
| fdf6d8c0 J |
173 | // Add new sidebar classes in addition to Drupal core's sidebar-* classes. |
| 174 | // This provides some backwards compatibility with Zen 6.x-1.x themes. | |
| 2f37f103 J |
175 | if ($vars['layout'] != 'both') { |
| 176 | $new_layout = ($vars['layout'] == 'left') ? 'first' : 'second'; | |
| fdf6d8c0 J |
177 | if (array_search('sidebar-' . $vars['layout'], $classes)) { |
| 178 | $classes[] = 'sidebar-' . $new_layout; | |
| 2f37f103 | 179 | } |
| fdf6d8c0 | 180 | // Replace core's $layout variable with our naming of sidebars. |
| 2f37f103 | 181 | $vars['layout'] = $new_layout; |
| 536678ab | 182 | } |
| 007cbfc2 | 183 | $vars['body_classes_array'] = $classes; |
| 363d1497 | 184 | $vars['body_classes'] = implode(' ', $classes); // Concatenate with spaces. |
| e0a8f494 | 185 | } |
| 7c5fa196 | 186 | |
| e0a8f494 | 187 | /** |
| 3183d194 J |
188 | * Override or insert variables into the maintenance page template. |
| 189 | * | |
| 190 | * @param $vars | |
| 191 | * An array of variables to pass to the theme template. | |
| 192 | * @param $hook | |
| 31c1fbc2 | 193 | * The name of the template being rendered ("maintenance_page" in this case.) |
| 3183d194 J |
194 | */ |
| 195 | function zen_preprocess_maintenance_page(&$vars, $hook) { | |
| 196 | // If Zen is the maintenance theme, add some styles. | |
| 197 | if ($GLOBALS['theme'] == 'zen') { | |
| 198 | include_once './' . _zen_path() . '/zen-internals/template.zen.inc'; | |
| 199 | _zen_preprocess_page($vars, $hook); | |
| 200 | } | |
| 201 | // Add conditional stylesheets. | |
| 202 | elseif (!module_exists('conditional_styles')) { | |
| 203 | $vars['styles'] .= $vars['conditional_styles'] = variable_get('conditional_styles_' . $GLOBALS['theme'], ''); | |
| 204 | } | |
| 205 | ||
| 206 | // Classes for body element. Allows advanced theming based on context | |
| 207 | // (home page, node of certain type, etc.) | |
| 208 | $vars['body_classes_array'] = explode(' ', $vars['body_classes']); | |
| 209 | } | |
| 210 | ||
| 211 | /** | |
| 0b1037f4 | 212 | * Override or insert variables into the node templates. |
| e0a8f494 J |
213 | * |
| 214 | * @param $vars | |
| 0b1037f4 | 215 | * An array of variables to pass to the theme template. |
| e6f4a124 | 216 | * @param $hook |
| 0b1037f4 | 217 | * The name of the template being rendered ("node" in this case.) |
| e0a8f494 | 218 | */ |
| fcf0b3cc | 219 | function zen_preprocess_node(&$vars, $hook) { |
| 78362cd3 J |
220 | // Create the build_mode variable. |
| 221 | switch ($vars['node']->build_mode) { | |
| 222 | case NODE_BUILD_NORMAL: | |
| 223 | $vars['build_mode'] = $vars['teaser'] ? 'teaser' : 'full'; | |
| 224 | break; | |
| 225 | case NODE_BUILD_PREVIEW: | |
| 226 | $vars['build_mode'] = 'preview'; | |
| 227 | break; | |
| 228 | case NODE_BUILD_SEARCH_INDEX: | |
| 229 | $vars['build_mode'] = 'search_index'; | |
| 230 | break; | |
| 231 | case NODE_BUILD_SEARCH_RESULT: | |
| 232 | $vars['build_mode'] = 'search_result'; | |
| 233 | break; | |
| 234 | case NODE_BUILD_RSS: | |
| 235 | $vars['build_mode'] = 'rss'; | |
| 236 | break; | |
| 237 | case NODE_BUILD_PRINT: | |
| 238 | $vars['build_mode'] = 'print'; | |
| 239 | break; | |
| 240 | } | |
| 241 | ||
| c91ed8a5 J |
242 | // Create the user_picture variable. |
| 243 | $vars['user_picture'] = $vars['picture']; | |
| 244 | ||
| 78362cd3 | 245 | // Special classes for nodes. |
| 23086957 | 246 | $classes = array('node'); |
| c91ed8a5 J |
247 | // Class for node type: "node-type-page", "node-type-story", "node-type-my-custom-type", etc. |
| 248 | $classes[] = zen_id_safe('node-type-' . $vars['type']); | |
| d893f301 J |
249 | if ($vars['promote']) { |
| 250 | $vars['classes_array'][] = 'node-promoted'; | |
| c91ed8a5 | 251 | } |
| e0a8f494 | 252 | if ($vars['sticky']) { |
| c91ed8a5 | 253 | $classes[] = 'node-sticky'; |
| e0a8f494 | 254 | } |
| b457ba98 | 255 | if (!$vars['status']) { |
| 23086957 | 256 | $classes[] = 'node-unpublished'; |
| 28511ba8 J |
257 | $vars['unpublished'] = TRUE; |
| 258 | } | |
| 259 | else { | |
| 260 | $vars['unpublished'] = FALSE; | |
| e0a8f494 | 261 | } |
| b457ba98 J |
262 | if ($vars['uid'] && $vars['uid'] == $GLOBALS['user']->uid) { |
| 263 | $classes[] = 'node-mine'; // Node is authored by current user. | |
| 7c5fa196 | 264 | } |
| e0a8f494 | 265 | if ($vars['teaser']) { |
| b457ba98 | 266 | $classes[] = 'node-teaser'; // Node is displayed as teaser. |
| e0a8f494 | 267 | } |
| d893f301 J |
268 | if (isset($vars['preview'])) { |
| 269 | $vars['classes_array'][] = 'node-preview'; | |
| c91ed8a5 | 270 | } |
| 1f314b47 | 271 | $vars['classes_array'] = $classes; |
| e0a8f494 | 272 | } |
| 7c5fa196 | 273 | |
| e0a8f494 | 274 | /** |
| 0b1037f4 | 275 | * Override or insert variables into the comment templates. |
| e0a8f494 J |
276 | * |
| 277 | * @param $vars | |
| 0b1037f4 | 278 | * An array of variables to pass to the theme template. |
| e6f4a124 | 279 | * @param $hook |
| 0b1037f4 | 280 | * The name of the template being rendered ("comment" in this case.) |
| e0a8f494 | 281 | */ |
| fcf0b3cc | 282 | function zen_preprocess_comment(&$vars, $hook) { |
| 3183d194 | 283 | include_once './' . _zen_path() . '/zen-internals/template.comment.inc'; |
| 29ba6758 | 284 | _zen_preprocess_comment($vars, $hook); |
| 960bac1c | 285 | } |
| 4dd0f1bf JR |
286 | |
| 287 | /** | |
| 94f89279 J |
288 | * Preprocess variables for region.tpl.php |
| 289 | * | |
| 290 | * Prepare the values passed to the theme_region function to be passed into a | |
| 291 | * pluggable template engine. Uses the region name to generate a template file | |
| 292 | * suggestions. If none are found, the default region.tpl.php is used. | |
| 293 | * | |
| 294 | * @see region.tpl.php | |
| 295 | */ | |
| 296 | function zen_preprocess_region(&$vars, $hook) { | |
| 297 | // Create the $content variable that templates expect. | |
| 298 | $vars['content'] = $vars['elements']['#children']; | |
| 299 | $vars['region'] = $vars['elements']['#region']; | |
| 300 | ||
| 301 | $region = 'region-' . str_replace('_', '-', $vars['region']); | |
| 302 | $vars['classes_array'] = array('region', $region); | |
| 303 | if ($vars['region'] == 'navbar') { | |
| 304 | $vars['classes_array'][] = 'clearfix'; | |
| 305 | } | |
| 306 | $vars['template_files'][] = $region; | |
| 307 | } | |
| 308 | ||
| 309 | /** | |
| 0b1037f4 | 310 | * Override or insert variables into the block templates. |
| 28511ba8 J |
311 | * |
| 312 | * @param $vars | |
| 0b1037f4 | 313 | * An array of variables to pass to the theme template. |
| e6f4a124 | 314 | * @param $hook |
| 0b1037f4 | 315 | * The name of the template being rendered ("block" in this case.) |
| 28511ba8 | 316 | */ |
| fcf0b3cc | 317 | function zen_preprocess_block(&$vars, $hook) { |
| 28511ba8 J |
318 | $block = $vars['block']; |
| 319 | ||
| 76772d59 | 320 | // Special classes for blocks. |
| 0bcb1dd5 J |
321 | $classes = array('block'); |
| 322 | $classes[] = 'block-' . $block->module; | |
| 323 | $classes[] = 'region-' . $vars['block_zebra']; | |
| 324 | $classes[] = $vars['zebra']; | |
| 325 | $classes[] = 'region-count-' . $vars['block_id']; | |
| 326 | $classes[] = 'count-' . $vars['id']; | |
| 28511ba8 | 327 | |
| a0e81398 | 328 | $vars['edit_links_array'] = array(); |
| 28511ba8 | 329 | if (theme_get_setting('zen_block_editing') && user_access('administer blocks')) { |
| 3183d194 | 330 | include_once './' . _zen_path() . '/zen-internals/template.block-editing.inc'; |
| a0e81398 | 331 | zen_preprocess_block_editing($vars, $hook); |
| 9c9b5bbc | 332 | $classes[] = 'with-block-editing'; |
| 28511ba8 | 333 | } |
| 9c9b5bbc J |
334 | |
| 335 | // Render block classes. | |
| 1f314b47 | 336 | $vars['classes_array'] = $classes; |
| 0db41f1b J |
337 | } |
| 338 | ||
| 339 | /** | |
| 340 | * Override or insert variables into templates after preprocess functions have run. | |
| 341 | * | |
| 342 | * @param $vars | |
| 343 | * An array of variables to pass to the theme template. | |
| 344 | * @param $hook | |
| 345 | * The name of the template being rendered. | |
| 346 | */ | |
| 347 | function zen_process(&$vars, $hook) { | |
| 348 | switch ($hook) { | |
| 349 | case 'page': | |
| 350 | case 'maintenance_page': | |
| 351 | $vars['body_classes'] = !empty($vars['body_classes_array']) ? implode(' ', $vars['body_classes_array']) : ''; | |
| 352 | break; | |
| 353 | default: | |
| 354 | $vars['classes'] = !empty($vars['classes_array']) ? implode(' ', $vars['classes_array']) : ''; | |
| 355 | break; | |
| 356 | } | |
| 28511ba8 J |
357 | } |
| 358 | ||
| 359 | /** | |
| 6f634acb J |
360 | * Override or insert variables into the block templates after preprocess functions have run. |
| 361 | * | |
| 362 | * @param $vars | |
| 363 | * An array of variables to pass to the theme template. | |
| 364 | * @param $hook | |
| 365 | * The name of the template being rendered ("block" in this case.) | |
| 366 | */ | |
| 367 | function zen_process_block(&$vars, $hook) { | |
| 368 | $vars['edit_links'] = !empty($vars['edit_links_array']) ? '<div class="edit">' . implode(' ', $vars['edit_links_array']) . '</div>' : ''; | |
| 369 | } | |
| 370 | ||
| 371 | /** | |
| 7c5fa196 J |
372 | * Converts a string to a suitable html ID attribute. |
| 373 | * | |
| 2bf29305 J |
374 | * http://www.w3.org/TR/html4/struct/global.html#h-7.5.2 specifies what makes a |
| 375 | * valid ID attribute in HTML. This function: | |
| 376 | * | |
| 4f5c1d0c | 377 | * - Ensure an ID starts with an alpha character by optionally adding an 'id'. |
| 4d7d1dc8 | 378 | * - Replaces any character except alphanumeric characters with dashes. |
| 7c5fa196 | 379 | * - Converts entire string to lowercase. |
| 7c5fa196 | 380 | * |
| 28511ba8 | 381 | * @param $string |
| 7c5fa196 J |
382 | * The string |
| 383 | * @return | |
| 384 | * The converted string | |
| 385 | */ | |
| 4dd0f1bf | 386 | function zen_id_safe($string) { |
| 2bf29305 | 387 | // Replace with dashes anything that isn't A-Z, numbers, dashes, or underscores. |
| 4d7d1dc8 J |
388 | $string = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $string)); |
| 389 | // If the first character is not a-z, add 'id' in front. | |
| 2bf29305 J |
390 | if (!ctype_lower($string{0})) { // Don't use ctype_alpha since its locale aware. |
| 391 | $string = 'id' . $string; | |
| 4dd0f1bf | 392 | } |
| 2bf29305 | 393 | return $string; |
| 7c5fa196 | 394 | } |
| 3183d194 J |
395 | |
| 396 | /** | |
| 397 | * Returns the path to the Zen theme. | |
| 398 | * | |
| 399 | * drupal_get_filename() is broken; see #341140. When that is fixed in Drupal 6, | |
| 400 | * replace _zen_path() with drupal_get_path('theme', 'zen'). | |
| 401 | */ | |
| 402 | function _zen_path() { | |
| 403 | static $path = FALSE; | |
| 404 | if (!$path) { | |
| 405 | $matches = drupal_system_listing('zen\.info$', 'themes', 'name', 0); | |
| 406 | if (!empty($matches['zen']->filename)) { | |
| 407 | $path = dirname($matches['zen']->filename); | |
| 408 | } | |
| 409 | } | |
| 410 | return $path; | |
| 411 | } |