Using Plone's built-in batching mechanism

« Return to page index

In this tutorial, Helge Tesdal from Jarn (formerly Plone Solutions) shows you how to use the built-in batching utility in Plone to create a Previous/Next selector with pages when you have a lot of items you want to list.

PloneBatch usage

PloneBatch is an extension of the regular Batch class in ZTUtils. It also comes with a handy macro for making the navigation menu to ease development. It's perfect for those 2000 items search result pages.

The main steps of including the PloneBatch in your template will be to import the Batch, make a batch from your resultset, use the navigation macro and iterate over the batch elements.

Source code in this example comes from the search.pt template in Plone.

First step, set up your Batch

In the beginning of your template you would import Batch from Plone and define some variables used by it:

  <div metal:fill-slot="main"
       tal:define="results python:here.queryCatalog();
                   Batch python:modules['Products.CMFPlone'].Batch;
                   b_size python:30;
                   b_start python:0;
                   b_start request/b_start | b_start;">

results is the list to make batch from. In this case it is the results of a search (catalog query), but it can be any list.

Batch is imported from Products.CMFPlone and made available in the template as Batch.

b_size is the batch size, the number of elements to display in each batch.

b_start is the first element in the batch. It is retrieved from the request, or 0 if not found. Usually you will see b_start set to different values in the URL when you navigate around the pages in the result.

Second step, make a batch from the results

After setting up Batch and other variables, we are ready to make the batch from our result:

  <div tal:condition="results"
       tal:define="batch python:Batch(results, 
                                      b_size, 
                                      int(b_start),
                                      orphan=1);">

If the next batch would contain no more than orphan elements, it is combined with the current batch. In this case, if the next batch would contain only 1 element, it is combined with the current page.

Third step, make a navigation menu

For your convenience we have provided a macro to make the navigation menus. This macro will typically be called before and after iterating over the items in the batch:

  <div metal:use-macro="here/batch_macros/macros/navigation" />

The result will be something similar to this:

  «Previous 30    1 2 3 4 [5] 6 7 8 ...Last    Next 30»

Fourth step, iterate over the batch

Now you are ready to iterate over the batch. This is done exactly as you would iterate over the regular result set:

  <metal:block tal:repeat="result batch">
      <p tal:content="result/getURL">
      The URL from result will be written here
      </p>
  </metal:block>

You might want to call the navigation macro again after iterating over the result to get a navigation menu both above and below the result.

PloneBatch: Advanced Usage

The batch navigation is customizable, and here is an overview of the more advanced features available.

The Batch constructor takes these arguments:

sequence
The list to batch
size
The number of items in each batch
start=0
The first item in the batch, 0-index
end=0
The last item in the batch, 0-index and optional
orphan=0
The next page will be combined with the current page if it does not contain more than orphan elements. Optional and default 0
overlap=0
The number of overlapping elements in each batch. Optional and default 0
pagerange=7
The number of pages to display in the navigation menu
quantumleap=0
0 or 1 to indicate wheter bigger increments should be used in the navigation list for big results. This would make navigation faster as you could make bigger jumps.
b_start_str=b_start
The variable name to be used to set the start of the batch. Changing this enables multiple batches with different starting points on the same page.

Making your own navigation menu

You can make your own navigation menu if you are not satisfied with the regular one. To do this you have to know which attributes are available in the batch object.

size
Batchsize
start
First element, 1 based index into the sequence
first
First element, 0 based index into the sequence
end
Last element, 0 based index into the sequence
orphan
The next page will be combined with the current page if it does not contain more than orphan elements
overlap
The number of overlapping elements in each batch
length
Length of the batch
b_start_str
The name of the request variable storing batch starting point
last
First element on last page
previous
previous Batch, previous.first is the first element in the previous page
next
next Batch, next.first is the first element in the next page
sequence_length
The length of the result
numpages
Total number of pages
pagenumber
Current page number
pagerange
The computed number of pages to display in the navigation menu
pagerangestart
The first page to display in the navigation menu
pagerangeend
The last page to display in the navigation menu
navlist
A list containing the pagenumbers for the navigation list
prevlist
A list containing the pagenumbers for the navigation list with pagenumbers lower than the current page
nextlist
A list containing the pagenumbers for the navigation list with pagenumbers higher than the current page
quantumleap
0 or 1 to indicate if there should be bigger gaps between the pagenumbers in on the edges of the navigation list
leapback
A list containing the pagenumbers for the quantum leap navigation list with pagehumbers lower than the current page
leapforward
A list containing the pagenumbers for the quantum leap navigation list with pagehumbers lower than the current page
pageurl(self, formvariables, pagenumber=-1):
""" Makes the url for a given page """
def navurls(self, formvariables, navlist=[]):
""" Returns the page number and url for the navigation quick links """
def prevurls(self, formvariables):
""" Helper method to get prev navigation list from templates """
def nexturls(self, formvariables):
""" Helper method to get next navigation list from templates """