# 0027 Templating with custom web elements

Date: 2021-12-31

## Status

Accepted

## Context

[Custom Elements](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements)
(part of the Web Components standards) is a set of specific actions that allow
web developers to create HTML elements with their own defined behaviours. One
of the possible uses for custom elements is to transform the browser into a
templating engine: by expanding custom elements the way a templating engine
would have.

LedgerSMB uses Template Toolkit as its templating engine to generate HTML
documents on the server. On the browser, the Dojo Toolkit JavaScript library
renders widgets. The Template Toolkit output is annotated for processing by
Dojo Toolkit, replacing annotated HTML elements with DOM (sub)trees: its
widgets.

To make its annotated widgets work, Dojo Toolkit introduces a parsing
phase to the rendering of HTML documents: a phase where documents have been
rendered by the browser, but they are not functional yet: the widgets need
to be expanded. Additionally, when (parts) of a page are replaced, Dojo
first needs to remove the widgets in the scope of that part of the page.
This is because as part of its operation, Dojo maintains a registry of
widgets associated with the current DOM tree. Rendering a widget with a
`widget_id` that already exists in the registry causes rendering problems.

In order to make LedgerSMB work in its current implementation - using
Dojo and acting as a Single Page Application (SPA) - careful orchestration
is required coordinating Dojo with (partial) page loads. Since errors may
cause Dojo page processing to be aborted, this is a fragile process.

With Custom Elements, the process is generally the same as the one we use
from Dojo, with the notable difference that it's no longer Dojo which is
post processing page loads and pre processing page unloads: it's the browser
doing so. Every element added to or removed from the DOM tree is notified of
that event.

The custom element mechanism can be used to render Dojo widgets by wrapping
Dojo widgets as custom elements. This has the following benefits:

* No Dojo pre and post processing of the page is required  
  presumably, the browser can do this type of processing as part of its DOM
  creation -- reducing DOM handling
* Loading and unloading of Dojo widgets automatically becomes consistent

At the same time, the Template Toolkit can be simplified, because e.g.
defaulting of parameters can be offloaded to the custom elements on the browser.

## Decision

Custom Elements / Web Components will be used to wrap Dojo widgets with these
benefits:

* Elimination of the need to run the Dojo parser and unloader steps
* Consistency in unloading Dojo widgets, eliminating a fragile process
* Adding a layer of abstraction, opening opportunities to move to another
  widget library when the time comes

## Consequences

* Custom Element widgets need to be developed for each type of Dojo widget
* Template Toolkit needs to expand to custom elements (replacing Dojo widgets)
* Alternatives need to be identified for ContentPane, TabContainer and BorderContainer
  Dojo widgets used to define UI layout
* Alternatives need to be identified for widgets developed by the project (dojo
  module: `lsmb/`): Invoice, InvoiceLines, InvoiceLine, Form, SimpleForm  
  in other words: widgets which enhance the HTML output generated by scripts in `old/`

## Annotations

[ADR 0011 - Use Dojo Toolkit for active UI](./0011-use-Dojo-Toolkit-for-active-UI.md)
