{# Field rendering shared by the three editing screens, so a course, a category and a page present the same controls in the same order and staff only have to learn them once. #} {% macro field(f) %}
{{ f.label(class="form-label") }} {{ f(class="form-control", **kwargs) }} {% for error in f.errors %}
{{ error }}
{% endfor %}
{% endmacro %} {% macro flashes() %} {% with messages = get_flashed_messages(with_categories=true) %} {% for category, message in messages %}
{{ message }}
{% endfor %} {% endwith %} {% endmacro %} {% macro visibility(form) %} {% set timezone = config['COURSES_TIMEZONE'] %} {# The two controls, together, with the timezone spelled out. A date typed in the wrong zone releases material early, and the field itself is the only place that warning is any use. #}
{{ _('Visibility') }}
{{ form.hidden(class="form-check-input") }} {{ form.hidden.label(class="form-check-label") }}
{{ _('Withheld from readers until you clear this, whatever the date below says.') }}
{{ form.publish_at.label(class="form-label") }} {{ form.publish_at(class="form-control") }}
{{ _('Local time in %(timezone)s. Leave it empty to release as soon as it is not hidden.', timezone=timezone) }}
{% for error in form.publish_at.errors %}
{{ error }}
{% endfor %}
{% endmacro %} {# The badge asks the service, not the row. It used to ask item.is_released(), which reads the item's own two columns and nothing else, and it lied in both directions: a page inside a withheld course showed as Visible while readers got a 404, and a hidden item with a date announced a release that was never going to arrive. Four states now, because "withheld" was hiding two different situations and a teacher needs to know which screen to go and fix. #} {% macro state_badge(item) %} {%- set status = visibility_state(item) -%} {%- if status.state == 'visible' -%} {{ _('Visible') }} {%- elif status.state == 'scheduled' -%} {{ _('Withheld until %(moment)s', moment=status.moment|course_datetime) }} {%- elif status.state == 'blocked' -%} {# Released in itself, and still unreachable. Naming what is holding it is the whole value of this state. #} {{ _('Held back by %(name)s', name=status.blocked_by.name) }} {%- else -%} {{ _('Withheld') }} {%- endif -%} {% endmacro %} {% macro delete_button(action, form, question) %}
{{ form.hidden_tag() }}
{% endmacro %}