Speaking Navigation in Drupal

Door Erik (3 oktober 2009)
Of ik wist wat 'Speaking Block Navigation' was? "Nee, maar ik ben wel in voor iets nieuws." En dus kreeg ik wireframes met deze voor mij nieuwe soort van navigatie. Na wat Googlen vond ik dit artikel over Speaking Navigation. Een site-navigatie waarbij een subtitel aan de 'normale' menutekst is toegevoegd. wire frame Speaking Navigation Mijn vermoeden dat dit in Drupal niet al te moeilijk te realiseren was kwam uit. Eerst de HTML:
<li><a href="/home"><em>Home</em>Terug naar<br />de voorpagina</a></li>
Zowel de titel als de subtitel moeten klikbaar zijn. De em-tag is toegevoegd om de titel zowel syntactisch als voor vormgeving te kunnen onderscheiden van de subtitel. En zo valideert de HTML ook nog steeds. De tekst die anders als 'title' van de link is, wordt nu gebuikt als subtitel. In Drupal is dit met theming op te lossen, maar een kleine ingreep is het niet. Het primaire menu worden vaak in een template geplaatst met:
<?php print theme('links'$primary_links); ?>
Dit vervang ik door:
<?php print $primary_menu?>
In template.php voeg ik toe:
<?php
/**
 * Override or insert variables into the page templates.
 *
 * @param $vars
 *   An array of variables to pass to the theme template.
 * @param $hook
 *   The name of the template being rendered.
 */
function MIJNTHEME_preprocess_page(&$vars$hook) {
  
$vars['primary_menu'] = theme('speaking_menu'$vars['primary_links']);
}
?>
Dus in plaats van de functie theme_links() ga ik een functie theme_speaking_menu() gebruiken. Een override van theme_links() is in dit geval niet mogelijk omdat theme_links() voor alle links wordt gebruikt en we binnen de functie geen onderscheid kunnen maken. Om een nieuwe theme-functie binnen template.php te definiëren moet deze met een hook_theme()-implementatie gedeclareerd worden.
<?php
/**
 * Implementation of hook_theme().
 */
function MIJNTHEME_theme($existing$type$theme$path) {
  return array(
    
'speaking_menu' => array(
      
'arguments' => array('links' => NULL'attributes' => array('class' => 'links')),
    ),
  );
}
?>
Om een kleine wijziging aan te brengen moet ik hier theme_links() geheel kopiëren.
<?php
/**
 * Theming of speaking menu links.
 *
 * Based on theme_links().
 *
 * Customized:
 *  - Modified: Link format
 *      <li><a class="_class_" href="_href_" title="_title_">Menu name</a></li>
 *    replaced by:
 *      <li><a class="_class_" href="_href_"><em>Menu name</em>_title</a></li>
 *  - Removed: else part of if (isset($link['href']) {}. 
 *    Primary links are always links.
 */
function MIJNTHEME_speaking_menu($links$attributes = array('class' => 'links')) {
  global 
$language;
  
$output '';

  if (
count($links) > 0) {
    
$output '<ul'drupal_attributes($attributes) .'>';

    
$num_links count($links);
    
$i 1;

    foreach (
$links as $key => $link) {
      
$class $key;

      
// Add first, last and active classes to the list of links to help out themers.
      
if ($i == 1) {
        
$class .= ' first';
      }
      if (
$i == $num_links) {
        
$class .= ' last';
      }
      if (isset(
$link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page()))
          && (empty(
$link['language']) || $link['language']->language == $language->language)) {
        
$class .= ' active';
      }
      
$output .= '<li'drupal_attributes(array('class' => $class)) .'>';

      if (isset(
$link['href'])) {
        
// Pass in $link as $options, they share the same keys.

        // --- Start Modified ---
        // Do a quick check on suspicious code before using the expensive strip_tags().
        
if (isset($link['attributes']['title']) && strpos($link['attributes']['title'], '<') !== FALSE) {
           
$link['attributes']['title'] = strip_tags($link['attributes']['title']);
        }
        
// Convert all Windows and Mac newlines to a single newline and
        // simply replace any line break with '<br />'.
        
$link['attributes']['title'] = str_replace(array("\r\n""\r"), "\n"$link['attributes']['title']);
        
$link['attributes']['title'] = preg_replace('/\n/''<br />'$link['attributes']['title']);
        
        
// Build new text string and use it for the link.
        
$text '<em>'check_plain($link['title']) .'</em>'$link['attributes']['title'];
        unset(
$link['attributes']['title']);
        
$link['html'] = TRUE;
        
$output .= l($text$link['href'], $link);
        
// --- End Modified ---

      
}
      
// --- Removed: else {} ---

      
$i++;
      
$output .= "</li>\n";
    }

    
$output .= '</ul>';
  }

  return 
$output;
}
?>
Ik voeg graag veel commentaar aan code toe. In de toelichting bij de functie wat er gewijzigd is én in de code welke regels zijn gewijzigd en wat ze doen. Om deze code in je eigen theme toe te passen moet uiteraard 'MIJNTHEME' door de juiste theme-naam worden vervangen.
Drupalversie:  Drupal 6

Reactie toevoegen