Note: this code is now included in the Views Bonus Pack. This article may still be useful in understanding ways to get creative with views, or if you need do something that the bonus pack won't handle.

I have a site with a huge number of taxonomy terms, too many to display in a single sitemap page. I wanted to create a sitemap that would display an A/B/C style listing horizontally across the top, then a list of the taxonomy terms for the selected letter below it, to look like:

displays:

A | B | C | ...

Accessible Travel
Assisted Living
...

To accomplish this, I first created a view called 'sitemap' with an url of 'sitemap', a title of 'Site Map', and a page display set to display as a list, used the node title as a field, and set it up to display 30 items to be sure it could at least display the whole alphabet on one page. I gave it a taxonomy argument with an option of '1' (meaning group it by the first letter of the term) and set it up to display all results, sorted ascending. I then created a second taxonomy term argument, everything the same as the first one, but with the option field left blank, meaning that it should group the nodes that matched the first argument by the complete taxonomy term name.

This gave me a view where I would go to the url 'mysite/sitemap' and see a list of letters, with the number of nodes next to each one. I could then click on the letter to see a list of all terms that start with that letter, then click on the term to see the list of matching nodes.

I have a very long list of nodes, so I also added a content type filter and exposed it, so the end user could filter the results by type, if they wanted to.

This created the bottom part of the page. I wanted to keep the alpha list showing at the top of the page as a second view of the view. That alpha list is really just a block view of the same view I just created, so I set the view up to produce both a page and a block.

To get the block to display at the top of the view, I needed to make a change in my page template. I added a snippet to mytheme.page.tpl.php right above the page title that looks like the following. This told the template to display the block view of the view in a div with an id of 'alpha_list' (and to add a pipe after each item as a separator and a nobreak space between the letter and the number to keep the numbers next to the right letter irrespective of line breaks):

  <?php 
  if (arg(0) == 'sitemap') {
   $block = views_block('view', 'sitemap');
   print '<h2>'.$block['subject'].'</h2>';
   $replace = array(
     ' (' => '&nbsp(',
     '</li>' => '&nbsp;| </li>',
     );
   print '<div id="alpha_list">'.strtr($block['content'], $replace).'</div>';
  }
  ?>

I also needed a bit of css to get the alpha list to display horizontally instead of vertically, and to make the letter names more prominant and the numbers next to them a bit less prominant, so I added the following to my css:

#alpha_list {
  clear:both;
  margin: 10px 0;
  padding:10px;
  border-bottom:1px #CCC solid;
  text-align:center;
  color:#666;
  }
#alpha_list a {
  color:#000;
  }  
#alpha_list ul, #alpha_list li {
  margin:0;
  padding:0;
  }  
#alpha_list li {
  display:inline;
  }

And that did it. Now I could create a link to sitemap/A and visitors get the view I wanted -- the alpha list across the top and the details below. Clicking on a different letter in the top list changes the details in the lower view to match the selected letter.

You can see the results on a live site at http://www.elderweb.com/home/sitemap/A.

An export of the view follows (you'll have to change the content types when you import it to match your own site setup):

  $view = new stdClass();
  $view->name = 'sitemap';
  $view->description = '';
  $view->access = array (
);
  $view->view_args_php = '';
  $view->page = TRUE;
  $view->page_title = 'Site Map';
  $view->page_header = '';
  $view->page_header_format = '3';
  $view->page_footer = '';
  $view->page_footer_format = '1';
  $view->page_empty = '';
  $view->page_empty_format = '1';
  $view->page_type = 'list';
  $view->url = 'sitemap';
  $view->use_pager = TRUE;
  $view->nodes_per_page = '30';
  $view->menu = TRUE;
  $view->menu_title = 'Site Map';
  $view->menu_tab = FALSE;
  $view->menu_tab_default = FALSE;
  $view->menu_weight = '';
  $view->block = TRUE;
  $view->block_title = 'Site Map';
  $view->block_header = '';
  $view->block_header_format = '1';
  $view->block_footer = '';
  $view->block_footer_format = '1';
  $view->block_empty = '';
  $view->block_empty_format = '1';
  $view->block_type = 'list';
  $view->nodes_per_block = '30';
  $view->block_more = '1';
  $view->block_use_page_header = FALSE;
  $view->block_use_page_footer = FALSE;
  $view->block_use_page_empty = FALSE;
  $view->sort = array (
    array (
      'tablename' => 'term_data',
      'field' => 'weight',
      'sortorder' => 'ASC',
      'options' => '',
    ),
    array (
      'tablename' => 'node',
      'field' => 'created',
      'sortorder' => 'DESC',
      'options' => '',
    ),
  );
  $view->argument = array (
    array (
      'type' => 'taxletter',
      'argdefault' => '4',
      'title' => '%1',
      'options' => '1',
      'wildcard' => '',
      'wildcard_substitution' => '',
    ),
    array (
      'type' => 'taxletter',
      'argdefault' => '4',
      'title' => '%2',
      'options' => '',
      'wildcard' => '',
      'wildcard_substitution' => '',
    ),
  );
  $view->field = array (
    array (
      'tablename' => 'node',
      'field' => 'title',
      'label' => '',
      'handler' => 'views_handler_field_nodelink',
      'sortable' => '1',
    ),
  );
  $view->filter = array (
    array (
      'tablename' => 'node',
      'field' => 'status',
      'operator' => '=',
      'options' => '',
      'value' => '1',
    ),
    array (
      'tablename' => 'node',
      'field' => 'type',
      'operator' => 'OR',
      'options' => '',
      'value' => array (
  0 => 'blog',
  1 => 'article',
  2 => 'book',
  3 => 'category-cat',
  4 => 'news',
  5 => 'press',
),
    ),
    array (
      'tablename' => 'node',
      'field' => 'status',
      'operator' => '=',
      'options' => '',
      'value' => '1',
    ),
  );
  $view->exposed_filter = array (
    array (
      'tablename' => 'node',
      'field' => 'type',
      'label' => 'Type:',
      'optional' => 1,
      'is_default' => 1,
      'operator' => 1,
      'single' => 1,
    ),
  );
  $view->requires = array(term_data, node);
  $views[$view->name] = $view;