by JohnAlbin: Remove zen_field__no_wrapper() that was accidentally added
[project/zen.git] / template.php
1 <?php
2 /**
3 * @file
4 * Contains theme override functions and preprocess functions for the Zen theme.
5 *
6 * IMPORTANT WARNING: DO NOT MODIFY THIS FILE.
7 *
8 * The base Zen theme is designed to be easily extended by its sub-themes. You
9 * shouldn't modify this or any of the CSS or PHP files in the root zen/ folder.
10 * See the online documentation for more information:
11 * http://drupal.org/node/193318
12 */
13
14 // Auto-rebuild the theme registry during theme development.
15 if (theme_get_setting('zen_rebuild_registry') && !defined('MAINTENANCE_MODE')) {
16 // Rebuild .info data.
17 system_rebuild_theme_data();
18 // Rebuild theme registry.
19 drupal_theme_rebuild();
20 }
21
22
23 /**
24 * Implements HOOK_theme().
25 */
26 function zen_theme(&$existing, $type, $theme, $path) {
27 include_once './' . drupal_get_path('theme', 'zen') . '/zen-internals/template.theme-registry.inc';
28 return _zen_theme($existing, $type, $theme, $path);
29 }
30
31 /**
32 * Return a themed breadcrumb trail.
33 *
34 * @param $variables
35 * - title: An optional string to be used as a navigational heading to give
36 * context for breadcrumb links to screen-reader users.
37 * - title_attributes_array: Array of HTML attributes for the title. It is
38 * flattened into a string within the theme function.
39 * - breadcrumb: An array containing the breadcrumb links.
40 * @return
41 * A string containing the breadcrumb output.
42 */
43 function zen_breadcrumb($variables) {
44 $breadcrumb = $variables['breadcrumb'];
45 // Determine if we are to display the breadcrumb.
46 $show_breadcrumb = theme_get_setting('zen_breadcrumb');
47 if ($show_breadcrumb == 'yes' || $show_breadcrumb == 'admin' && arg(0) == 'admin') {
48
49 // Optionally get rid of the homepage link.
50 $show_breadcrumb_home = theme_get_setting('zen_breadcrumb_home');
51 if (!$show_breadcrumb_home) {
52 array_shift($breadcrumb);
53 }
54
55 // Return the breadcrumb with separators.
56 if (!empty($breadcrumb)) {
57 $breadcrumb_separator = theme_get_setting('zen_breadcrumb_separator');
58 $trailing_separator = $title = '';
59 if (theme_get_setting('zen_breadcrumb_title')) {
60 $item = menu_get_item();
61 if (!empty($item['tab_parent'])) {
62 // If we are on a non-default tab, use the tab's title.
63 $title = check_plain($item['title']);
64 }
65 else {
66 $title = drupal_get_title();
67 }
68 if ($title) {
69 $trailing_separator = $breadcrumb_separator;
70 }
71 }
72 elseif (theme_get_setting('zen_breadcrumb_trailing')) {
73 $trailing_separator = $breadcrumb_separator;
74 }
75
76 // Provide a navigational heading to give context for breadcrumb links to
77 // screen-reader users.
78 if (empty($variables['title'])) {
79 $variables['title'] = t('You are here');
80 }
81 // Unless overridden by a preprocess function, make the heading invisible.
82 if (!isset($variables['title_attributes_array']['class'])) {
83 $variables['title_attributes_array']['class'][] = 'element-invisible';
84 }
85 $heading = '<h2' . drupal_attributes($variables['title_attributes_array']) . '>' . $variables['title'] . '</h2>';
86
87 return '<div class="breadcrumb">' . $heading . implode($breadcrumb_separator, $breadcrumb) . $trailing_separator . $title . '</div>';
88 }
89 }
90 // Otherwise, return an empty string.
91 return '';
92 }
93
94 /**
95 * Override or insert variables into the html template.
96 *
97 * @param $variables
98 * An array of variables to pass to the theme template.
99 * @param $hook
100 * The name of the template being rendered ("html" in this case.)
101 */
102 function zen_preprocess_html(&$variables, $hook) {
103 // Add paths needed for html5shim.
104 $variables['base_path'] = base_path();
105 $variables['path_to_zen'] = drupal_get_path('theme', 'zen');
106 $variables['add_html5_respond_js'] = theme_get_setting('zen_add_html5_respond_js');
107
108 // If the user is silly and enables Zen as the theme, add some styles.
109 if ($GLOBALS['theme'] == 'zen') {
110 include_once './' . $variables['path_to_zen'] . '/zen-internals/template.zen.inc';
111 _zen_preprocess_html($variables, $hook);
112 }
113
114 // Attributes for html element.
115 $variables['html_attributes_array'] = array(
116 'lang' => $variables['language']->language,
117 'dir' => $variables['language']->dir,
118 );
119
120 // Classes for body element. Allows advanced theming based on context
121 // (home page, node of certain type, etc.)
122 if (!$variables['is_front']) {
123 // Add unique class for each page.
124 $path = drupal_get_path_alias($_GET['q']);
125 // Add unique class for each website section.
126 list($section, ) = explode('/', $path, 2);
127 $arg = explode('/', $_GET['q']);
128 if ($arg[0] == 'node') {
129 if ($arg[1] == 'add') {
130 $section = 'node-add';
131 }
132 elseif (isset($arg[2]) && is_numeric($arg[1]) && ($arg[2] == 'edit' || $arg[2] == 'delete')) {
133 $section = 'node-' . $arg[2];
134 }
135 }
136 $variables['classes_array'][] = drupal_html_class('section-' . $section);
137 }
138 if (theme_get_setting('zen_wireframes')) {
139 $variables['classes_array'][] = 'with-wireframes'; // Optionally add the wireframes style.
140 }
141 // Store the menu item since it has some useful information.
142 $variables['menu_item'] = menu_get_item();
143 switch ($variables['menu_item']['page_callback']) {
144 case 'views_page':
145 // Is this a Views page?
146 $variables['classes_array'][] = 'page-views';
147 break;
148 case 'page_manager_page_execute':
149 case 'page_manager_node_view':
150 case 'page_manager_contact_site':
151 // Is this a Panels page?
152 $variables['classes_array'][] = 'page-panels';
153 break;
154 }
155 $variables['skip_link_anchor'] = theme_get_setting('zen_skip_link_anchor');
156 $variables['skip_link_text'] = theme_get_setting('zen_skip_link_text');
157 }
158
159 /**
160 * Override or insert variables into the html templates.
161 *
162 * @param $variables
163 * An array of variables to pass to the theme template.
164 * @param $hook
165 * The name of the template being rendered ("html" in this case.)
166 */
167 function zen_process_html(&$variables, $hook) {
168 // Flatten out html_attributes.
169 $variables['html_attributes'] = drupal_attributes($variables['html_attributes_array']);
170 }
171
172 /**
173 * Override or insert variables in the html_tag theme function.
174 */
175 function zen_process_html_tag(&$variables) {
176 $tag = &$variables['element'];
177
178 if ($tag['#tag'] == 'style' || $tag['#tag'] == 'script') {
179 // Remove redundant type attribute and CDATA comments.
180 unset($tag['#attributes']['type'], $tag['#value_prefix'], $tag['#value_suffix']);
181
182 // Remove media="all" but leave others unaffected.
183 if (isset($tag['#attributes']['media']) && $tag['#attributes']['media'] === 'all') {
184 unset($tag['#attributes']['media']);
185 }
186 }
187 }
188
189 /**
190 * Implement hook_html_head_alter().
191 */
192 function zen_html_head_alter(&$head) {
193 // Simplify the meta tag for character encoding.
194 $head['system_meta_content_type']['#attributes'] = array('charset' => str_replace('text/html; charset=', '', $head['system_meta_content_type']['#attributes']['content']));
195 }
196
197 /**
198 * Override or insert variables into the page template.
199 *
200 * @param $variables
201 * An array of variables to pass to the theme template.
202 * @param $hook
203 * The name of the template being rendered ("page" in this case.)
204 */
205 function zen_preprocess_page(&$variables, $hook) {
206 // Find the title of the menu used by the secondary links.
207 $secondary_links = variable_get('menu_secondary_links_source', 'user-menu');
208 if ($secondary_links) {
209 $menus = function_exists('menu_get_menus') ? menu_get_menus() : menu_list_system_menus();
210 $variables['secondary_menu_heading'] = $menus[$secondary_links];
211 }
212 else {
213 $variables['secondary_menu_heading'] = '';
214 }
215 }
216
217 /**
218 * Override or insert variables into the maintenance page template.
219 *
220 * @param $variables
221 * An array of variables to pass to the theme template.
222 * @param $hook
223 * The name of the template being rendered ("maintenance_page" in this case.)
224 */
225 function zen_preprocess_maintenance_page(&$variables, $hook) {
226 // Add paths needed or html5shim.
227 $variables['base_path'] = base_path();
228 $variables['path_to_zen'] = drupal_get_path('theme', 'zen');
229
230 // If Zen is the maintenance theme, add some styles.
231 if ($GLOBALS['theme'] == 'zen') {
232 include_once './' . drupal_get_path('theme', 'zen') . '/zen-internals/template.zen.inc';
233 _zen_preprocess_html($variables, $hook);
234 }
235
236 // Attributes for html element.
237 $variables['html_attributes_array'] = array(
238 'lang' => $variables['language']->language,
239 'dir' => $variables['language']->dir,
240 );
241 }
242
243 /**
244 * Override or insert variables into the maintenance page template.
245 *
246 * @param $variables
247 * An array of variables to pass to the theme template.
248 * @param $hook
249 * The name of the template being rendered ("maintenance_page" in this case.)
250 */
251 function zen_process_maintenance_page(&$variables, $hook) {
252 // Flatten out html_attributes.
253 $variables['html_attributes'] = drupal_attributes($variables['html_attributes_array']);
254 }
255
256 /**
257 * Override or insert variables into the node templates.
258 *
259 * @param $variables
260 * An array of variables to pass to the theme template.
261 * @param $hook
262 * The name of the template being rendered ("node" in this case.)
263 */
264 function zen_preprocess_node(&$variables, $hook) {
265 // Add $unpublished variable.
266 $variables['unpublished'] = (!$variables['status']) ? TRUE : FALSE;
267
268 // Add pubdate to submitted variable.
269 $variables['pubdate'] = '<time pubdate datetime="' . format_date($variables['node']->created, 'custom', 'c') . '">' . $variables['date'] . '</time>';
270 if ($variables['display_submitted']) {
271 $variables['submitted'] = t('Submitted by !username on !datetime', array('!username' => $variables['name'], '!datetime' => $variables['pubdate']));
272 }
273
274 // Add a class for the view mode.
275 if (!$variables['teaser']) {
276 $variables['classes_array'][] = 'view-mode-' . $variables['view_mode'];
277 }
278
279 // Add a class to show node is authored by current user.
280 if ($variables['uid'] && $variables['uid'] == $GLOBALS['user']->uid) {
281 $variables['classes_array'][] = 'node-by-viewer';
282 }
283
284 $variables['title_attributes_array']['class'][] = 'node-title';
285 }
286
287 /**
288 * Override or insert variables into the comment templates.
289 *
290 * @param $variables
291 * An array of variables to pass to the theme template.
292 * @param $hook
293 * The name of the template being rendered ("comment" in this case.)
294 */
295 function zen_preprocess_comment(&$variables, $hook) {
296 // If comment subjects are disabled, don't display them.
297 if (variable_get('comment_subject_field_' . $variables['node']->type, 1) == 0) {
298 $variables['title'] = '';
299 }
300
301 // Add pubdate to submitted variable.
302 $variables['pubdate'] = '<time pubdate datetime="' . format_date($variables['comment']->created, 'custom', 'c') . '">' . $variables['created'] . '</time>';
303 $variables['submitted'] = t('!username replied on !datetime', array('!username' => $variables['author'], '!datetime' => $variables['pubdate']));
304
305 // Zebra striping.
306 if ($variables['id'] == 1) {
307 $variables['classes_array'][] = 'first';
308 }
309 if ($variables['id'] == $variables['node']->comment_count) {
310 $variables['classes_array'][] = 'last';
311 }
312 $variables['classes_array'][] = $variables['zebra'];
313
314 $variables['title_attributes_array']['class'][] = 'comment-title';
315 }
316
317 /**
318 * Preprocess variables for region.tpl.php
319 *
320 * @param $variables
321 * An array of variables to pass to the theme template.
322 * @param $hook
323 * The name of the template being rendered ("region" in this case.)
324 */
325 function zen_preprocess_region(&$variables, $hook) {
326 // Sidebar regions get some extra classes and a common template suggestion.
327 if (strpos($variables['region'], 'sidebar_') === 0) {
328 $variables['classes_array'][] = 'column';
329 $variables['classes_array'][] = 'sidebar';
330 $variables['theme_hook_suggestions'][] = 'region__sidebar';
331 // Allow a region-specific template to override Zen's region--sidebar.
332 $variables['theme_hook_suggestions'][] = 'region__' . $variables['region'];
333 }
334 // Use a template with no wrapper for the content region.
335 elseif ($variables['region'] == 'content') {
336 $variables['theme_hook_suggestions'][] = 'region__no_wrapper';
337 }
338 }
339
340 /**
341 * Override or insert variables into the block templates.
342 *
343 * @param $variables
344 * An array of variables to pass to the theme template.
345 * @param $hook
346 * The name of the template being rendered ("block" in this case.)
347 */
348 function zen_preprocess_block(&$variables, $hook) {
349 // Use a template with no wrapper for the page's main content.
350 if ($variables['block_html_id'] == 'block-system-main') {
351 $variables['theme_hook_suggestions'][] = 'block__no_wrapper';
352 }
353
354 // Classes describing the position of the block within the region.
355 if ($variables['block_id'] == 1) {
356 $variables['classes_array'][] = 'first';
357 }
358 // The last_in_region property is set in zen_page_alter().
359 if (isset($variables['block']->last_in_region)) {
360 $variables['classes_array'][] = 'last';
361 }
362 $variables['classes_array'][] = $variables['block_zebra'];
363
364 $variables['title_attributes_array']['class'][] = 'block-title';
365 }
366
367 /**
368 * Override or insert variables into the block templates.
369 *
370 * @param $variables
371 * An array of variables to pass to the theme template.
372 * @param $hook
373 * The name of the template being rendered ("block" in this case.)
374 */
375 function zen_process_block(&$variables, $hook) {
376 // Drupal 7 should use a $title variable instead of $block->subject.
377 $variables['title'] = $variables['block']->subject;
378 }
379
380 /**
381 * Implements hook_page_alter().
382 *
383 * Look for the last block in the region. This is impossible to determine from
384 * within a preprocess_block function.
385 *
386 * @param $page
387 * Nested array of renderable elements that make up the page.
388 */
389 function zen_page_alter(&$page) {
390 // Look in each visible region for blocks.
391 foreach (system_region_list($GLOBALS['theme'], REGIONS_VISIBLE) as $region => $name) {
392 if (!empty($page[$region])) {
393 // Find the last block in the region.
394 $blocks = array_reverse(element_children($page[$region]));
395 while ($blocks && !isset($page[$region][$blocks[0]]['#block'])) {
396 array_shift($blocks);
397 }
398 if ($blocks) {
399 $page[$region][$blocks[0]]['#block']->last_in_region = TRUE;
400 }
401 }
402 }
403 }
404
405 /**
406 * Implements hook_form_BASE_FORM_ID_alter().
407 *
408 * Prevent user-facing field styling from screwing up node edit forms by
409 * renaming the classes on the node edit form's field wrappers.
410 */
411 function zen_form_node_form_alter(&$form, &$form_state, $form_id) {
412 // Remove if #1245218 is backported to D7 core.
413 foreach (array_keys($form) as $item) {
414 if (strpos($item, 'field_') === 0) {
415 if (!empty($form[$item]['#attributes']['class'])) {
416 foreach ($form[$item]['#attributes']['class'] as &$class) {
417 if (strpos($class, 'field-type-') === 0 || strpos($class, 'field-name-') === 0) {
418 // Make the class different from that used in theme_field().
419 $class = 'form-' . $class;
420 }
421 }
422 }
423 }
424 }
425 }