' . $variables['breadcrumb_separator'] . ''; // Build the breadcrumb trail. $output = ''; } return $output; } /** * Override or insert variables into the html template. * * @param $variables * An array of variables to pass to the theme template. * @param $hook * The name of the template being rendered. This is usually "html", but can * also be "maintenance_page" since zen_preprocess_maintenance_page() calls * this function to have consistent variables. */ function zen_preprocess_html(&$variables, $hook) { // Add variables and paths needed for HTML5 and responsive support. $variables['base_path'] = base_path(); $variables['path_to_zen'] = drupal_get_path('theme', 'zen'); // Get settings for HTML5 and responsive support. array_filter() removes // items from the array that have been disabled. $meta = array_filter((array) theme_get_setting('zen_meta')); $variables['add_html5_shim'] = in_array('html5', $meta); $variables['default_mobile_metatags'] = in_array('meta', $meta); // If the user is silly and enables Zen as the theme, add some styles. if ($GLOBALS['theme'] == 'zen') { include_once './' . $variables['path_to_zen'] . '/zen-internals/template.zen.inc'; _zen_preprocess_html($variables, $hook); } // Attributes for html element. $variables['html_attributes_array'] = array( 'lang' => $variables['language']->language, 'dir' => $variables['language']->dir, ); // Send X-UA-Compatible HTTP header to force IE to use the most recent // rendering engine. // This also prevents the IE compatibility mode button to appear when using // conditional classes on the html tag. if (is_null(drupal_get_http_header('X-UA-Compatible'))) { drupal_add_http_header('X-UA-Compatible', 'IE=edge'); } $variables['skip_link_anchor'] = check_plain(theme_get_setting('zen_skip_link_anchor')); $variables['skip_link_text'] = check_plain(theme_get_setting('zen_skip_link_text')); // Return early, so the maintenance page does not call any of the code below. if ($hook != 'html') { return; } // Serialize RDF Namespaces into an RDFa 1.1 prefix attribute. if ($variables['rdf_namespaces']) { $prefixes = array(); foreach (explode("\n ", ltrim($variables['rdf_namespaces'])) as $namespace) { // Remove xlmns: and ending quote and fix prefix formatting. $prefixes[] = str_replace('="', ': ', substr($namespace, 6, -1)); } $variables['rdf_namespaces'] = ' prefix="' . implode(' ', $prefixes) . '"'; } // Classes for body element. Allows advanced theming based on context // (home page, node of certain type, etc.) if (!$variables['is_front']) { // Add unique class for each page. $path = drupal_get_path_alias($_GET['q']); // Add unique class for each website section. list($section, ) = explode('/', $path, 2); $arg = explode('/', $_GET['q']); if ($arg[0] == 'node' && isset($arg[1])) { if ($arg[1] == 'add') { $section = 'node-add'; } elseif (isset($arg[2]) && is_numeric($arg[1]) && ($arg[2] == 'edit' || $arg[2] == 'delete')) { $section = 'node-' . $arg[2]; } } $variables['classes_array'][] = drupal_html_class('section-' . $section); } // Store the menu item since it has some useful information. $variables['menu_item'] = menu_get_item(); if ($variables['menu_item']) { switch ($variables['menu_item']['page_callback']) { case 'views_page': // Is this a Views page? $variables['classes_array'][] = 'page-views'; break; case 'page_manager_blog': case 'page_manager_blog_user': case 'page_manager_contact_site': case 'page_manager_contact_user': case 'page_manager_node_add': case 'page_manager_node_edit': case 'page_manager_node_view_page': case 'page_manager_page_execute': case 'page_manager_poll': case 'page_manager_search_page': case 'page_manager_term_view_page': case 'page_manager_user_edit_page': case 'page_manager_user_view_page': // Is this a Panels page? $variables['classes_array'][] = 'page-panels'; break; } } } /** * Override or insert variables into the html templates. * * @param $variables * An array of variables to pass to the theme template. * @param $hook * The name of the template being rendered ("html" in this case.) */ function zen_process_html(&$variables, $hook) { // Flatten out html_attributes. $variables['html_attributes'] = drupal_attributes($variables['html_attributes_array']); } /** * Override or insert variables in the html_tag theme function. */ function zen_process_html_tag(&$variables) { $tag = &$variables['element']; if ($tag['#tag'] == 'style' || $tag['#tag'] == 'script') { // Remove redundant CDATA comments. unset($tag['#value_prefix'], $tag['#value_suffix']); // Remove redundant type attribute. if (isset($tag['#attributes']['type']) && $tag['#attributes']['type'] !== 'text/ng-template') { unset($tag['#attributes']['type']); } // Remove media="all" but leave others unaffected. if (isset($tag['#attributes']['media']) && $tag['#attributes']['media'] === 'all') { unset($tag['#attributes']['media']); } } } /** * Implement hook_html_head_alter(). */ function zen_html_head_alter(&$head) { // Simplify the meta tag for character encoding. if (isset($head['system_meta_content_type']['#attributes']['content'])) { $head['system_meta_content_type']['#attributes'] = array('charset' => str_replace('text/html; charset=', '', $head['system_meta_content_type']['#attributes']['content'])); } } /** * Override or insert variables into the page template. * * @param $variables * An array of variables to pass to the theme template. * @param $hook * The name of the template being rendered ("page" in this case.) */ function zen_preprocess_page(&$variables, $hook) { // Find the title of the menu used by the secondary links. $secondary_links = variable_get('menu_secondary_links_source', 'user-menu'); if ($secondary_links) { $menus = function_exists('menu_get_menus') ? menu_get_menus() : menu_list_system_menus(); $variables['secondary_menu_heading'] = isset($menus[$secondary_links]) ? $menus[$secondary_links] : ''; } else { $variables['secondary_menu_heading'] = ''; } } /** * Override or insert variables into the maintenance page template. * * @param $variables * An array of variables to pass to the theme template. * @param $hook * The name of the template being rendered ("maintenance_page" in this case.) */ function zen_preprocess_maintenance_page(&$variables, $hook) { zen_preprocess_html($variables, $hook); // There's nothing maintenance-related in zen_preprocess_page(). Yet. //zen_preprocess_page($variables, $hook); } /** * Override or insert variables into the maintenance page template. * * @param $variables * An array of variables to pass to the theme template. * @param $hook * The name of the template being rendered ("maintenance_page" in this case.) */ function zen_process_maintenance_page(&$variables, $hook) { zen_process_html($variables, $hook); // Ensure default regions get a variable. Theme authors often forget to remove // a deleted region's variable in maintenance-page.tpl. foreach (array('header', 'navigation', 'highlighted', 'help', 'content', 'sidebar_first', 'sidebar_second', 'footer', 'bottom') as $region) { if (!isset($variables[$region])) { $variables[$region] = ''; } } } /** * Override or insert variables into the node templates. * * @param $variables * An array of variables to pass to the theme template. * @param $hook * The name of the template being rendered ("node" in this case.) */ function zen_preprocess_node(&$variables, $hook) { // Add $unpublished variable. $variables['unpublished'] = (!$variables['status']) ? TRUE : FALSE; // Set preview variable to FALSE if it doesn't exist. $variables['preview'] = isset($variables['preview']) ? $variables['preview'] : FALSE; // Add pubdate to submitted variable. $variables['pubdate'] = ''; if ($variables['display_submitted']) { $variables['submitted'] = t('Submitted by !username on !datetime', array('!username' => $variables['name'], '!datetime' => $variables['pubdate'])); } // If the node is unpublished, add the "unpublished" watermark class. if ($variables['unpublished'] || $variables['preview']) { $variables['classes_array'][] = 'watermark__wrapper'; } // Add a class for the view mode. if (!$variables['teaser']) { $variables['classes_array'][] = 'view-mode-' . $variables['view_mode']; } // Add a class to show node is authored by current user. if ($variables['uid'] && $variables['uid'] == $GLOBALS['user']->uid) { $variables['classes_array'][] = 'node-by-viewer'; } } /** * Override or insert variables into the comment templates. * * @param $variables * An array of variables to pass to the theme template. * @param $hook * The name of the template being rendered ("comment" in this case.) */ function zen_preprocess_comment(&$variables, $hook) { // Add $unpublished variable. $variables['unpublished'] = ($variables['status'] == 'comment-unpublished') ? TRUE : FALSE; // Add $preview variable. $variables['preview'] = ($variables['status'] == 'comment-preview') ? TRUE : FALSE; // If comment subjects are disabled, don't display them. if (variable_get('comment_subject_field_' . $variables['node']->type, 1) == 0) { $variables['title'] = ''; } // Add pubdate to submitted variable. $variables['pubdate'] = ''; $variables['submitted'] = t('!username replied on !datetime', array('!username' => $variables['author'], '!datetime' => $variables['pubdate'])); // If the comment is unpublished/preview, add a "unpublished" watermark class. if ($variables['unpublished'] || $variables['preview']) { $variables['classes_array'][] = 'watermark__wrapper'; } // Zebra striping. if ($variables['id'] == 1) { $variables['classes_array'][] = 'first'; } if ($variables['id'] == $variables['node']->comment_count) { $variables['classes_array'][] = 'last'; } $variables['classes_array'][] = $variables['zebra']; // Add the comment__permalink class. $uri = entity_uri('comment', $variables['comment']); $uri_options = $uri['options'] + array('attributes' => array('class' => array('comment__permalink'), 'rel' => 'bookmark')); $variables['permalink'] = l(t('Permalink'), $uri['path'], $uri_options); // Remove core's permalink class and add the comment__title class. $variables['title_attributes_array']['class'][] = 'comment__title'; $uri_options = $uri['options'] + array('attributes' => array('rel' => 'bookmark')); $variables['title'] = l($variables['comment']->subject, $uri['path'], $uri_options); } /** * Preprocess variables for region.tpl.php * * @param $variables * An array of variables to pass to the theme template. * @param $hook * The name of the template being rendered ("region" in this case.) */ function zen_preprocess_region(&$variables, $hook) { // Use a template with no wrapper for the sidebar regions. if (strpos($variables['region'], 'sidebar_') === 0) { // Allow a region-specific template to override Zen's region--no-wrapper. array_unshift($variables['theme_hook_suggestions'], 'region__no_wrapper'); } // Use a template with no wrapper for the content region. elseif ($variables['region'] == 'content') { // Allow a region-specific template to override Zen's region--no-wrapper. array_unshift($variables['theme_hook_suggestions'], 'region__no_wrapper'); } // Add a BEM-style class for header region. elseif ($variables['region'] == 'header') { array_unshift($variables['classes_array'], 'header__region'); } } /** * Override or insert variables into the block templates. * * @param $variables * An array of variables to pass to the theme template. * @param $hook * The name of the template being rendered ("block" in this case.) */ function zen_preprocess_block(&$variables, $hook) { // Use a template with no wrapper for the page's main content. if ($variables['block_html_id'] == 'block-system-main') { $variables['theme_hook_suggestions'][] = 'block__no_wrapper'; } // Classes describing the position of the block within the region. if ($variables['block_id'] == 1) { $variables['classes_array'][] = 'first'; } // The last_in_region property is set in zen_page_alter(). if (isset($variables['block']->last_in_region)) { $variables['classes_array'][] = 'last'; } $variables['classes_array'][] = $variables['block_zebra']; $variables['title_attributes_array']['class'][] = 'block__title'; // Add Aria Roles via attributes. switch ($variables['block']->module) { case 'system': switch ($variables['block']->delta) { case 'main': // Note: the "main" role goes in the page.tpl, not here. break; case 'help': case 'powered-by': $variables['attributes_array']['role'] = 'complementary'; break; default: // Any other "system" block is a menu block. $variables['attributes_array']['role'] = 'navigation'; break; } break; case 'menu': case 'menu_block': case 'blog': case 'book': case 'comment': case 'forum': case 'shortcut': case 'statistics': $variables['attributes_array']['role'] = 'navigation'; break; case 'search': $variables['attributes_array']['role'] = 'search'; break; case 'help': case 'aggregator': case 'locale': case 'poll': case 'profile': $variables['attributes_array']['role'] = 'complementary'; break; case 'node': switch ($variables['block']->delta) { case 'syndicate': $variables['attributes_array']['role'] = 'complementary'; break; case 'recent': $variables['attributes_array']['role'] = 'navigation'; break; } break; case 'user': switch ($variables['block']->delta) { case 'login': $variables['attributes_array']['role'] = 'form'; break; case 'new': case 'online': $variables['attributes_array']['role'] = 'complementary'; break; } break; } } /** * Override or insert variables into the block templates. * * @param $variables * An array of variables to pass to the theme template. * @param $hook * The name of the template being rendered ("block" in this case.) */ function zen_process_block(&$variables, $hook) { // Drupal 7 should use a $title variable instead of $block->subject. $variables['title'] = isset($variables['block']->subject) ? $variables['block']->subject : ''; } /** * Implements hook_page_alter(). * * Look for the last block in the region. This is impossible to determine from * within a preprocess_block function. * * @param $page * Nested array of renderable elements that make up the page. */ function zen_page_alter(&$page) { // Look in each visible region for blocks. foreach (system_region_list($GLOBALS['theme'], REGIONS_VISIBLE) as $region => $name) { if (!empty($page[$region])) { // Find the last block in the region. $blocks = array_reverse(element_children($page[$region])); while ($blocks && !isset($page[$region][$blocks[0]]['#block'])) { array_shift($blocks); } if ($blocks) { $page[$region][$blocks[0]]['#block']->last_in_region = TRUE; } } } } /** * Implements hook_form_BASE_FORM_ID_alter(). * * Prevent user-facing field styling from screwing up node edit forms by * renaming the classes on the node edit form's field wrappers. */ function zen_form_node_form_alter(&$form, &$form_state, $form_id) { // Remove if #1245218 is backported to D7 core. foreach (array_keys($form) as $item) { if (strpos($item, 'field_') === 0) { if (!empty($form[$item]['#attributes']['class'])) { foreach ($form[$item]['#attributes']['class'] as &$class) { // Core bug: the field-type-text-with-summary class is used as a JS hook. if ($class != 'field-type-text-with-summary' && strpos($class, 'field-type-') === 0 || strpos($class, 'field-name-') === 0) { // Make the class different from that used in theme_field(). $class = 'form-' . $class; } } } } } } /** * Returns HTML for primary and secondary local tasks. * * @ingroup themeable */ function zen_menu_local_tasks(&$variables) { $output = ''; if (!empty($variables['primary'])) { $variables['primary']['#prefix'] = '