Skip to content

Instantly share code, notes, and snippets.

@booch
Last active January 8, 2023 03:29
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save booch/3e8d89241f549724e212 to your computer and use it in GitHub Desktop.
Save booch/3e8d89241f549724e212 to your computer and use it in GitHub Desktop.
HTML Templating Patterns

HTML Templating Patterns

I've decided to try documenting the different patterns used in HTML templates. By HTML templates, I mean taking some HTML(ish) text, and inserting dynamically-generated content. This templating can take place on the web server or in the browser; the patterns don't usually differ between the two.

Delimited HTML

Almost all of the most commonly-used templating systems use this pattern. The HTML has embedded code within with some non-HTML delimiters (such as <% %> or {{}}).

Pros

  • Very common
  • Well understood
  • Some variants enforce separation of logic and presentation

Cons

  • Might not be able to use in a WYSIWYG HTML editor
  • Can't use XML/HTML tools to manipulate the HTML

Examples

  • JSP
  • ASP
  • PHP
  • ERB
  • Mustache
  • FreeMarker

Tag Libraries

Tag libraries provide additional tags (elements) that can be used within an HTML(ish) document.

Pros

  • Easier for developers to work with
  • Less verbose than HTML
  • Shows intent of HTML structure better than HTML
  • Some enforcement of separation of logic and presentation
  • Can use XML/HTML tools to manipulate the HTML

Cons

  • No WYSIWYG support at all
  • Hard for designers to work with

Examples

  • Web Components
  • JSTL
  • Radius (Ruby)

Non-HTML

Pros

  • Easier for developers to work with
  • Shows HTML structure better than HTML
  • Less verbose than HTML
  • Some variants enforce separation of logic and presentation

Cons

  • No WYSIWYG support at all
  • Hard for designers to work with
  • Can't use XML/HTML tools to manipulate the HTML

Examples

  • HAML
  • Slim
  • Jade
  • Angular (components)

Template Attribute Language

This pattern uses standard HTML, enhanced only with extra attributes on elements.

Pros

  • Enforces separation of logic and presentation
  • Templates can be round-tripped through most WYSIWYG HTML editors
  • Can use XML/HTML tools to manipulate the HTML

Cons

  • Not commonly used, so harder to understand
  • Developers and designers share the template file

Examples

  • Angular directives (typical style)
  • ZPT (Zope Page Templates) TAL
  • PHPTAL
  • Thymeleaf (Java)
  • Flower (Perl 6)

HTML-only

This pattern uses a plain HTML file, with no special markup (other than classes and IDs). The code adds the dynamic content via CSS (or possibly XPath) selectors. The mapping between selectors and dynamic content might be in a separate file, or within the code.

Pros

  • Enforces separation of logic and presentation
  • Templates can be round-tripped through ALL WYSIWYG HTML editors
  • Can use XML/HTML tools to manipulate the HTML
  • Composable

Cons

  • Not commonly used, so harder to understand
  • More pieces in play - template, content, and mapping

Examples

  • Amrita (Ruby)
  • Enlive (Clojure)
  • Pure.js
  • Psttt (PHP)

Code-only

In this pattern, the HTML

Pros

  • Easy for developers to work with

Cons

  • No WYSIWYG support at all
  • Hard for designers to work with
  • Can't use XML/HTML tools to manipulate the HTML

Examples

  • Builder (Ruby)
  • Elm

Mixed

When researching this, I found that Angular mixes several of these (delimited, taglib, and TAL):

<!-- These all match the `foo` directive. -->
<input ng-model="foo" /> <!-- TAL (with non-HTML-compliant attributes)-->
<input data-ng-model="foo" /> <!-- TAL (with HTML5-compliant attributes) -->
<foo>{{name}}</foo> <!-- Delimited, inside a taglib-style element -->

I also took a look at React.JS rendering, which seems to be a mix of a taglib and delimited, but JSX also allows easily mixing code and markup:

<div>
  <AddTodoComponent/>
  <TodosListComponent/>
</div>

var AddTodoComponent = React.createClass({
  render: function () {
    return (
      <form>
        <input type="text" disabled={AppStore.isSaving()}/>
      </form>
    );
  }
});
@waldyrious
Copy link

This is so cool! Thanks for sharing your research. Would you consider making this a proper repository so other people could submit contributions and improvements?

For example, I believe Marko would be a good addition to the "Tag Libraries" section, and the "Template Attribute Language" section should probably use the "Natural templating" terminology that Thymeleaf uses, since TAL is a specific language that e.g. Thymeleaf doesn't conform to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment