1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
"""
byceps.util.templatefilters
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Provide and register custom template filters.

:Copyright: 2014-2025 Jochen Kupperschmidt
:License: Revised BSD (see `LICENSE` file for details)
"""

from flask_babel import gettext
from jinja2 import pass_eval_context, Undefined
from jinja2.filters import do_trim
from markupsafe import escape, Markup
from moneyed import Money

from .l10n import format_money


@pass_eval_context
def dim(eval_ctx, value):
    """Render value in a way so that it looks dimmed."""
    dimmed = _dim(value)
    return _wrap_markup_on_autoescape(eval_ctx, dimmed)


def _dim(value):
    return f'<span class="dimmed">{escape(value)}</span>'


@pass_eval_context
def fallback(eval_ctx, value, fallback=None):
    if not isinstance(value, Undefined) and value:
        result = do_trim(value)

        if eval_ctx.autoescape:
            result = escape(result)
    else:
        if fallback is None:
            fallback = gettext('not specified')

        if eval_ctx.autoescape:
            fallback = escape(fallback)

        result = _dim(fallback)

    return _wrap_markup_on_autoescape(eval_ctx, result)


def _wrap_markup_on_autoescape(eval_ctx, value):
    return Markup(value) if eval_ctx.autoescape else value


def moneyformat(money: Money) -> str:
    """Format monetary value with amount and currency."""
    return format_money(money)


def register(app):
    """Make functions available as template filters."""
    functions = [
        dim,
        fallback,
        moneyformat,
    ]

    for f in functions:
        app.add_template_filter(f)