Adding Accesskeys to Drupal Primary Links

After about 3 weeks of playing with Drupal v6 I have finally figured out how to add accesskeys to $primary_links. In this article I will show you how to do this and also how to add the keys to previous versions of Drupal too. Why this little step seemed so hard to achieve is beyond me - though none-the-less we are there how.

Aside from assigning accesskeys manually or through the link functions built in to Drupal there are 2 ways of creating accesskeys dynamically for, say, the $primary_links menu that is available. This can be achieved through creating custom modules or even through custom theming. Included in this article are examples of both these methods, plus simple examples using l(), modifying themed output and for starters the basic HTML syntax.

Method 1: HTML

The following outputs basic HTML link with accesskey for the home page. This code would be placed in page.tpl.php. Similar text can be found on this page if you view it's source code. This will work in any Drupal version.


<?php
   
  
<?php if ($site_name) { ?>
  <h1 class="site-name"><a accesskey="0" 
    href="<?php print $front_page?>
    title="<?php print t('Home'); ?>"><?php print $site_name?></a></h1>
  <?php ?>


Method 2: Using l()

The l() function has changed with the new version of Drupal. However, I still have an example firstly of how to use the function prior to v6. The first snippet should work in 4.7x upwards below v6. The second snippet is specifically for v6 and upwards.


<?php 
/* Versions below v6 */
print l(
'help'/* title */
'site/help',  /* url */ 
array('accesskey' => 8'title' => 'Site Help')  /* link attributes */
); ?> [8]

This returns the following in source code:
<a href="/site/help" accesskey="8" title="Site Help">help</a> [8]



<?php
/* Versions v6 upwards */
print l(
t('help'), /* title */ 
'node/24',   /* url */ 
array('attributes' => array('accesskey' => 8'title' => 'Site Help'
/* link attributes,  more arrays */
); ?>

This returns the same in source code:
<a href="/site/help" accesskey="8" title="Site Help">help</a>


Method 3: Cheat using theme() and str_replace()

I am using a custom pager for one of the themes I have developed for mobile sites. This guarantees a certain output. I can then use str_replace() to modify the links and add accesskeys to them. I only have a next/previous link and subsequently replace the text as follows:


<?php 
function phptemplate_pager(
$tags = array(), 
$limit=3
$element 0
$parameters = array()
) {
  
// STUFF TO OUTPUT A THEMED DIV WITH NEXT /  PREVIOUS LINKS
     
    // THIS SHOULD EQUAL THE HTML EQUIVILANT OF t()s ABOVE
    
  
$output str_replace('>&lt;&lt;'' accesskey="7" title="previous"><<'
    
$output);
  
$output str_replace('>&gt;&gt;'' accesskey="9" title="next">>>'
    
$output);  
  return 
$output;
  }
}



The above example show how to change links individually. The following examples show how to use a module to theme $primary_links in v5 and override using themes in v6. Again, v6 code is not backward compatible at the present. v5 code can be used with v4.7 and upwards until the latest branch of v5. Change MODULE_NAME to match your module's name

Theme As Part of a Module


<?php 
/* Drupal v4 < 6 */
function theme_MODULE_NAME_primary_links($links) {
  
$output '';

  if (count($links) > 0) {
    
$num_links count($links);
    
$i 1;

    foreach ($links as $link) {
      
$html = isset($link['html']) && $link['html'];

      $link['query'] = isset($link['query']) ? $link['query'] : NULL;
      
$link['fragment'] = isset($link['fragment']) ? $link['fragment'] : NULL;

      if (isset($link['href'])) {
        
$output .= l($link['title'], $link['href'], 
        
array_merge($link['attributes'], array('accesskey' => $i)), 
        
$link['query'], $link['fragment'], FALSE$html);
      }
      else if (
$link['title']) {
        if (!
$html) {
          
$link['title'] = check_plain($link['title']);
        }
        
$output .= $link['title'];
      }
      
$output .= ' | ';
      
$i++;
    }
  }
  return empty(
$output) ? '' substr($output0, -3);
}



Theme As Part of a Theme - php template


<?php
// in template.php
function phptemplate_accesskeylink($links) {
    
 if (
count($links) > 0) { 
  
$i 1;   
  foreach (
$links as $key => $link) {
    
$links[$key]['attributes']['accesskey'] = $i;
    
$i++;
  } 
}      
return 
$links;
}
// in page.tpl.php
    
print theme('links'phptemplate_accesskeylink($primary_links));


Theme Using Custom Themes

A slightly different approach was taken by me when demoing v6. I decided I want to learn some of the functionality of the new version before trying to upgrade the accessibility module. To this end, I played around with themes and eventually managed to get accesskeys working within the themes by override the $primary_links variable when using the new phptemplate_preprocess_page function in template.php.


<?php 
function phptemplate_preprocess_page(&$vars) {
// OTHER STUFF AS REQUIRED
$newlinks = array();
$blah $vars['primary_links']; // CHANGE TO MENU OF CHOICE
  
$i 1;
foreach (
$blah as $menu_item => $menu_value) {
    
$new_links [$menu_item] = array('attributes' => array('accesskey' => $i));
    
$new_link [$menu_item] = $menu_value;
    
$i++;
}
  
$att array_merge_recursive($new_links$new_link);
  
$m_l '';
foreach (
$att as $lmenu => $latts){
    
$m_l .= "\n" l$latts['title'], $latts['href'], 
    array(
'attributes' => $latts['attributes']) ) .' | ';
}

$vars['mobi_links'] = rtrim($m_l' | ');


You can then use $mobi_links in your page.tpl.php, to show the modified $primary_links. I hope you find it useful. Any comments or suggestions always welcome.

Syndicate content