I’m sure regular contributors to Drupal will cringe at what I’m about to show you, but I found it to be a handy trick. Let’s say you’re using the Views module in Drupal 6 and you want a way to dynamically control the number of items listed in a view. In my case, a client I was working for wanted to be able to select the number of products displayed per page.

Reasonable request, right? Unfortunately, Views doesn’t handle it out of the box. After a bit of fiddling, I managed to come up with the following hack. Mind you, I use the term “hack” here literally; you should never edit a module like this if you can avoid it, if only because it makes updates painful later on.

The operative code is in the pre_execute() function on line 1795 of modules/plugins/views_plugin_display.inc. It normally looks like this:

$this->view->set_items_per_page($this->get_option('items_per_page'));

As the name suggests, anything you feed to this function will set the number of items displayed by the view. In my case, I wanted to use a URL variable coupled with a drop-down menu and some jQuery to toggle it, so I changed it like so:

$this->view->set_items_per_page((($_GET['items-per-page'] > 0) ? $_GET['items-per-page'] : $this->get_option('items_per_page')));

Voila! One line of code and you’re off to the races. Type ‘?items-per-page=X’ into the URL (with X being a number, of course) and it should work like a charm. The pagination even follows suit.

For those who want the full solution, here’s the code for the drop-down menu. You’ll need to add it to a view-specific template file. Just follow the pattern to create your own items per page options.

<?php $items_per_page_override = ($_GET['items-per-page'] > 0) ? $_GET['items-per-page'] : 12; ?>
<div id="items-per-page-selector"><strong>Items per Page:</strong> <select>
<option value="12"<?php echo ($items_per_page_override == 12) ? ' selected="selected"' : ''; ?>>12</option>
<option value="18"<?php echo ($items_per_page_override == 18) ? ' selected="selected"' : ''; ?>>18</option>
<option value="24"<?php echo ($items_per_page_override == 24) ? ' selected="selected"' : ''; ?>>24</option>
<option value="9999"<?php echo ($items_per_page_override == 9999) ? ' selected="selected"' : ''; ?>>All</option>
</select>

And here is the jQuery that controls the behavior of the drop-down menu.

$(document).ready(function(){
$('#items-per-page-selector select').change(function(){
window.location = '?items-per-page=' + $(this).val();
});
});

11 thoughts on “Selectable Items per Page Hack for Drupal 6 Views

  1. Note: I think it’s possible to override this value without a .module hack, at least in the case of embedded views. In the case of embedded views, I believe you could simply set $view->set_items_per_page just like you did in your hack but in the embed.

  2. Would it also be possible to override the function in the theme template.php file so you didn’t have to hack the module? sites/all/themes/theme_name/template.php
    Then it would be specific for the theme on a server running multiple Drupal sites.

    Either way, great solution. Surprised someone hasn’t added something like this to views>pager. It would nice to have a “user defined” option, or at least a “view all” option.

  3. That could be a possible solution, jberg, although I’m not sure if that function can be overridden from template.php. I’ve never tried it that way, but I imagine it’s possible; pretty much everything in Drupal can be overridden one way or another.

  4. Another solution I found with your suggestion is to use the hook_views_pre_execute to modify the item_per_page value like this :

    function mymodule_views_pre_execute( &$view ) {

    if( $view->name == “my_view” ) {

    $display = $view->current_display;

    if( $view->display[$display]->display_title == “All my blog posts” ) {

    $limit = 12;
    if( isset( $_GET[“limit”] ) ) $limit = $_SESSION[‘limit’] = $_GET[“limit”];
    else if( isset( $_SESSION[‘limit’] ) ) $limit = $_SESSION[‘limit’];

    if( intval( $limit ) == 0 )
    $limit = 12;

    $view->set_items_per_page( $limit );
    }
    }

    Hope this help 😉

  5. You guys saved me a lot of time. Thank you very much.
    titouille’s solution works very well.

  6. Another version of titoulle’s answer is to have this in a custom module:

    function yourmodulename_views_pre_execute(&$view){
    if ($view->name == ‘yourviewname’) {

    $view->set_items_per_page((($_GET[‘items-per-page’] > 0) ? $_GET[‘items-per-page’] : $view->get_option(‘items_per_page’)));

    }

    }

    This code is just slightly different from the one above, I didn’t have need to code in the limit amount or use SESSION variables.

    Hope this helps anyone who needs it.

  7. EDIT:

    Sorry I hadn’t fully tested that code: here is the working code:

    module:

    function yourmodulename_views_pre_execute(&$view){
    if ($view->name == ‘yourviewname’) {

    $view->set_items_per_page((($_GET[‘items-per-page’] > 0) ? $_GET[‘items-per-page’] : ”));

    }

    }

  8. I like the solution but had some problems with blocks which do not use a pager. so changed things a bit so views on the same page which are not using a pager will not be affected.

    ?get_option(‘use_pager’) == ‘0’) {
    $this->view->set_items_per_page($this->get_option(‘items_per_page’));
    } else {
    $this->view->set_items_per_page((($_GET[‘items-per-page’] > 0) ? $_GET[‘items-per-page’] : $this->get_option(‘items_per_page’)));
    }
    ?>

    Tried to make a module but probably I am doing something wrong somewhere since got all kinds of weird things. If someone has the complete module code I would appreciate it since hate to hack into the core code.

  9. hmm something went wrong with the pasting

    the correct code which works
    if ($this->get_option(‘use_pager’) == ‘0’) {
    $this->view->set_items_per_page($this->get_option(‘items_per_page’));
    } else {
    $this->view->set_items_per_page((($_GET[‘items-per-page’] > 0) ? $_GET[‘items-per-page’] : $this->get_option(‘items_per_page’)));
    }

  10. All good solutions. Interestingly enough, the D7 version of Views exposed the items per page filter, so it seems this will always be a backwards hack. Yay for open source!

Leave a Reply

Your email address will not be published. Required fields are marked *