The Site Map module in Drupal automatically generates a site map page for your site (not to be confused with an XML site map). By default, the Site Map module creates one list of links, but if you have a complex site, this can be a really long list. When this issue came up on a client's site recently, we wrote a bit of code that breaks that one column site map into two columns so that it's more readable and navigable for users. This is a very specific example, but it demonstrates how jQuery can be used in a range of other situations, so I thought I'd share with you how we did it. To create our two columns, we added code in three places: in a new JS file we created (mytheme_sitemap.js
), in a new CSS file we created (mytheme_sitemap.css
), and in template.php
(in hook_preprocess
). First, here's the code we placed in mytheme_sitemap.js
(our new JavaScript file):
$(document).ready(function(){ // make sitemap 2 columns at breakpoint var and add IDs to each box if ($('.site-map-box')) { var counter = 1; //add CSS ids to each box for optional styling $('.site-map-box').each(function() { this.id = 'sitemap_id_'+counter; counter++; }); //CHANGE THE "breakpoint" TO HOW MANY "site-map-box's" YOU WANT IN THE FIRST COLUMN var breakpoint = 1; var col2 = breakpoint-1; //grab the first few divs and wrap them for CSS $('.site-map-box:lt('+breakpoint+')').wrapAll('
This code takes the contents of the site map and divides it up into two smaller divs. First, we assign a DOM ID to every "site-map-box" in case we want to add special styles. This part is not necessary, but will make your themer/designer happy. The next part requires a little testing to know the correct number for the "breakpoint" variable. The Site map module just puts everything in a long list in its own order. Some of the "site-map-box's" could be really long, some could be really short. Because the number of boxes displayed is irrelevant to their actual length, we manually decide the most visually pleasing breakpoint based on our own content. For example, if you set the "breakpoint" variable to '3'?, the second column will begin with the 4th section of the site map. I know this approach requires a manual configuration. In an other application, you could very easily assign the breakpoint to be half the total number of boxes.
var breakpoint = Math.round((counter-1) / 2);
This would make your two columns have an equal number of boxes, not necessarily be of equal length. Next, we created a CSS file (mytheme_sitemap.css
) to float one of our new divs to the left, and one to the right.
/*site map*/ #site-map .col1 { float:left; width:49%; } #site-map .col2 { float:right; width:49%; }
For the third and final step, we added code to template.php
that checks to see if the current page is the site map page (by looking at the URL path), and if so, adds our new CSS and JS files to the theme.
/** * Override or insert PHPTemplate variables into the templates. */ function mytheme_preprocess(&$vars, $hook) { if (arg(0) == 'sitemap') { drupal_add_js(drupal_get_path('theme', 'mytheme') .'/scripts/mytheme_sitemap.js'); drupal_add_css(drupal_get_path('theme', 'mytheme') .'/styles/mytheme_sitemap.css'); } }
And that's it! A pretty easy solution to a common problem.