Skip to content
This repository has been archived by the owner on Apr 4, 2023. It is now read-only.

Prefer blocks to subtemplates #358

Open
cmc333333 opened this issue May 18, 2016 · 3 comments
Open

Prefer blocks to subtemplates #358

cmc333333 opened this issue May 18, 2016 · 3 comments

Comments

@cmc333333
Copy link
Member

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.

cmc333333 pushed a commit to cmc333333/regulations-site that referenced this issue Jun 2, 2016
This uses the `enum` model introduced in Python 3.4 (but since backported).
I'm definitely not wedded to this, but I think it's a good model.

Mostly template changes. I'm not a fan of using `.name == 'MyValue`, but
Django's templates will silently fail if we were to do something like
meta.comment_state == CommentState.Mispelled
so I don't think we're actually losing anything with the string comparison.

Removes the "regulations/comment-write-closed.html" partial; we're preferring
blocks moving forward. See
eregs#358

Tests need to be updated
@adborden
Copy link
Member

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)

  • header
  • sub-header
  • toc-head
  • panel
  • panel-drawers
  • TOC, history, search-drawers
  • main-content
  • sidebar

Example blocks (components)

Search drawer

  • header
  • content

Sub-head

  • toc-head
  • content

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
Copy link
Member Author

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
Copy link
Member

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants