.. _pagination-quickstart:

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.  In ``controller/root.py``:

.. code-block:: python

    from tg.decorators import paginate

    @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 direction since it
will be trimed to only contain the current page.  You will also have
have a basic page navigation with ``${tmpl_context.paginators.movies.pager()}``:

.. code-block:: html+genshi

    <ol>
       <li py:for="movie in movies" py:content="movie">Movie title and year</li>
    </ol>

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


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
:py:class:`tg.support.paginate.Page` for more details:

.. code-block:: python

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


Adding Parameters to Links
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can pass any number of arguments to the *pager* function and they will be used to create
the links to the other pages.

For example with the following code:

.. code-block:: html+genshi

    ${tmpl_context.paginators.movies.pager(param1='hi', param2='man')}

the resulting links will be:

- */list?page=1&param1=hi&param2=man*
- */list?page=2&param1=hi&param2=man*

and so on...

By default the url used to generate links will be the same of the page
where the paginated data will be visible, this can be changed by passing
the **link** argument to the *pager* function:

.. code-block:: html+genshi

    ${tmpl_context.paginators.movies.pager(link='/otherlink', param1='hi', param2='man')}

and the resulting link will be generated by using the provided url:

- /otherlink?page=1&param1=hi&param2=man

Adding Previous And Next Links
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Apart from providing the ``pager`` method the paginator ``Page`` object we receive
inside our template context provides the ``previous_page`` and ``next_page`` properties
which can be used to create previous/next links:

.. code-block:: html+genshi

	<p class="pagelist">
		<a class="prevPage" href="/list?page=${tmpl_context.paginators.movies.previous_page}">&lt;&lt;&lt;</a>
		${tmpl_context.paginators.movies.pager(format='~3~', page_param='page', show_if_single_page=True)}
		<a class="nextPage" href="/list?page=${tmpl_context.paginators.movies.next_page}">&gt;&gt;&gt;</a>
	</p>

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:

.. code-block:: css

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

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