/** * Pre-processes variables for the "bootstrap_dropdown" theme hook. * * See theme function for list of available variables. * * @see bootstrap_bootstrap_dropdown() * * @ingroup theme_preprocess */ function bootstrap_preprocess_bootstrap_dropdown(&$variables) { $element =& $variables['element']; // Provide defaults. $element += array('#wrapper_attributes' => NULL, '#attributes' => NULL, '#alignment' => NULL, '#toggle' => NULL, '#items' => NULL); // Dropdown vertical alignment. $element['#wrapper_attributes']['class'][] = 'dropdown'; if ($element['#alignment'] === 'up' || is_array($element['#alignment']) && in_array('up', $element['#alignment'])) { $element['#wrapper_attributes']['class'][] = 'dropup'; } if (isset($element['#toggle'])) { if (is_string($element['#toggle'])) { $element['#toggle'] = array('#theme' => 'link__bootstrap_dropdown__toggle', '#text' => _bootstrap_filter_xss($element['#toggle']), '#path' => '#', '#options' => array('attributes' => array(), 'html' => TRUE, 'external' => TRUE)); } if (isset($element['#toggle']['#options']['attributes'])) { $element['#toggle']['#options']['attributes']['class'][] = 'dropdown-toggle'; $element['#toggle']['#options']['attributes']['data-toggle'] = 'dropdown'; } else { $element['#toggle']['#attributes']['class'][] = 'dropdown-toggle'; $element['#toggle']['#attributes']['data-toggle'] = 'dropdown'; } } // Menu items. $element['#attributes']['role'] = 'menu'; $element['#attributes']['class'][] = 'dropdown-menu'; if ($element['#alignment'] === 'right' || is_array($element['#alignment']) && in_array('right', $element['#alignment'])) { $element['#attributes']['class'][] = 'dropdown-menu-right'; } }
/** * Overrides theme_menu_link() for book module. */ function bootstrap_menu_link__book_toc(array $variables) { $element = $variables['element']; $sub_menu = drupal_render($element['#below']); $title = $element['#title']; $href = $element['#href']; $options = !empty($element['#localized_options']) ? $element['#localized_options'] : array(); $attributes = !empty($element['#attributes']) ? $element['#attributes'] : array(); $attributes['role'] = 'presentation'; // Header. $link = TRUE; if ($title && $href === FALSE) { $attributes['class'][] = 'dropdown-header'; $link = FALSE; } elseif ($title === FALSE && $href === FALSE) { $attributes['class'][] = 'divider'; $link = FALSE; } elseif (($href == $_GET['q'] || $href == '<front>' && drupal_is_front_page()) && empty($options['language'])) { $attributes['class'][] = 'active'; } // Filter the title if the "html" is set, otherwise l() will automatically // sanitize using check_plain(), so no need to call that here. if (!empty($options['html'])) { $title = _bootstrap_filter_xss($title); } // Convert to a link. if ($link) { $title = l($title, $href, $options); } return '<li' . drupal_attributes($attributes) . '>' . $title . $sub_menu . "</li>\n"; }
/** * Returns HTML for status and/or error messages, grouped by type. * * An invisible heading identifies the messages for assistive technology. * Sighted users see a colored box. See http://www.w3.org/TR/WCAG-TECHS/H69.html * for info. * * @param array $variables * An associative array containing: * - display: (optional) Set to 'status' or 'error' to display only messages * of that type. * * @return string * The constructed HTML. * * @see theme_status_messages() * * @ingroup theme_functions */ function bootstrap_status_messages($variables) { $display = $variables['display']; $output = ''; $status_heading = array('status' => t('Status message'), 'error' => t('Error message'), 'warning' => t('Warning message'), 'info' => t('Informative message')); // Map Drupal message types to their corresponding Bootstrap classes. // @see http://twitter.github.com/bootstrap/components.html#alerts $status_class = array('status' => 'success', 'error' => 'danger', 'warning' => 'warning', 'info' => 'info'); // Retrieve messages. $message_list = drupal_get_messages($display); // Allow the disabled_messages module to filter the messages, if enabled. if (module_exists('disable_messages') && variable_get('disable_messages_enable', '1')) { $message_list = disable_messages_apply_filters($message_list); } foreach ($message_list as $type => $messages) { $class = isset($status_class[$type]) ? ' alert-' . $status_class[$type] : ''; $output .= "<div class=\"alert alert-block{$class} messages {$type}\">\n"; $output .= " <a class=\"close\" data-dismiss=\"alert\" href=\"#\">×</a>\n"; if (!empty($status_heading[$type])) { $output .= '<h4 class="element-invisible">' . _bootstrap_filter_xss($status_heading[$type]) . "</h4>\n"; } if (count($messages) > 1) { $output .= " <ul>\n"; foreach ($messages as $message) { $output .= ' <li>' . _bootstrap_filter_xss($message) . "</li>\n"; } $output .= " </ul>\n"; } else { $output .= _bootstrap_filter_xss($messages[0]); } $output .= "</div>\n"; } return $output; }
/** * Returns HTML for a single local action link. * * @param array $variables * An associative array containing: * - element: A render element containing: * - #link: A menu link array with 'title', 'href', and 'localized_options' * keys. * * @return string * The constructed HTML. * * @see theme_menu_local_action() * * @ingroup theme_functions */ function bootstrap_menu_local_action($variables) { $link = $variables['element']['#link']; $title = $link['title']; $icon = _bootstrap_iconize_text($title); $href = !empty($link['href']) ? $link['href'] : FALSE; $options = isset($link['localized_options']) ? $link['localized_options'] : array(); // Format the action link. if ($href) { // Turn link into a mini-button and colorize based on title. if ($class = _bootstrap_colorize_text($title)) { if (!isset($options['attributes']['class'])) { $options['attributes']['class'] = array(); } $string = is_string($options['attributes']['class']); if ($string) { $options['attributes']['class'] = explode(' ', $options['attributes']['class']); } $options['attributes']['class'][] = 'btn'; $options['attributes']['class'][] = 'btn-xs'; $options['attributes']['class'][] = 'btn-' . $class; if ($string) { $options['attributes']['class'] = implode(' ', $options['attributes']['class']); } } // Force HTML so we can render any icon that may have been added. $options['html'] = !empty($options['html']) || !empty($icon) ? TRUE : FALSE; } // Filter the title if the "html" is set, otherwise l() will automatically // sanitize using check_plain(), so no need to call that here. if (!empty($options['html'])) { $title = _bootstrap_filter_xss($title); } return $href ? l($icon . $title, $href, $options) : $icon . $title; }
/** * Processes variables for the "bootstrap_modal" theme hook. * * See template for list of available variables. * * @see bootstrap-modal.tpl.php * * @ingroup theme_process */ function bootstrap_process_bootstrap_modal(&$variables) { $variables['attributes'] = drupal_attributes($variables['attributes']); $variables['dialog_attributes'] = drupal_attributes($variables['dialog_attributes']); $variables['heading'] = _bootstrap_filter_xss(render($variables['heading'])); $variables['body'] = render($variables['body']); $variables['footer'] = render($variables['footer']); }
/** * Processes variables for the "block" theme hook. * * See template for list of available variables. * * @see block.tpl.php * * @ingroup theme_process */ function bootstrap_process_block(&$variables) { // Drupal 7 should use a $title variable instead of $block->subject. // Don't override an existing "title" variable, some modules may already it. if (!isset($variables['title'])) { $variables['title'] = $variables['block']->subject; } $variables['title'] = _bootstrap_filter_xss($variables['title']); }
/** * Processes variables for the "bootstrap_panel" theme hook. * * See template for list of available variables. * * @see bootstrap-panel.tpl.php * * @ingroup theme_process */ function bootstrap_process_bootstrap_panel(&$variables) { $variables['attributes'] = drupal_attributes($variables['attributes']); if (!empty($variables['title'])) { $variables['title'] = _bootstrap_filter_xss(render($variables['title'])); } if (!empty($variables['description'])) { $variables['description'] = _bootstrap_filter_xss(render($variables['description'])); } }
/** * Returns HTML for a button form element. * * @param array $variables * An associative array containing: * - element: An associative array containing the properties of the element. * Properties used: #attributes, #button_type, #name, #value. * * @return string * The constructed HTML. * * @see theme_button() * * @ingroup theme_functions */ function bootstrap_button($variables) { $element = $variables['element']; // Allow button text to be appear hidden. // @see https://www.drupal.org/node/2327437 $text = !empty($element['#hide_text']) ? '<span class="element-invisible">' . $element['#value'] . '</span>' : $element['#value']; // Add icons before or after the value. // @see https://www.drupal.org/node/2219965 if (!empty($element['#icon'])) { if ($element['#icon_position'] === 'before') { $text = $element['#icon'] . ' ' . $text; } elseif ($element['#icon_position'] === 'after') { $text .= ' ' . $element['#icon']; } } // This line break adds inherent margin between multiple buttons. return '<button' . drupal_attributes($element['#attributes']) . '>' . _bootstrap_filter_xss($text) . "</button>\n"; }
/** * Processes variables for the "bootstrap_carousel" theme hook. * * See template for list of available variables. * * @see bootstrap-carousel.tpl.php * * @ingroup theme_process */ function bootstrap_process_bootstrap_carousel(&$variables) { $variables['target'] = '#' . $variables['attributes']['id']; $variables['attributes'] = drupal_attributes($variables['attributes']); // Ensure the item arrays are constructed properly for the template. foreach ($variables['items'] as $delta => $item) { // Convert items that are string into the appropriate array structure. if (is_string($item)) { $variables['items'][$delta] = array('image' => $item); } // Populate defaults. $variables['items'][$delta] += array('title' => NULL, 'description' => NULL, 'url' => NULL); if (!empty($variables['items'][$delta]['title'])) { $variables['items'][$delta]['title'] = _bootstrap_filter_xss(render($item['title'])); } if (!empty($variables['items'][$delta]['description'])) { $variables['items'][$delta]['description'] = _bootstrap_filter_xss(render($item['description'])); } } }
/** * Returns HTML for a single local task link. * * @param array $variables * An associative array containing: * - element: A render element containing: * - #link: A menu link array with 'title', 'href', and 'localized_options' * keys. * - #active: A boolean indicating whether the local task is active. * * @return string * The constructed HTML. * * @see theme_menu_local_task() * * @ingroup theme_functions */ function bootstrap_menu_local_task($variables) { $link = $variables['element']['#link']; $options = isset($link['localized_options']) ? $link['localized_options'] : array(); $title = $link['title']; $href = $link['href']; $attributes = array(); // Add text to indicate active tab for non-visual users. if (!empty($variables['element']['#active'])) { $options['html'] = TRUE; $attributes['class'][] = 'active'; $title = t('!local-task-title!active', array('!local-task-title' => $title, '!active' => '<span class="element-invisible">' . t('(active tab)') . '</span>')); } // Filter the title if the "html" is set, otherwise l() will automatically // sanitize using check_plain(), so no need to call that here. if (!empty($options['html'])) { $title = _bootstrap_filter_xss($title); } return '<li' . drupal_attributes($attributes) . '>' . l($title, $href, $options) . "</li>\n"; }
/** * Returns HTML for a list or nested list of items. * * - Uses an early D8 version of the theme function, which fixes bugs (and was * refused for commit because it was "too late to change theme output)". * - Removes first/last, even/odd classes. * - Removes useless div.item-list wrapper, allows optional #wrapper_attributes. * - Removes hard-coded #title as <h3>, introduce support for #title as an array * containing, text, tag and optional attributes. * * @param array $variables * An associative array containing: * - items: An array of items to be displayed in the list. If an item is a * string, then it is used as is. If an item is an array, then the "data" * element of the array is used as the contents of the list item. If an item * is an array with a "children" element, those children are displayed in a * nested list. All other elements are treated as attributes of the list * item element. * - title: The title of the list. * - type: The type of list to return (e.g. "ul", "ol"). * - attributes: The attributes applied to the list element. * * @return string * The constructed HTML. * * @see theme_item_list() * * @ingroup theme_functions */ function bootstrap_item_list($variables) { $items = $variables['items']; $title = $variables['title']; $type = $variables['type']; $list_attributes = $variables['attributes']; // Drupal core only supports #title as a string. This implementation supports // heading level, and attributes as well. $heading = ''; if (!empty($title)) { // If it's a string, normalize into an array. if (is_string($title)) { $title = array('text' => $title); } // Set defaults. $title += array('level' => 'h3', 'attributes' => array()); // Heading outputs only when it has text. if (!empty($title['text'])) { $heading .= '<' . $title['level'] . drupal_attributes($title['attributes']) . '>'; $heading .= empty($title['html']) ? check_plain($title['text']) : _bootstrap_filter_xss($title['text']); $heading .= '</' . $title['level'] . '>'; } } $output = ''; if ($items) { $output .= '<' . $type . drupal_attributes($list_attributes) . '>'; foreach ($items as $key => $item) { $attributes = array(); if (is_array($item)) { $value = ''; if (isset($item['data'])) { // Allow data to be renderable. if (is_array($item['data']) && (!empty($item['data']['#type']) || !empty($item['data']['#theme']))) { $value .= drupal_render($item['data']); } else { $value .= $item['data']; } } $attributes = array_diff_key($item, array('data' => 0, 'children' => 0)); // Append nested child list, if any. if (isset($item['children'])) { // HTML attributes for the outer list are defined in the 'attributes' // theme variable, but not inherited by children. For nested lists, // all non-numeric keys in 'children' are used as list attributes. $child_list_attributes = array(); foreach ($item['children'] as $child_key => $child_item) { if (is_string($child_key)) { $child_list_attributes[$child_key] = $child_item; unset($item['children'][$child_key]); } } $value .= theme('item_list', array('items' => $item['children'], 'type' => $type, 'attributes' => $child_list_attributes)); } } else { $value = $item; } $output .= '<li' . drupal_attributes($attributes) . '>' . $value . "</li>\n"; } $output .= "</{$type}>"; } // Output the list and title only if there are any list items. if (!empty($output)) { $output = $heading . $output; } return $output; }
/** * Processes variables for the "progress_bar" theme hook. * * See template for list of available variables. * * @see progress-bar.tpl.php * * @ingroup theme_process */ function bootstrap_process_progress_bar(&$variables) { $variables['percent'] = check_plain($variables['percent']); $variables['message'] = _bootstrap_filter_xss($variables['message']); }