magfest-archive / guests

Magfest band management plugin for ubersystem
GNU Affero General Public License v3.0
1 stars 1 forks source link

Revamp guest plugin templating system to allow better customization #104

Closed kitsuta closed 7 years ago

kitsuta commented 7 years ago

Implements a block-based templating system to minimize duplication and maximize overriding ability.

The goal of this was to allow full customization of all text in the plugin while allowing future extendability (e.g., via event plugins) and without creating a ton of maintenance in the future.

Guest Templating System FAQ

How does this work? Every template under /checklist/ holds information for both the snippet and the form related to a particular deadline. So, bio_deadline.html now holds text for the blurb on the guest's checklist and the form itself. It chooses which to display based on the template variable snippet.

The /checklist/index.html page sets snippet to True and then goes through the items in a group's checklist and, for each step, tries to include:

  1. The group-type specific checklist (e.g., guest_bio_deadline.html) if it exists
  2. The original checklist template (e.g., bio_deadline.html) as a fallback

Each page in /guests/ (e.g., /guests/bio.html) ALSO imports either the group-type-specific item or the original template. These pages set snippet to False.

Each group-type-specific template extends the original template for that step. In other words, checklist/guest_bio_deadline.html has {% extends "checklist/bio_deadline.html" %} at the top. It then uses block overrides to change the text.

What are the possible overrides? The blocks that may be overridden in each template are:

The pages under /guests/ just include templates. Why keep them? Jinja2 cannot have an included template override blocks in the parent, so we need an intermediary template. Besides, we still need guestbase.html to be extended.

Why not have a single child for each step that uses if-statements to change blocks? This code doesn't work as expected:

{% if guest.group_type == c.GUEST %}
{% block deadline_headline %}Step title just for guests{% endblock %}
{% endif %}

You might think that we could just include this template and it will only override the block for Guest type groups. Instead, the block override totally ignores the if statement and overrides the block no matter what. Whoops!

Why are the agreement and info pages different? It is assumed that every 'info' page (the admin overview of a group's information) and 'agreement' step (the written agreement a group must acknowledge) will be bespoke, so we use a slightly less convoluted system where a single template includes another template based on the group's type. Note that in this system there are no defaults, so if you need a group type of NewGroup to sign an agreement, you'll need to make a newgroup_agreement.html template

Why use if statements in guests/index.html if you avoid them everywhere else? Index.html is only one page, so it's a little less of a burden to just switch the text based on group type directly. Plus, since it's the basis for the steps' complicated system, trying to do inheritance with it proved to be a bit much.