{% endmacro %}
{#
flashed_messages: the shared alert list. A macro rather than a block so the
login page can render it inside its card -- a sign-in error banner at the
top of the page sits 10em above the form it belongs to.
#}
{% macro flashed_messages() %}
{% with messages = get_flashed_messages(with_categories=True) %}
{% if messages %}
{% for category, message in messages %}
{% set mapping = {'message': 'info', 'error': 'danger'} %}
{% set variant = ' alert-' ~ mapping.get(category, category) if category else '' %}
{{ message }}
{% endfor %}
{% endif %}
{% endwith %}
{% endmacro %}
{#
utc_timestamp: renders a stored (naive UTC) datetime.
The attribute keeps the exact instant with its offset; the text is the wall
clock, to the second and unlabelled -- the zone is named once per page by
tz_indicator. The tooltip leads with that same wall-clock text, verbatim,
then the exact instant in parens -- a truncated cell's tooltip must contain
what was cut off, not just the machine-readable value. EportalUtils.
renderTimestamps rewrites both the text and the tooltip to match; the page
must load eportal-js/utils.js.
#}
{% macro utc_timestamp(value) -%}
{%- if value -%}
{%- set iso = value|utc_isoformat -%}
{%- set display = value|utc_display -%}
{%- endif -%}
{%- endmacro %}
{#
tz_indicator: names the zone every timestamp on the page is printed in.
Once per page, in the navbar: the zone is one fact per page, and a column
heading is too narrow for an IANA name. On every page, from base.html: the
values are UTC whether or not a page happens to print one, so there is
nothing for a page to opt into and nothing it can forget. The zone *name*,
never an abbreviation or a fixed offset: one page shows rows either side of
a DST boundary.
#}
{% macro tz_indicator() -%}