trac.util.presentation – Utilities for dynamic content generation

trac.util.presentation.jinja2_update(jenv)

Augment a Jinja2 environment with filters, tests and global functions defined in this module.

We define a few Jinja2 custom filters.

trac.util.presentation.flatten_filter(value)

Combine incoming sequences in one.

trac.util.presentation.groupattr_filter(_eval_ctx, iterable, num, attr, *args, **kwargs)

Similar to group, but as an attribute filter.

trac.util.presentation.htmlattr_filter(_eval_ctx, d, autospace=True)

Create an SGML/XML attribute string based on the items in a dict.

If the dict itself is none or undefined, it returns the empty string. d can also be an iterable or a mapping, in which case it will be converted to a dict.

All values that are neither none nor undefined are automatically escaped.

For HTML attributes like 'checked' and 'selected', a truth value will be converted to the key value itself. For others it will be 'true' or 'on'. For 'class', the classes processing will be applied.

Example:

<ul${{'class': {'my': 1, 'list': True, 'empty': False},
      'missing': none, 'checked': 1, 'selected': False,
      'autocomplete': True, 'id': 'list-%d'|format(variable),
      'style': {'border-radius': '3px' if rounded,
                'background': '#f7f7f7'}
     }|htmlattr}>
...
</ul>

Results in something like this:

<ul class="my list" id="list-42" checked="checked" autocomplete="on"
    style="border-radius: 3px; background: #f7f7f7">
...
</ul>

As you can see it automatically prepends a space in front of the item if the filter returned something unless the second parameter is false.

Adapted from Jinja2’s builtin do_xmlattr filter.

trac.util.presentation.max_filter(seq, default=None)

Returns the max value from the sequence.

trac.util.presentation.min_filter(seq, default=None)

Returns the min value from the sequence.

trac.util.presentation.trim_filter(value, what=None)

Strip leading and trailing whitespace or other specified character.

Adapted from Jinja2’s builtin trim filter.

We also define a few Jinja2 custom tests.

trac.util.presentation.is_greaterthan(a, b)
trac.util.presentation.is_greaterthanorequal(a, b)
trac.util.presentation.is_lessthan(a, b)
trac.util.presentation.is_lessthanorequal(a, b)
trac.util.presentation.is_not_equalto(a, b)
trac.util.presentation.is_not_in(a, b)
trac.util.presentation.istext(text)

True for text (unicode and str), but False for Markup.

The following utilities are all available within Jinja2 templates.

trac.util.presentation.captioned_button(req, symbol, text)

Return symbol and text or only symbol, according to user preferences.

trac.util.presentation.first_last(idx, seq)

Generate first or last or both, according to the position idx in sequence seq.

In Jinja2 templates, rather use:

<li ${{'class': {'first': loop.first, 'last': loop.last}}|htmlattr}>

This is less error prone, as the sequence remains implicit and therefore can’t be wrong.

trac.util.presentation.group(iterable, num, predicate=None)

Combines the elements produced by the given iterable so that every n items are returned as a tuple.

>>> items = [1, 2, 3, 4]
>>> for item in group(items, 2):
...     print(item)
(1, 2)
(3, 4)

The last tuple is padded with None values if its’ length is smaller than num.

>>> items = [1, 2, 3, 4, 5]
>>> for item in group(items, 2):
...     print(item)
(1, 2)
(3, 4)
(5, None)

The optional predicate parameter can be used to flag elements that should not be packed together with other items. Only those elements where the predicate function returns True are grouped with other elements, otherwise they are returned as a tuple of length 1:

>>> items = [1, 2, 3, 4]
>>> for item in group(items, 2, lambda x: x != 3):
...     print(item)
(1, 2)
(3,)
(4, None)
trac.util.presentation.istext(text)

True for text (unicode and str), but False for Markup.

trac.util.presentation.paginate(items, page=0, max_per_page=10)

Simple generic pagination.

Given an iterable, this function returns:
  • the slice of objects on the requested page,
  • the total number of items, and
  • the total number of pages.

The items parameter can be a list, tuple, or iterator:

>>> items = list(xrange(12))
>>> items
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> paginate(items)
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 12, 2)
>>> paginate(items, page=1)
([10, 11], 12, 2)
>>> paginate(iter(items))
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 12, 2)
>>> paginate(iter(items), page=1)
([10, 11], 12, 2)

This function also works with generators:

>>> def generate():
...     for idx in xrange(12):
...         yield idx
>>> paginate(generate())
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 12, 2)
>>> paginate(generate(), page=1)
([10, 11], 12, 2)

The max_per_page parameter can be used to set the number of items that should be displayed per page:

>>> items = xrange(12)
>>> paginate(items, page=0, max_per_page=6)
([0, 1, 2, 3, 4, 5], 12, 2)
>>> paginate(items, page=1, max_per_page=6)
([6, 7, 8, 9, 10, 11], 12, 2)
Raises:TracError – if page is out of the range of the paginated results.
trac.util.presentation.separated(items, sep=', ', last=None)

Yield (item, sep) tuples, one for each element in items.

The separator after the last item is specified by the last parameter, which defaults to None. (Since 1.1.3)

>>> list(separated([1, 2]))
[(1, ','), (2, None)]
>>> list(separated([1]))
[(1, None)]
>>> list(separated('abc', ':'))
[('a', ':'), ('b', ':'), ('c', None)]
>>> list(separated((1, 2, 3), sep=';', last='.'))
[(1, ';'), (2, ';'), (3, '.')]
trac.util.presentation.to_json(value)

Encode value to JSON.

Modules generating paginated output will be happy to use a rich pagination controller. See Query, Report and Search modules for example usage.

class trac.util.presentation.Paginator(items, page=0, max_per_page=10, num_items=None)

Bases: object

Pagination controller