eregs / regulations-site

Web interface for viewing U.S. federal regulations and other regulatory information
https://regulations.atf.gov/
Creative Commons Zero v1.0 Universal
20 stars 46 forks source link

Prefer blocks to subtemplates #358

Open cmc333333 opened 8 years ago

cmc333333 commented 8 years ago

We take (at least) two approaches to allowing clients to override markup. We've broken several of our templates into sub-templates ("partials" in rails-speak), meaning that client agencies need to know template names. We've also provided several blocks which can be overridden via something like django-overextends. The latter approach lends itself better to documentation (as the full markup in visible), so let's see which sub-templates can be replaced.

adborden commented 8 years ago

I've been thinking about this for a bit and have been collecting some notes. Here are my thoughts along with some suggestions. Hopefully others can chime in since this is only my experience and specific to the challenges related to fec-eregs.

I don't think a wholesale "blocks over sub-templates" is quite right. I would rather see a policy about when to use sub-templates and when blocks should be used. Here's some thoughts on the topic.

Other theming frameworks

I took a look at some other frameworks, but didn't find them particularly insightful, they're really solving a different use case than what we're looking at, but here's what I found.

These frameworks generally use django's standard templating to implement themes. They break templates into sub-templates, and overwrite files wholesale. Not using overextends to override block content. They also use custom template loaders for dynamically picking themes based on request paramters, but I don't think this will be much use to us.

Advantages of sub-templates

While blocks are nice because they allow you to replace content, sub-templates allow you to re-use and move content around.

Somewhere between blocks and sub-templates

After having some experience customizing fec-eregs, I feel like I would prefer sub-templates for high-level modules, and blocks for components of the module.

Example sub-templates (modules)

Example blocks (components)

Search drawer

Sub-head

Notice how toc-head is both a sub-template and a block. It allows you to customize the toc-head content OR move it to another location. Blocks alone won't let you do this.

Semantic styling

I also suggest that the LESS files be broken down by component and/or module. We're kind of doing this today, but we could be more explicit about it. I'd like the filenames to have better consistency with the sub-template or block names.

Thinking in BEM

I don't mean to confuse you with another "block" term, but the module-component breakdown is similar to how the BEM methodology describes Blocks and Elements and feeds nicely into the CSS semantics.

Nested blocks

chrome.html is the worst offender, but there are many nested blocks here. It makes it difficult to grok what's going on, and in your overridden template, I'm not even sure how best to organize all these blocks.

Some of the blocks in chrome.html are prefixed, I suggest we make this a convention when using nested blocks. For example:

{% block sub-head %}
  {% block sub-head--toc-head %}
  {% endblock %}
  {% block sub-head--content %}
  {% endblock %}
{% endblock%}

{% block panel %}
  {% block panel--drawer-toc %}{% endblock %}
  {% block panel--drawer-history %}{% endblock %}
  {% block panel--drawer-search %}{% endblock %}
{% endblock %}

And your override would look like:

{% overextends "chrome.html" %}

{% block sub-head--toc-head %}
{% endblock %}

{% block sub-head--content %}
{% endblock %}

Container inside block

Sometimes I see things like

<header class="header">
  {% block header %}{% endblock %}
</header>

and sometimes

{% block header %}
<header class="header">
</header>
{% endblock %}

I think the latter is more flexible and should be preferred.

cc @annalee

cmc333333 commented 8 years ago

Lots of good thoughts here, @adborden, thanks for sharing! @donjo and @xtine will be tackling some of this over the summer as we try to make the platform easier to theme. I'll preface by saying that our primary goal is to make simple theming (color schemes, fonts, etc.) easier; what you all are trying to do w/ FEC is a much heavier rework, but I think there is still significant overlap.

Agreed that template includes and blocks should have different purposes. It sounds like we're in agreement that sub-templates are for either reusable content (less needed, though we do have some reuse) or "modules" to help break down templates. The big disadvantage of sub-templates is that they're very difficult to read, particularly when there are dozens of replaceable chunks of content. Blocks (in the Django sense) really shine here, as they're described inline. I think we're ultimately in agreement here, too, and that we want to move the existing templates in this direction.

While I generally dislike BEM-style naming, I think it makes a lot of sense here, and something we should implement. I'd go one step further and argue that we should do everything we can to align our templates with our stylesheets in terms of naming conventions. Pie in the sky :)

On containers within blocks, I think there are two distinct use cases -- in the former, we want to replace some content (text, really), in the latter we want to replace markup. I think we can accomplish the former need through other mechanisms (configuration variables, and similar), which are more in line with our theming goals. I think, then, we should expect that the tag-inside-block approach to be the path forward and replace the block-inside-tags with variables and similar.

Regarding overextends -- it's definitely not a perfect solution (we've run into issues around recursive templates, in particular), but I think the approach is largely sound. Perhaps we could code up some sort of alternative (something like {% block-or-include "/path/here.html" %}?), though I'd worry about yet another custom system to keep in mind. We can also look at other template engines, if we think there's a better system.

In any event, we currently have several different approaches to the same problems (Many-to-many, really, given that we have many different problems); I'd really like to see a single-solution-per-problem-type, allowing different techniques for different issues. I apologize for not giving better context; it's certainly not the case that we should replace all sub-templates with blocks. I think we should replace the current mix of sub-templates and blocks + overextends for theming and agency-specific content with the latter, sans any issues we encounter with recursive templates.

adborden commented 8 years ago

Sounds great, glad we're mostly on the same page. Once other folks chime in, I'd like to document our conventions/recommendations in something like a README, CONTRIBUTING, theming guide, etc.