Customizing a View: 'Show N per page' links

26 Feb 2009
Posted by jcfiala

Setting up a view these days with Views2 can get you 90-95% of the way to what your client, or you, want, but sometimes you've got to go in and make a few tweaks to customize a view to what's needed. One hook that's useful for customizing is hook_views_pre_execute(&$view).

In this helpful hook, you can add something to the foot of your view by using the $view->attachment_after property and setting it to the proper html, or to the head by using the $view->attachment_before property. You can also adjust what the view is doing, and since this is before the query execution, you can easily change settings such as the number of rows being returned.

When you create a view you have to state how many rows appear on each page of data, but you might want more flexibility and give your users the choice of, say, showing 5 per page, 10 per page, or 25 results per page or more. There's three things you need to add to your site to do this: A method of getting the current page limit, a theme method to write the links to display, and a method to amend the view to display those links.

<pre>
<?php
/**
* Checks the query string and the session to see what the current pager count is.
*
* @param string $session_pager_key The string to identify the pager count for this page.
* @return A number of rows per page.
*/
function example_get_pager_count($session_pager_key) {
  if (isset(
$_GET['pager_count'])) {
   
$pager_limit = $_GET['pager_count'] + 0;
   
$_SESSION[$session_pager_key] = $pager_limit;
  }
  else {
   
$pager_limit = isset($_SESSION[$session_pager_key]) ? ($_SESSION[$session_pager_key] + 0) : 10;
  }
  return
$pager_limit;
}

/**
* Theme function to display a set of links to change how many rows to display per page.
*
* @param array $available_sizes An array of numbers which are size choices.
* @param int $current_size The currently selected size.
* @return string XHMTL output displaying the links.
*/
function theme_example_pager_count_display($available_sizes, $current_size) {
 
$output = '<span class="pager_count_display">Show ';
  foreach (
$available_sizes as $size) {
   
$class = '';
    if (
$size == $current_size) {
     
$class = 'current';
     
$options[] = '<strong>'. $size .'</strong>';
    }
    else {
     
$options[] = l($size, $_GET['q'], array('query' => array('pager_count' => $size), 'attributes' => array('class' => $class)));
    }
  }
 
 
$output .= implode(' ', $options);
 
$output .= ' Per Page</span>';
  return
$output;
}

/**
* Implements hook_views_pre_execute().
*
* This allows us to adjust the number of rows to present, and to add the pager
* count display functionality.
*
* @param stdClass $view The view to alter.
*/
function example_views_pre_execute(&$view) {
  if (
$view->name == 'example_view') {
   
$pager_limit = example_get_pager_count('pager_count');
   
   
$view->pager['items_per_page'] = $pager_limit;
   
$view->handler->options['items_per_page'] = $pager_limit;
   
$view->attachment_after = theme('example_pager_count_display', array(5, 10, 25), $pager_limit);
  }
}
?>

</pre>

Tags: