';
return $breadcrumbs;
}
}
function zurb_foundation_field($variables) {
$output = '';
// Render the label, if it's not hidden.
if (!$variables['label_hidden']) {
$output .= '
' . $variables['label'] . ':
';
}
// Edit module requires some extra wrappers to work.
if (module_exists('edit')) {
$output .= '
';
return $output;
}
/**
* Implements theme_links() targeting the main menu specifically.
* Formats links for Top Bar http://foundation.zurb.com/docs/components/top-bar.html
*/
function zurb_foundation_links__topbar_main_menu($variables) {
// We need to fetch the links ourselves because we need the entire tree.
$links = menu_tree_output(menu_tree_all_data(variable_get('menu_main_links_source', 'main-menu')));
$output = _zurb_foundation_links($links);
$variables['attributes']['class'][] = 'left';
return '
' . $output . '
';
}
/**
* Implements theme_links() targeting the secondary menu specifically.
* Formats links for Top Bar http://foundation.zurb.com/docs/components/top-bar.html
*/
function zurb_foundation_links__topbar_secondary_menu($variables) {
// We need to fetch the links ourselves because we need the entire tree.
$links = menu_tree_output(menu_tree_all_data(variable_get('menu_secondary_links_source', 'user-menu')));
$output = _zurb_foundation_links($links);
$variables['attributes']['class'][] = 'right';
return '
' . $output . '
';
}
/**
* Helper function to output a Drupal menu as a Foundation Top Bar.
*
* @param array
* An array of menu links.
*
* @return string
* A rendered list of links, with no
or wrapper.
*
* @see zurb_foundation_links__system_main_menu()
* @see zurb_foundation_links__system_secondary_menu()
*/
function _zurb_foundation_links($links) {
$output = '';
foreach (element_children($links) as $key) {
$output .= _zurb_foundation_render_link($links[$key]);
}
return $output;
}
/**
* Helper function to recursively render sub-menus.
*
* @param array
* An array of menu links.
*
* @return string
* A rendered list of links, with no
or wrapper.
*
* @see _zurb_foundation_links()
*/
function _zurb_foundation_render_link($link) {
$output = '';
// This is a duplicate link that won't get the dropdown class and will only
// show up in small-screen.
$small_link = $link;
if (!empty($link['#below'])) {
$link['#attributes']['class'][] = 'has-dropdown';
}
// Render top level and make sure we have an actual link.
if (!empty($link['#href'])) {
$rendered_link = NULL;
// Foundation offers some of the same functionality as Special Menu Items;
// ie: Dividers and Labels in the top bar. So let's make sure that we
// render them the Foundation way.
if (module_exists('special_menu_items')) {
if ($link['#href'] === '') {
$rendered_link = '';
}
else if ($link['#href'] === '') {
$link['#attributes']['class'][] = 'divider';
$rendered_link = '';
}
}
// If this item is active and/or in the active trail, add necessary classes.
$active_classes = _zurb_foundation_in_active_trail($link['#href']);
if (isset($link['#attributes']['class'])) {
$link['#attributes']['class'] = array_merge($link['#attributes']['class'], $active_classes);
}
else {
$link['#attributes']['class'] = $active_classes;
}
// Test for localization options and apply them if they exist.
if (isset($link['#localized_options']['attributes']) && is_array($link['#localized_options']['attributes'])) {
$link['#attributes'] = array_merge($link['#attributes'], $link['#localized_options']['attributes']);
}
// If this item is in the active trail, merge the active-trail class into
// the #localized_options.
if (in_array('active-trail', $active_classes)) {
if(isset($link['#localized_options']['attributes']['class'])) {
$link['#localized_options']['attributes']['class'][] = 'active-trail';
}
else {
$link['#localized_options']['attributes']['class'] = array('active-trail');
}
}
// Only render our link now that all options have been folded into the
// #localized_options array.
if (!isset($rendered_link)) {
$rendered_link = theme('zurb_foundation_menu_link', array('link' => $link));
}
$output .= '
' . $rendered_link;
// Build lower menu levels
if (!empty($link['#below'])) {
// Add repeated link under the dropdown for small-screen.
$small_link['#attributes']['class'][] = 'show-for-small';
$sub_menu = '
' . l($link['#title'], $link['#href'], $link['#localized_options']);
// Build sub nav recursively.
foreach ($link['#below'] as $sub_link) {
if (!empty($sub_link['#href'])) {
$sub_menu .= _zurb_foundation_render_link($sub_link);
}
}
$output .= '
' . $sub_menu . '
';
}
$output .= '
';
}
return $output;
}
/**
* Checks whether an item is active or in the active trail.
*
* This is based on the code in the core toolbar module
* /modules/toolbar/toolbar.module function toolbar_in_active_trail($path)
*
* @param
* The path of a menu item we're evaluating
*
* @return
* An array of classes if active or in the active trail.
* An empty array if not active or in the active trail.
*
* @todo
* Look at migrating to a menu system level function.
*/
function _zurb_foundation_in_active_trail($link_path) {
$classes = array();
$active_paths = array();
// Don't waste cycles: if we're on the front page, we're either active or not
// and we don't need to look at the rest of the tree.
if (drupal_is_front_page()) {
if ($link_path == '') {
$classes[] = 'active';
}
return $classes;
}
// If the current page matches the item path, it's active and we don't need to
// look further. Comment out the return statement to have both 'active' and
// 'active-trail' classes applied to the item for the current page.
if ($link_path == current_path()) {
$classes[] = 'active';
return $classes;
}
// If we're not on the front page and the current link is not the current page,
// The we need to check the whole active trail. Since Drupal caches the result
// of menu_get_active_trail(), this is not too costly.
$active_trail = menu_get_active_trail();
$front = array_shift($active_trail);
foreach ($active_trail as $item) {
$active_paths[$item['link_path']] = TRUE;
}
if (!empty($active_paths[$link_path])) {
$classes[] = 'active-trail';
}
return $classes;
}
/**
* Theme function to render a single top bar menu link.
*/
function theme_zurb_foundation_menu_link($variables) {
$link = $variables['link'];
return l($link['#title'], $link['#href'], $link['#localized_options']);
}
/*
* Implements hook_preprocess_block()
*/
function zurb_foundation_preprocess_block(&$variables) {
// Convenience variable for block headers.
$title_class = &$variables['title_attributes_array']['class'];
// Generic block header class.
$title_class[] = 'block-title';
// In the header region visually hide block titles.
if ($variables['block']->region == 'header') {
$title_class[] = 'element-invisible';
}
// Add a unique class for each block for styling.
$variables['classes_array'][] = $variables['block_html_id'];
// Add classes based on region.
switch ($variables['elements']['#block']->region) {
// Clear blocks in this region
case 'sidebar_first':
$variables['classes_array'][] = 'clearfix';
break;
// Add a striping class & clear blocks in this region
case 'sidebar_second':
$variables['classes_array'][] = 'block-' . $variables['zebra'];
$variables['classes_array'][] = 'clearfix';
break;
case 'header':
$variables['classes_array'][] = 'header';
break;
default;
}
}
/**
* Implements template_preprocess_field().
*/
function zurb_foundation_preprocess_field(&$variables) {
$variables['title_attributes_array']['class'][] = 'field-label';
// Edit classes for taxonomy term reference fields.
if ($variables['field_type_css'] == 'taxonomy-term-reference') {
$variables['content_attributes_array']['class'][] = 'comma-separated';
}
// Convenience variables.
$name = $variables['element']['#field_name'];
$bundle = $variables['element']['#bundle'];
$mode = $variables['element']['#view_mode'];
$classes = &$variables['classes_array'];
$title_classes = &$variables['title_attributes_array']['class'];
$content_classes = &$variables['content_attributes_array']['class'];
$item_classes = array();
// Global field classes.
$classes[] = 'field-wrapper';
$content_classes[] = 'field-items';
$item_classes[] = 'field-item';
// Uncomment the lines below to see variables you can use to target a field.
// print 'Name: ' . $name . ' ';
// print 'Bundle: ' . $bundle . ' ';
// print 'Mode: ' . $mode .' ';
// Add specific classes to targeted fields.
if(isset($field)) {
switch ($mode) {
// All teasers.
case 'teaser':
switch ($field) {
// Teaser read more links.
case 'node_link':
$item_classes[] = 'more-link';
break;
// Teaser descriptions.
case 'body':
case 'field_description':
$item_classes[] = 'description';
break;
}
break;
}
}
// Check if exists
// switch ($field) {
// case 'field_authors':
// $title_classes[] = 'inline';
// $content_classes[] = 'authors';
// $item_classes[] = 'author';
// break;
// }
// Apply odd or even classes along with our custom classes to each item.
foreach ($variables['items'] as $delta => $item) {
$item_classes[] = $delta % 2 ? 'odd' : 'even';
$variables['item_attributes_array'][$delta]['class'] = $item_classes;
}
// Add class to a specific fields across content types.
switch ($variables['element']['#field_name']) {
case 'body':
$variables['classes_array'] = array('body');
break;
case 'field_summary':
$variables['classes_array'][] = 'text-teaser';
break;
case 'field_link':
case 'field_date':
// Replace classes entirely, instead of adding extra.
$variables['classes_array'] = array('text-content');
break;
case 'field_image':
// Replace classes entirely, instead of adding extra.
$variables['classes_array'] = array('image');
break;
default:
break;
}
// Add classes to body based on content type and view mode.
if ($variables['element']['#field_name'] == 'body') {
// Add classes to Foobar content type.
if ($variables['element']['#bundle'] == 'foobar') {
$variables['classes_array'][] = 'text-secondary';
}
// Add classes to other content types with view mode 'teaser';
elseif ($variables['element']['#view_mode'] == 'teaser') {
$variables['classes_array'][] = 'text-secondary';
}
// The rest is text-content.
else {
$variables['classes_array'][] = 'field';
}
}
}
/**
* Implements template_preprocess_html().
*
* Adds additional classes.
*/
function zurb_foundation_preprocess_html(&$variables) {
global $language;
// Clean up the lang attributes
$variables['html_attributes'] = 'lang="' . $language->language . '" dir="' . $language->dir . '"';
// Add language body class.
if (function_exists('locale')) {
$variables['classes_array'][] = 'lang-' . $variables['language']->language;
}
// @TODO Custom fonts from Google web-fonts
// $font = str_replace(' ', '+', theme_get_setting('zurb_foundation_font'));
// if (theme_get_setting('zurb_foundation_font')) {
// drupal_add_css('http://fonts.googleapis.com/css?family=' . $font , array('type' => 'external', 'group' => CSS_THEME));
// }
// Classes for body element. Allows advanced theming based on context
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':
$variables['classes_array'][] = 'views-page';
break;
case 'page_manager_page_execute':
case 'page_manager_node_view':
case 'page_manager_contact_site':
$variables['classes_array'][] = 'panels-page';
break;
}
}
}
/**
* Implements template_preprocess_node
*
* Add template suggestions and classes.
*/
function zurb_foundation_preprocess_node(&$variables) {
// Add node--node_type--view_mode.tpl.php suggestions.
$variables['theme_hook_suggestions'][] = 'node__' . $variables['type'] . '__' . $variables['view_mode'];
// Add node--view_mode.tpl.php suggestions.
$variables['theme_hook_suggestions'][] = 'node__' . $variables['view_mode'];
// Add a class for the view mode.
if (!$variables['teaser']) {
$variables['classes_array'][] = 'view-mode-' . $variables['view_mode'];
}
$variables['title_attributes_array']['class'][] = 'node-title';
}
/**
* Implements template_preprocess_page
*
* Add convenience variables and template suggestions.
*/
function zurb_foundation_preprocess_page(&$variables) {
// Add page--node_type.tpl.php suggestions
if (!empty($variables['node'])) {
$variables['theme_hook_suggestions'][] = 'page__' . $variables['node']->type;
}
$variables['logo_img'] = '';
if (!empty($variables['logo'])) {
$variables['logo_img'] = theme('image', array(
'path' => $variables['logo'],
'alt' => strip_tags($variables['site_name']) . ' ' . t('logo'),
'title' => strip_tags($variables['site_name']) . ' ' . t('Home'),
'attributes' => array(
'class' => array('logo'),
),
));
}
$variables['linked_logo'] = '';
if (!empty($variables['logo_img'])) {
$variables['linked_logo'] = l($variables['logo_img'], '', array(
'attributes' => array(
'rel' => 'home',
'title' => strip_tags($variables['site_name']) . ' ' . t('Home'),
),
'html' => TRUE,
));
}
$variables['linked_site_name'] = '';
if (!empty($variables['site_name'])) {
$variables['linked_site_name'] = l($variables['site_name'], '', array(
'attributes' => array(
'rel' => 'home',
'title' => strip_tags($variables['site_name']) . ' ' . t('Home'),
),
));
}
// Top bar.
if ($variables['top_bar'] = theme_get_setting('zurb_foundation_top_bar_enable')) {
$top_bar_classes = array();
if (theme_get_setting('zurb_foundation_top_bar_grid')) {
$top_bar_classes[] = 'contain-to-grid';
}
if (theme_get_setting('zurb_foundation_top_bar_sticky')) {
$top_bar_classes[] = 'sticky';
}
if ($variables['top_bar'] == 2) {
$top_bar_classes[] = 'show-for-small';
}
$variables['top_bar_classes'] = implode(' ', $top_bar_classes);
$variables['top_bar_menu_text'] = check_plain(theme_get_setting('zurb_foundation_top_bar_menu_text'));
$top_bar_options = array();
if (!theme_get_setting('zurb_foundation_top_bar_custom_back_text')) {
$top_bar_options[] = 'custom_back_text:false';
}
if ($back_text = check_plain(theme_get_setting('zurb_foundation_top_bar_back_text'))) {
if ($back_text !== 'Back') {
$top_bar_options[] = "back_text:'{$back_text}'";
}
}
if (!theme_get_setting('zurb_foundation_top_bar_is_hover')) {
$top_bar_options[] = 'is_hover:false';
}
if (!theme_get_setting('zurb_foundation_top_bar_scrolltop')) {
$top_bar_options[] = 'scrolltop:false';
}
$variables['top_bar_options'] = ' data-options="' . implode('; ', $top_bar_options) . '"';
}
// Alternative header.
// This is what will show up if the top bar is disabled or enabled only for
// mobile.
if ($variables['alt_header'] = ($variables['top_bar'] != 1)) {
// Hide alt header on mobile if using top bar in mobile.
$variables['alt_header_classes'] = $variables['top_bar'] == 2 ? ' hide-for-small' : '';
}
// Menus for alternative header.
$variables['alt_main_menu'] = '';
if (!empty($variables['main_menu'])) {
$variables['alt_main_menu'] = theme('links__system_main_menu', array(
'links' => $variables['main_menu'],
'attributes' => array(
'id' => 'main-menu-links',
'class' => array('links', 'inline-list', 'clearfix'),
),
'heading' => array(
'text' => t('Main menu'),
'level' => 'h2',
'class' => array('element-invisible'),
),
));
}
$variables['alt_secondary_menu'] = '';
if (!empty($variables['secondary_menu'])) {
$variables['alt_secondary_menu'] = theme('links__system_secondary_menu', array(
'links' => $variables['secondary_menu'],
'attributes' => array(
'id' => 'secondary-menu-links',
'class' => array('links', 'clearfix'),
),
'heading' => array(
'text' => t('Secondary menu'),
'level' => 'h2',
'class' => array('element-invisible'),
),
));
}
// Top bar menus.
$variables['top_bar_main_menu'] = '';
if (!empty($variables['main_menu'])) {
$variables['top_bar_main_menu'] = theme('links__topbar_main_menu', array(
'links' => $variables['main_menu'],
'attributes' => array(
'id' => 'main-menu',
'class' => array('main-nav'),
),
'heading' => array(
'text' => t('Main menu'),
'level' => 'h2',
'class' => array('element-invisible'),
),
));
}
$variables['top_bar_secondary_menu'] = '';
if (!empty($variables['secondary_menu'])) {
$variables['top_bar_secondary_menu'] = theme('links__topbar_secondary_menu', array(
'links' => $variables['secondary_menu'],
'attributes' => array(
'id' => 'secondary-menu',
'class' => array('secondary', 'link-list'),
),
'heading' => array(
'text' => t('Secondary menu'),
'level' => 'h2',
'class' => array('element-invisible'),
),
));
}
// Messages in modal.
$variables['zurb_foundation_messages_modal'] = theme_get_setting('zurb_foundation_messages_modal');
// Convenience variables
if (!empty($variables['page']['sidebar_first'])){
$left = $variables['page']['sidebar_first'];
}
if (!empty($variables['page']['sidebar_second'])) {
$right = $variables['page']['sidebar_second'];
}
// Dynamic sidebars
if (!empty($left) && !empty($right)) {
$variables['main_grid'] = 'large-6 push-3';
$variables['sidebar_first_grid'] = 'large-3 pull-6';
$variables['sidebar_sec_grid'] = 'large-3';
} elseif (empty($left) && !empty($right)) {
$variables['main_grid'] = 'large-9';
$variables['sidebar_first_grid'] = '';
$variables['sidebar_sec_grid'] = 'large-3';
} elseif (!empty($left) && empty($right)) {
$variables['main_grid'] = 'large-9 push-3';
$variables['sidebar_first_grid'] = 'large-3 pull-9';
$variables['sidebar_sec_grid'] = '';
} else {
$variables['main_grid'] = 'large-12';
$variables['sidebar_first_grid'] = '';
$variables['sidebar_sec_grid'] = '';
}
// Ensure modal reveal behavior if modal messages are enabled.
if(theme_get_setting('zurb_foundation_messages_modal')) {
drupal_add_js(drupal_get_path('theme', 'zurb_foundation') . '/js/behavior/reveal.js');
}
}
/**
* Implements hook_css_alter()
*/
function zurb_foundation_css_alter(&$css) {
// Remove defaults.css file.
unset($css[drupal_get_path('module', 'system') . '/system.menus.css']);
// Remove Drupal core CSS.
if (theme_get_setting('zurb_foundation_disable_core_css')) {
foreach($css as $path => $values) {
if(strpos($path, 'modules/') === 0) {
unset($css[$path]);
}
}
}
}
/**
* Replace Drupal pagers with Foundation pagers.
*/
function zurb_foundation_pager($variables) {
$tags = $variables['tags'];
$element = $variables['element'];
$parameters = $variables['parameters'];
$quantity = $variables['quantity'];
global $pager_page_array, $pager_total;
// Calculate various markers within this pager piece:
// Middle is used to "center" pages around the current page.
$pager_middle = ceil($quantity / 2);
// Current is the page we are currently paged to.
$pager_current = $pager_page_array[$element] + 1;
// First is the first page listed by this pager piece (re-quantify).
$pager_first = $pager_current - $pager_middle + 1;
// Last is the last page listed by this pager piece (re-quantify)
$pager_last = $pager_current + $quantity - $pager_middle;
// Max is the maximum page number.
$pager_max = $pager_total[$element];
// End of marker calculations.
// Prepare for generation loop.
$i = $pager_first;
if ($pager_last > $pager_max) {
// Adjust "center" if at end of query.
$i = $i + ($pager_max - $pager_last);
$pager_last = $pager_max;
}
if ($i <= 0) {
// Adjust "center" if at start of query.
$pager_last = $pager_last + (1 - $i);
$i = 1;
}
// End of generation loop preparation.
$li_first = theme('pager_first', array('text' => (isset($tags[0]) ? $tags[0] : t('« first')), 'element' => $element, 'parameters' => $parameters));
$li_previous = theme('pager_previous', array('text' => (isset($tags[1]) ? $tags[1] : t('‹ previous')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
$li_next = theme('pager_next', array('text' => (isset($tags[3]) ? $tags[3] : t('next ›')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
$li_last = theme('pager_last', array('text' => (isset($tags[4]) ? $tags[4] : t('last »')), 'element' => $element, 'parameters' => $parameters));
if ($pager_total[$element] > 1) {
if ($li_first) {
$items[] = array(
'class' => array('arrow'),
'data' => $li_first,
);
}
if ($li_previous) {
$items[] = array(
'class' => array('arrow'),
'data' => $li_previous,
);
}
// When there is more than one page, create the pager list.
if ($i != $pager_max) {
if ($i > 1) {
$items[] = array(
'class' => array('unavailable'),
'data' => '…',
);
}
// Now generate the actual pager piece.
for (; $i <= $pager_last && $i <= $pager_max; $i++) {
if ($i < $pager_current) {
$items[] = array(
'data' => theme('pager_previous', array('text' => $i, 'element' => $element, 'interval' => ($pager_current - $i), 'parameters' => $parameters)),
);
}
if ($i == $pager_current) {
$items[] = array(
'class' => array('current'),
'data' => '' . $i . '',
);
}
if ($i > $pager_current) {
$items[] = array(
'data' => theme('pager_next', array('text' => $i, 'element' => $element, 'interval' => ($i - $pager_current), 'parameters' => $parameters)),
);
}
}
if ($i < $pager_max) {
$items[] = array(
'class' => array('unavailable'),
'data' => '…',
);
}
}
// End generation.
if ($li_next) {
$items[] = array(
'class' => array('arrow'),
'data' => $li_next,
);
}
if ($li_last) {
$items[] = array(
'class' => array('arrow'),
'data' => $li_last,
);
}
$pager_links = array(
'#theme' => 'item_list',
'#items' => $items,
'#attributes' => array('class' => array('pagination', 'pager')),
);
if (theme_get_setting('zurb_foundation_pager_center')) {
$pager_links['#prefix'] = '
' . $pager_links;
}
}
/**
* Implements hook_theme().
*/
function zurb_foundation_theme() {
$return = array();
$return['zurb_foundation_reveal'] = array(
'variables' => array(
// The text to display in the link.
'text' => '',
// Whether the text uses HTML.
'html' => FALSE,
// Whether the reveal uses AJAX content.
// This can either be set to true, to use the link's href property or be
// a URL to load the content from. Note that setting this parameter will
// override the contents of the "reveal" variable.
'ajax' => FALSE,
// The path for the link's href property. This is only really useful if
// you want to set 'ajax' to TRUE (see above).
'path' => FALSE,
// The content for the reveal modal. Can be either a string or a render
// array.
'reveal' => '',
// Extra classes to add to the link.
'link_classes_array' => array('zurb-foundation-reveal'),
// Extra classes to add to the reveal modal.
'reveal_classes_array' => array('expand'),
),
'function' => 'theme_zurb_foundation_reveal',
);
$return['zurb_foundation_menu_link'] = array(
'variables' => array('link' => NULL),
'function' => 'theme_zurb_foundation_menu_link',
);
return $return;
}
/**
* Helper function to store and return markup for reveal modals on the page.
* This is necessary because we need to add all of the reveals to the bottom of
* the page to avoid unexpected behavior. For more information please refer to
* the official Zurb Foundation documentation.
*
* @param array
* A render array for a reveal modal to store.
* @return array
* An array of all reveal render arrays.
*
* @see theme_zurb_foundation_reveal()
*/
function _zurb_foundation_reveal($reveal = NULL) {
$reveals = &drupal_static(__FUNCTION__);
if (!isset($reveals)) {
$reveals = array();
}
if (isset($reveal)) {
$reveals[] = $reveal;
}
return $reveals;
}
/**
* Theme function to create Zurb Foundation reveal modals.
*
* @see zurb_foundation_theme()
* @see zurb_foundation_preprocess_region()
* @see _zurb_foundation_reveal()
*/
function theme_zurb_foundation_reveal($variables) {
// Generate unique IDs.
static $counter = 0;
// Prepare reveal markup.
$reveal_id = 'zf-reveal-' . ++$counter;
$variables['reveal_classes_array'][] = 'reveal-modal';
$reveal_classes = implode(' ', $variables['reveal_classes_array']);
// Render reveal contents if applicable.
if (is_array($variables['reveal'])) {
$variables['reveal'] = drupal_render($variables['reveal']);
}
$reveal = array(
'#markup' => $variables['reveal'],
'#prefix' => '