Simplified body class generation code.
[project/zen.git] / zen / template.php
1 <?php
2 // $Id$
3
4 /**
5 * @file
6 * Contains theme override functions and preprocess functions for the Zen theme.
7 *
8 * IMPORTANT WARNING: DO NOT MODIFY THIS FILE.
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
14 */
15
16 // Auto-rebuild the theme registry during theme development.
17 if (theme_get_setting('zen_rebuild_registry')) {
18 drupal_rebuild_theme_registry();
19 }
20
21 /*
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.
24 */
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');
28 }
29 else {
30 drupal_add_css(drupal_get_path('theme', 'zen') . '/layout-liquid.css', 'theme', 'all');
31 }
32 }
33
34 /**
35 * Implements HOOK_theme().
36 */
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);
40 }
41
42 /**
43 * Return a themed breadcrumb trail.
44 *
45 * @param $breadcrumb
46 * An array containing the breadcrumb links.
47 * @return
48 * A string containing the breadcrumb output.
49 */
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') {
54
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);
59 }
60
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>";
66 }
67 }
68 // Otherwise, return an empty string
69 return '';
70 }
71
72 /**
73 * Implements theme_menu_item_link()
74 */
75 function zen_menu_item_link($link) {
76 if (empty($link['localized_options'])) {
77 $link['localized_options'] = array();
78 }
79
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;
84 }
85
86 return l($link['title'], $link['href'], $link['localized_options']);
87 }
88
89 /**
90 * Duplicate of theme_menu_local_tasks() but adds clear-block to tabs.
91 */
92 function zen_menu_local_tasks() {
93 $output = '';
94
95 if ($primary = menu_primary_local_tasks()) {
96 $output .= '<ul class="tabs primary clear-block">' . $primary . '</ul>';
97 }
98 if ($secondary = menu_secondary_local_tasks()) {
99 $output .= '<ul class="tabs secondary clear-block">' . $secondary . '</ul>';
100 }
101
102 return $output;
103 }
104
105
106 /**
107 * Override or insert variables into the page templates.
108 *
109 * @param $vars
110 * An array of variables to pass to the theme template.
111 * @param $hook
112 * The name of the template being rendered ("page" in this case.)
113 */
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>';
118 }
119
120 // Add conditional stylesheets.
121 if (!module_exists('conditional_styles')) {
122 $vars['styles'] .= $vars['conditional_styles'] = variable_get('conditional_styles_' . $GLOBALS['theme'], '');
123 }
124
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';
137 }
138 elseif (is_numeric(arg(1)) && (arg(2) == 'edit' || arg(2) == 'delete')) {
139 $section = 'node-' . arg(2);
140 }
141 }
142 $classes[] = zen_id_safe('section-' . $section);
143 }
144 if (theme_get_setting('zen_wireframes')) {
145 $classes[] = 'with-wireframes'; // Optionally add the wireframes style.
146 }
147 $vars['body_classes'] = implode(' ', $classes); // Concatenate with spaces.
148 }
149
150 /**
151 * Override or insert variables into the node templates.
152 *
153 * @param $vars
154 * An array of variables to pass to the theme template.
155 * @param $hook
156 * The name of the template being rendered ("node" in this case.)
157 */
158 function zen_preprocess_node(&$vars, $hook) {
159 // Special classes for nodes
160 $classes = array('node');
161 if ($vars['sticky']) {
162 $classes[] = 'sticky';
163 }
164 if (!$vars['status']) {
165 $classes[] = 'node-unpublished';
166 $vars['unpublished'] = TRUE;
167 }
168 else {
169 $vars['unpublished'] = FALSE;
170 }
171 if ($vars['uid'] && $vars['uid'] == $GLOBALS['user']->uid) {
172 $classes[] = 'node-mine'; // Node is authored by current user.
173 }
174 if ($vars['teaser']) {
175 $classes[] = 'node-teaser'; // Node is displayed as teaser.
176 }
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
180 }
181
182 /**
183 * Override or insert variables into the comment templates.
184 *
185 * @param $vars
186 * An array of variables to pass to the theme template.
187 * @param $hook
188 * The name of the template being rendered ("comment" in this case.)
189 */
190 function zen_preprocess_comment(&$vars, $hook) {
191 include_once './' . drupal_get_path('theme', 'zen') . '/template.comment.inc';
192 _zen_preprocess_comment($vars, $hook);
193 }
194
195 /**
196 * Override or insert variables into the block templates.
197 *
198 * @param $vars
199 * An array of variables to pass to the theme template.
200 * @param $hook
201 * The name of the template being rendered ("block" in this case.)
202 */
203 function zen_preprocess_block(&$vars, $hook) {
204 $block = $vars['block'];
205
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'];
213
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';
220 }
221
222 // Render block classes.
223 $vars['classes'] = implode(' ', $classes);
224 }
225
226 /**
227 * Converts a string to a suitable html ID attribute.
228 *
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:
231 *
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.
235 *
236 * @param $string
237 * The string
238 * @return
239 * The converted string
240 */
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;
247 }
248 return $string;
249 }