Pagination in TurboGears

Paginate Decorator

TurboGears provides a convenient paginate() decorator that you can combine with expose(). To use it, you simply have to pass it the name of a collection to paginate. This example assumes a SQLAlchemy quickstart with a Movie model and the current default Kajiki templates. Create templates/movie_list_deco.xhtml and, in controllers/root.py:

from tg import expose
from tg.decorators import paginate

from paginatesample.model import DBSession, Movie

@expose("paginatesample.templates.movie_list_deco")
@paginate("movies", items_per_page=5)
def decolist(self):
    """
    List and paginate all movies in the database using the
    paginate() decorator.
    """

    movies = DBSession.query(Movie)
    return dict(movies=movies, page='paginatesample Movie list')

In your template, you can now use the collection directly; it will be trimmed to only contain the current page. You will also have basic page navigation with ${tmpl_context.paginators.movies.pager()}:

<html py:extends="master.xhtml" py:strip="True">
  <body py:block="body" py:strip="True">
    <ol>
      <li py:for="movie in movies">${movie}</li>
    </ol>

    <p class="pagelist">
      ${tmpl_context.paginators.movies.pager()}
    </p>
  </body>
</html>

Advanced Pagination

The pager method of the paginator supports various customization options to tune the look and feel of the paginator, make sure you take a look at tg.support.paginate.Page for more details:

${tmpl_context.paginators.movies.pager(format='~3~', page_param='page', show_if_single_page=True)}

Adding Some Arrow Images

Once you added your own previous/next page entities you can style them as you prefer, one common need is to display an image instead of the text. Current quickstarts serve static files from public; the paths below assume you have added your own arrow images under public/img:

a.prevPage {
        background: url("/img/arrow-left.png") no-repeat;
        padding-left: 18px;
        padding-right: 18px;
        padding-top: 12px;
        padding-bottom: 15px;
        text-decoration: none;
        }

a.nextPage {
        background: url("/img/arrow-right.png") no-repeat;
        padding-left: 18px;
        padding-right: 18px;
        padding-top: 12px;
        padding-bottom: 15px;
        text-decoration: none;
        }