| 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 | /** |
| d212bfc9 J |
129 | * Override or insert variables into templates before other preprocess functions have run. |
| 130 | * | |
| 131 | * @param $vars | |
| 132 | * An array of variables to pass to the theme template. | |
| 133 | * @param $hook | |
| 134 | * The name of the template being rendered. | |
| 135 | */ | |
| 136 | function zen_preprocess(&$vars, $hook) { | |
| 137 | // In D6, the page.tpl uses a different variable name to hold the classes. | |
| 138 | $key = ($hook == 'page' || $hook == 'maintenance_page') ? 'body_classes' : 'classes'; | |
| 139 | ||
| 140 | // Create a D7-standard classes_array variable. | |
| 141 | if (array_key_exists($key, $vars)) { | |
| 17e89a6f J |
142 | // Views (and possibly other modules) have templates with a $classes |
| 143 | // variable that isn't a string, so we leave those variables alone. | |
| 144 | if (is_string($vars[$key])) { | |
| 145 | $vars['classes_array'] = explode(' ', $vars[$key]); | |
| 146 | unset($vars[$key]); | |
| 147 | } | |
| d212bfc9 J |
148 | } |
| 149 | else { | |
| 150 | $vars['classes_array'] = array($hook); | |
| 151 | } | |
| 152 | } | |
| 153 | ||
| 154 | /** | |
| 0b1037f4 | 155 | * Override or insert variables into the page templates. |
| 87695e28 J |
156 | * |
| 157 | * @param $vars | |
| 0b1037f4 | 158 | * An array of variables to pass to the theme template. |
| e6f4a124 | 159 | * @param $hook |
| 0b1037f4 | 160 | * The name of the template being rendered ("page" in this case.) |
| 87695e28 | 161 | */ |
| fcf0b3cc | 162 | function zen_preprocess_page(&$vars, $hook) { |
| 78d8d215 J |
163 | // If the user is silly and enables Zen as the theme, add some styles. |
| 164 | if ($GLOBALS['theme'] == 'zen') { | |
| 3183d194 | 165 | include_once './' . _zen_path() . '/zen-internals/template.zen.inc'; |
| 78d8d215 J |
166 | _zen_preprocess_page($vars, $hook); |
| 167 | } | |
| 719059ea | 168 | // Add conditional stylesheets. |
| 78d8d215 | 169 | elseif (!module_exists('conditional_styles')) { |
| 719059ea J |
170 | $vars['styles'] .= $vars['conditional_styles'] = variable_get('conditional_styles_' . $GLOBALS['theme'], ''); |
| 171 | } | |
| 172 | ||
| e0a8f494 J |
173 | // Classes for body element. Allows advanced theming based on context |
| 174 | // (home page, node of certain type, etc.) | |
| 6930eb03 | 175 | // Remove the mostly useless page-ARG0 class. |
| d212bfc9 J |
176 | if ($index = array_search(preg_replace('![^abcdefghijklmnopqrstuvwxyz0-9-_]+!s', '', 'page-'. drupal_strtolower(arg(0))), $vars['classes_array'])) { |
| 177 | unset($vars['classes_array'][$index]); | |
| 6930eb03 | 178 | } |
| e0a8f494 | 179 | if (!$vars['is_front']) { |
| 363d1497 | 180 | // Add unique class for each page. |
| 9faf4798 | 181 | $path = drupal_get_path_alias($_GET['q']); |
| d212bfc9 | 182 | $vars['classes_array'][] = zen_id_safe('page-' . $path); |
| 363d1497 | 183 | // Add unique class for each website section. |
| 8357c010 | 184 | list($section, ) = explode('/', $path, 2); |
| 28511ba8 J |
185 | if (arg(0) == 'node') { |
| 186 | if (arg(1) == 'add') { | |
| 363d1497 | 187 | $section = 'node-add'; |
| 28511ba8 J |
188 | } |
| 189 | elseif (is_numeric(arg(1)) && (arg(2) == 'edit' || arg(2) == 'delete')) { | |
| 363d1497 | 190 | $section = 'node-' . arg(2); |
| 28511ba8 J |
191 | } |
| 192 | } | |
| d212bfc9 | 193 | $vars['classes_array'][] = zen_id_safe('section-' . $section); |
| 960bac1c | 194 | } |
| 2041a7c1 | 195 | if (theme_get_setting('zen_wireframes')) { |
| d212bfc9 | 196 | $vars['classes_array'][] = 'with-wireframes'; // Optionally add the wireframes style. |
| 2041a7c1 | 197 | } |
| fdf6d8c0 J |
198 | // Add new sidebar classes in addition to Drupal core's sidebar-* classes. |
| 199 | // This provides some backwards compatibility with Zen 6.x-1.x themes. | |
| 2f37f103 J |
200 | if ($vars['layout'] != 'both') { |
| 201 | $new_layout = ($vars['layout'] == 'left') ? 'first' : 'second'; | |
| d212bfc9 J |
202 | if (array_search('sidebar-' . $vars['layout'], $vars['classes_array'])) { |
| 203 | $vars['classes_array'][] = 'sidebar-' . $new_layout; | |
| 2f37f103 | 204 | } |
| fdf6d8c0 | 205 | // Replace core's $layout variable with our naming of sidebars. |
| 2f37f103 | 206 | $vars['layout'] = $new_layout; |
| 536678ab | 207 | } |
| e0a8f494 | 208 | } |
| 7c5fa196 | 209 | |
| e0a8f494 | 210 | /** |
| 3183d194 J |
211 | * Override or insert variables into the maintenance page template. |
| 212 | * | |
| 213 | * @param $vars | |
| 214 | * An array of variables to pass to the theme template. | |
| 215 | * @param $hook | |
| 31c1fbc2 | 216 | * The name of the template being rendered ("maintenance_page" in this case.) |
| 3183d194 J |
217 | */ |
| 218 | function zen_preprocess_maintenance_page(&$vars, $hook) { | |
| 219 | // If Zen is the maintenance theme, add some styles. | |
| 220 | if ($GLOBALS['theme'] == 'zen') { | |
| 221 | include_once './' . _zen_path() . '/zen-internals/template.zen.inc'; | |
| 222 | _zen_preprocess_page($vars, $hook); | |
| 223 | } | |
| 224 | // Add conditional stylesheets. | |
| 225 | elseif (!module_exists('conditional_styles')) { | |
| 226 | $vars['styles'] .= $vars['conditional_styles'] = variable_get('conditional_styles_' . $GLOBALS['theme'], ''); | |
| 227 | } | |
| 228 | ||
| 229 | // Classes for body element. Allows advanced theming based on context | |
| 230 | // (home page, node of certain type, etc.) | |
| 231 | $vars['body_classes_array'] = explode(' ', $vars['body_classes']); | |
| 232 | } | |
| 233 | ||
| 234 | /** | |
| 0b1037f4 | 235 | * Override or insert variables into the node templates. |
| e0a8f494 J |
236 | * |
| 237 | * @param $vars | |
| 0b1037f4 | 238 | * An array of variables to pass to the theme template. |
| e6f4a124 | 239 | * @param $hook |
| 0b1037f4 | 240 | * The name of the template being rendered ("node" in this case.) |
| e0a8f494 | 241 | */ |
| fcf0b3cc | 242 | function zen_preprocess_node(&$vars, $hook) { |
| 78362cd3 J |
243 | // Create the build_mode variable. |
| 244 | switch ($vars['node']->build_mode) { | |
| 245 | case NODE_BUILD_NORMAL: | |
| 246 | $vars['build_mode'] = $vars['teaser'] ? 'teaser' : 'full'; | |
| 247 | break; | |
| 248 | case NODE_BUILD_PREVIEW: | |
| 249 | $vars['build_mode'] = 'preview'; | |
| 250 | break; | |
| 251 | case NODE_BUILD_SEARCH_INDEX: | |
| 252 | $vars['build_mode'] = 'search_index'; | |
| 253 | break; | |
| 254 | case NODE_BUILD_SEARCH_RESULT: | |
| 255 | $vars['build_mode'] = 'search_result'; | |
| 256 | break; | |
| 257 | case NODE_BUILD_RSS: | |
| 258 | $vars['build_mode'] = 'rss'; | |
| 259 | break; | |
| 260 | case NODE_BUILD_PRINT: | |
| 261 | $vars['build_mode'] = 'print'; | |
| 262 | break; | |
| 263 | } | |
| 264 | ||
| c91ed8a5 J |
265 | // Create the user_picture variable. |
| 266 | $vars['user_picture'] = $vars['picture']; | |
| 267 | ||
| 78362cd3 | 268 | // Special classes for nodes. |
| c91ed8a5 | 269 | // Class for node type: "node-type-page", "node-type-story", "node-type-my-custom-type", etc. |
| d212bfc9 | 270 | $vars['classes_array'][] = zen_id_safe('node-type-' . $vars['type']); |
| d893f301 J |
271 | if ($vars['promote']) { |
| 272 | $vars['classes_array'][] = 'node-promoted'; | |
| c91ed8a5 | 273 | } |
| e0a8f494 | 274 | if ($vars['sticky']) { |
| d212bfc9 | 275 | $vars['classes_array'][] = 'node-sticky'; |
| e0a8f494 | 276 | } |
| b457ba98 | 277 | if (!$vars['status']) { |
| d212bfc9 | 278 | $vars['classes_array'][] = 'node-unpublished'; |
| 28511ba8 J |
279 | $vars['unpublished'] = TRUE; |
| 280 | } | |
| 281 | else { | |
| 282 | $vars['unpublished'] = FALSE; | |
| e0a8f494 | 283 | } |
| b457ba98 | 284 | if ($vars['uid'] && $vars['uid'] == $GLOBALS['user']->uid) { |
| d212bfc9 | 285 | $vars['classes_array'][] = 'node-mine'; // Node is authored by current user. |
| 7c5fa196 | 286 | } |
| e0a8f494 | 287 | if ($vars['teaser']) { |
| d212bfc9 | 288 | $vars['classes_array'][] = 'node-teaser'; // Node is displayed as teaser. |
| e0a8f494 | 289 | } |
| d893f301 J |
290 | if (isset($vars['preview'])) { |
| 291 | $vars['classes_array'][] = 'node-preview'; | |
| c91ed8a5 | 292 | } |
| e0a8f494 | 293 | } |
| 7c5fa196 | 294 | |
| e0a8f494 | 295 | /** |
| 0b1037f4 | 296 | * Override or insert variables into the comment templates. |
| e0a8f494 J |
297 | * |
| 298 | * @param $vars | |
| 0b1037f4 | 299 | * An array of variables to pass to the theme template. |
| e6f4a124 | 300 | * @param $hook |
| 0b1037f4 | 301 | * The name of the template being rendered ("comment" in this case.) |
| e0a8f494 | 302 | */ |
| fcf0b3cc | 303 | function zen_preprocess_comment(&$vars, $hook) { |
| 3183d194 | 304 | include_once './' . _zen_path() . '/zen-internals/template.comment.inc'; |
| 29ba6758 | 305 | _zen_preprocess_comment($vars, $hook); |
| 960bac1c | 306 | } |
| 4dd0f1bf JR |
307 | |
| 308 | /** | |
| 94f89279 J |
309 | * Preprocess variables for region.tpl.php |
| 310 | * | |
| 311 | * Prepare the values passed to the theme_region function to be passed into a | |
| 312 | * pluggable template engine. Uses the region name to generate a template file | |
| 313 | * suggestions. If none are found, the default region.tpl.php is used. | |
| 314 | * | |
| 315 | * @see region.tpl.php | |
| 316 | */ | |
| 317 | function zen_preprocess_region(&$vars, $hook) { | |
| 318 | // Create the $content variable that templates expect. | |
| 319 | $vars['content'] = $vars['elements']['#children']; | |
| 320 | $vars['region'] = $vars['elements']['#region']; | |
| 321 | ||
| 322 | $region = 'region-' . str_replace('_', '-', $vars['region']); | |
| 323 | $vars['classes_array'] = array('region', $region); | |
| 324 | if ($vars['region'] == 'navbar') { | |
| 325 | $vars['classes_array'][] = 'clearfix'; | |
| 326 | } | |
| 327 | $vars['template_files'][] = $region; | |
| 328 | } | |
| 329 | ||
| 330 | /** | |
| 0b1037f4 | 331 | * Override or insert variables into the block templates. |
| 28511ba8 J |
332 | * |
| 333 | * @param $vars | |
| 0b1037f4 | 334 | * An array of variables to pass to the theme template. |
| e6f4a124 | 335 | * @param $hook |
| 0b1037f4 | 336 | * The name of the template being rendered ("block" in this case.) |
| 28511ba8 | 337 | */ |
| fcf0b3cc | 338 | function zen_preprocess_block(&$vars, $hook) { |
| 28511ba8 J |
339 | $block = $vars['block']; |
| 340 | ||
| 76772d59 | 341 | // Special classes for blocks. |
| d212bfc9 J |
342 | $vars['classes_array'][] = 'block-' . $block->module; |
| 343 | $vars['classes_array'][] = 'region-' . $vars['block_zebra']; | |
| 344 | $vars['classes_array'][] = $vars['zebra']; | |
| 345 | $vars['classes_array'][] = 'region-count-' . $vars['block_id']; | |
| 346 | $vars['classes_array'][] = 'count-' . $vars['id']; | |
| 28511ba8 | 347 | |
| a0e81398 | 348 | $vars['edit_links_array'] = array(); |
| 28511ba8 | 349 | if (theme_get_setting('zen_block_editing') && user_access('administer blocks')) { |
| 3183d194 | 350 | include_once './' . _zen_path() . '/zen-internals/template.block-editing.inc'; |
| a0e81398 | 351 | zen_preprocess_block_editing($vars, $hook); |
| d212bfc9 | 352 | $vars['classes_array'][] = 'with-block-editing'; |
| 28511ba8 | 353 | } |
| 0db41f1b J |
354 | } |
| 355 | ||
| 356 | /** | |
| 357 | * Override or insert variables into templates after preprocess functions have run. | |
| 358 | * | |
| 359 | * @param $vars | |
| 360 | * An array of variables to pass to the theme template. | |
| 361 | * @param $hook | |
| 362 | * The name of the template being rendered. | |
| 363 | */ | |
| 364 | function zen_process(&$vars, $hook) { | |
| 17e89a6f J |
365 | if (array_key_exists('classes_array', $vars)) { |
| 366 | $vars['classes'] = implode(' ', $vars['classes_array']); | |
| 367 | } | |
| 28511ba8 J |
368 | } |
| 369 | ||
| 370 | /** | |
| 6f634acb J |
371 | * Override or insert variables into the block templates after preprocess functions have run. |
| 372 | * | |
| 373 | * @param $vars | |
| 374 | * An array of variables to pass to the theme template. | |
| 375 | * @param $hook | |
| 376 | * The name of the template being rendered ("block" in this case.) | |
| 377 | */ | |
| 378 | function zen_process_block(&$vars, $hook) { | |
| 379 | $vars['edit_links'] = !empty($vars['edit_links_array']) ? '<div class="edit">' . implode(' ', $vars['edit_links_array']) . '</div>' : ''; | |
| 380 | } | |
| 381 | ||
| 382 | /** | |
| 7c5fa196 J |
383 | * Converts a string to a suitable html ID attribute. |
| 384 | * | |
| 2bf29305 J |
385 | * http://www.w3.org/TR/html4/struct/global.html#h-7.5.2 specifies what makes a |
| 386 | * valid ID attribute in HTML. This function: | |
| 387 | * | |
| 4f5c1d0c | 388 | * - Ensure an ID starts with an alpha character by optionally adding an 'id'. |
| 4d7d1dc8 | 389 | * - Replaces any character except alphanumeric characters with dashes. |
| 7c5fa196 | 390 | * - Converts entire string to lowercase. |
| 7c5fa196 | 391 | * |
| 28511ba8 | 392 | * @param $string |
| 7c5fa196 J |
393 | * The string |
| 394 | * @return | |
| 395 | * The converted string | |
| 396 | */ | |
| 4dd0f1bf | 397 | function zen_id_safe($string) { |
| 2bf29305 | 398 | // Replace with dashes anything that isn't A-Z, numbers, dashes, or underscores. |
| 4d7d1dc8 J |
399 | $string = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $string)); |
| 400 | // If the first character is not a-z, add 'id' in front. | |
| 2bf29305 J |
401 | if (!ctype_lower($string{0})) { // Don't use ctype_alpha since its locale aware. |
| 402 | $string = 'id' . $string; | |
| 4dd0f1bf | 403 | } |
| 2bf29305 | 404 | return $string; |
| 7c5fa196 | 405 | } |
| 3183d194 J |
406 | |
| 407 | /** | |
| 408 | * Returns the path to the Zen theme. | |
| 409 | * | |
| 410 | * drupal_get_filename() is broken; see #341140. When that is fixed in Drupal 6, | |
| 411 | * replace _zen_path() with drupal_get_path('theme', 'zen'). | |
| 412 | */ | |
| 413 | function _zen_path() { | |
| 414 | static $path = FALSE; | |
| 415 | if (!$path) { | |
| 416 | $matches = drupal_system_listing('zen\.info$', 'themes', 'name', 0); | |
| 417 | if (!empty($matches['zen']->filename)) { | |
| 418 | $path = dirname($matches['zen']->filename); | |
| 419 | } | |
| 420 | } | |
| 421 | return $path; | |
| 422 | } |