Usage
=====
.. highlight:: html+django
.. _sort:
Sorting
-------
The center piece of the app is the ``{% sort %}`` template tag which
takes one required and one optional argument.
The bare bones example is::
{% load sorter_tags %}
{% sort object_qs as sorted_objects %}
{% for obj in sorted_objects %}
{{ obj.title }}
{% endfor %}
If this template is rendered with a list of ``objects``, say a Django
QuerySet, the template tag will order it by calling the ``order_by()``.
The sorting criteria passed to this method is retrieved from the
request's GET paramaters (the "querystring_") by looking for a field-value
pair with the name **sort**.
Simple
++++++
So imagine you have a list of blog posts that you want to sort by their
creation dates, in an ascending order. With the example template above
all you'd have to do is to call the view rendering those blog posts with
the appropriate querystring::
http://example.com/blog/?sort=creation_date
Since name of the field is automatically picked up and passed to
``order_by()`` you can also sort in descending order by prepending
the name of the field with a negative sign (``-``)::
http://example.com/blog/?sort=-creation_date
You can also pass multiple fields to the querystring parameter to
sort for multiple fields::
http://example.com/blog/?sort=-creation_date,title
Complex
+++++++
In some cases you may want to sort multiple lists of objects in the same
template or use advanced techniques like chained sorting workflows.
All you need to do is to pass a second parameter to the ``{% sort %}``
template tag which defines the name of the querystring parameter::
{% load sorter_tags %}
{% sort object_qs with "posts" as sorted_objects %}
{% for obj in sorted_objects %}
{{ obj.title }}
{% endfor %}
Make sure to use unique names to prevent any clash with other sortings
that may happen on the same page. As a matter of additional precaution
the template tag will prepend it with ``'sort_'`` when analyzing the
request's querystring.
So if you'd use the example template above, the template tag would look
for a querystring parameter named ``'sort_posts'`` because the second
parameter to the template tag is ``"posts"``::
http://example.com/blog/?sort_posts=creation_date
.. _sortlink:
Links
-----
When sorting objects it's usually required to link to other sorting
criterias. ``django-sorter`` includes the ``{% sortlink %}`` template tag
for that which takes a number of optional arguments and a required list of
sorting criterias::
{% sortlink [with NAME] [rel REL] [class CLASS] [as VARIABLE] by ORDER_A1[,ORDER_A2,..] [ORDER_B1[,ORDER_B2,..]] .. %}
LABEL
{% endsortlink %}
As with the :ref:`{% sort %}` template tag, ``sortlink`` takes the
name of the querystring parameter it's supposed to be working with.
For example, the following code would fit the example
:ref:`shown above`::
{% sortlink with "posts" by "title" %}Title{% endsortlink %}
If this snippet would be included in a template that renders your blog
(with a request path of ``'/blog/'``), we'd get::
Title
Multiple criterias
++++++++++++++++++
Multiple sorting criterias can be specified in comma separated form::
{% sortlink with "posts" by "creation_data,title" %}
Creation date and title
{% endsortlink %}
would generate::
Creation date and title
Link text
+++++++++
The template tag is a block tag, which means translating the link text
is as easy as using Django's ``trans`` template tag::
{% load i18n %}
{% sortlink with "posts" by "creation_data,title" %}
{% trans "Creation date and title" %}
{% endsortlink %}
Other paramters
+++++++++++++++
- ``rel`` which sets the appropriate attribute of the link,
e.g. useful when trying to set `rel="nofollow"`_.
- ``class`` which is useful to style the link correctly.
- ``as`` which allows assigning the result of the template tag to
a template context variable.
Further customization
+++++++++++++++++++++
Of course any further customization is also possible by overriding the
templates used by the template tag. By default ``django-sorter`` will use
the ``sorter/sortlink.html`` template, to render each link.
Furthermore -- if a name is given with the ``with`` argument -- it'll also
look for the template ``sorter/sortlink_NAME.html``, where ``NAME`` is the
value of the argument passed. E.g.::
{% sortlink with "posts" by "title" %}Title{% endsortlink %}
would make the template tag look for a ``sorter/sortlink_posts.html``
*and* ``sorter/sortlink.html``.
The template tag passes a bunch of variable to the template:
- ``with`` - The name of querystring parameter to take into account.
- ``rel`` - The value to be used for the HTML rel attribute.
- ``class`` - The value to be used for the HTML class attribute.
- ``by`` - The list of sorting criterias.
- ``title`` - A string which lists all search criteria in prose.
- ``label`` - The rendered content of the template block.
- ``url`` - The URLObject_ instance with the querystring set appropriately.
- ``query`` - The value of the querystring parameter.
.. _`rel="nofollow"`: http://en.wikipedia.org/wiki/Nofollow
.. _`URLObject`: https://github.com/zacharyvoase/urlobject
Criteria cycling
++++++++++++++++
Sometimes you'll want to allow switching between criterias depending on
the currently selected sorting criteria. For example, if you sort a
list of blog posts in ascending order you might want to show a link
to the same list but in *descending* order.
With ``django-sorter`` this is as easy as passing a **series** of sorting
criterias to the same template tag::
{% sortlink with "posts" by "title" "-title" %}Title{% endsortlink %}
Now when the link is rendered it will check the current URL and select
**the next** sorting criteria to render.
For example, if you'd be on the page with the URL
``'/blog/?sort_posts=title'``, the result would be::
Title
Of course, if the last sorting criteria is found the current request's
querystring, it'll start with the first again.
.. _sortform:
Forms
-----
Other than the :ref:`sortlink` template tag, ``django-sorter``
also ships with a second template tag to apply other sorting criterias --
the ``sortform`` tag.
It works basically the same as ``sortlink`` and uses the same code behind
the scenes, but looks for a different template: ``sorter/sortform.html``.
Just like the :ref:`sortlink` tag it'll use the name of the
querystring parameter if given to additionally look for a specific template,
e.g. ``sorter/sortform_posts.html``
An example::
{% sortform with "posts" by "creation_date" %}
{% trans "Creation and title" %}
{% endsortform %}
rendered::
.. _sorturl:
URLs
----
As a quick helper in case you don't like ``django-sorter`` to generate
the links or forms for your sorting efforts, you can also use the simple
``sorturl`` template tag::
{% sorturl with "posts" by "creation_date" %}
would only return the URL to the sorting::
/blog/?sort_posts=creation_date
Don't forget that it also takes an optional ``as`` parameter (like the rest
of the parameters described for the :ref:`sort` template tag). That's
great for storing the URL to further mangle it or use it for other template-y
things, e.g.::
{% sorturl with "posts" by "creation_date" as sort_by_date_url %}
{% blocktrans with sort_by_date_url as url %}
Please visit the following URL to sort by date:
http://example.com{{ sort_by_date_url }}
Thanks!
{% endblocktrans %}
.. _querystring: http://en.wikipedia.org/wiki/Querystring