Template(s)¶
The structure described in the introduction is a bit “snoep” structurally. The <HEAD> and <BODY> elements are fleshed out by Web-Templates to be more practical. Both elements are enclosed within their own blocks and provided a minimal substructure [2] that is readily overridden.
Skeleton | Scaffold |
---|---|
{% block html dtd %}
<!DOCTYPE html>
{% endblock dtd %}
{% block html %}
<html>
{% block head %}
<head>
</head>
{% endblock head %}
{% block body %}
<body>
{% block %}
<header>
</header>
{% endblock %}
{% block %}
<nav>
</nav>
{% endblock %}
{% block %}
<main>
</main>
{% endblock %}
{% block aside %}
{% endblock %}
{% block %}
<footer>
</footer>
{% endblock %}
</body>
{% endblock body %}
</html>
{% endblock html %}
|
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<header>
</header>
<nav>
</nav>
<main>
</main>
<!-- aside -->
<footer>
</footer>
</body>
</html>
|
The skeleton provides a “formally” correct HTML 5 document while allowing the user to modify this per their needs. The <Head> and <Body> sections elaborate more upon the basic structure outlined above.
Blocks¶
Web-Templates tries to provide the only the necessary blocks for authors to hook into. Peppering the skeleton with blocks is fairly harmless since they collapse to white space in the scaffold once the template is processed.
Naming¶
The following naming convention is used within the skeleton template.
block ::= [root
+ "_"] +tag
+ ["_" +stem
]
Within the templates the terms set aside for the template engine are kept as short and canonical as possible. Roughly speaking the terms are determined as follows :
- Use the last most unique element wherever possible e.g. the
<MAIN>
element in<HTML><BODY><MAIN>...
is referenced asmain
in the template language references rather thenhtml_body_main
.
- Repeated blocks are ideally distinguished by their enclosing tag where possible e.g.
head_js
andbody_js
is preferrable tohead_js
andjs
.
- Default/fallback blocks may also be identified e.g.
js
- Repeated blocks are otherwise distinguished by their intent e.g. the
css_site
,css_page
andcss_view
blocks separately identify the CSS code for the site itself, the current page and its different representations of that page e.g. monitor, mobile or print and horizontal or vertical layout.- Where is no canonical location for a block and alternate such locations exist then it is preferable to omit the default location e.g. use
head_js_...
andfoot_js_...
instead ofjs_...
.
Root(s)¶
The weplates:root
that precedes the weplates:tag
is used to distinguish a group of tags.
root ::= "head" | "body" | "foot"
This splits the skeleton into three parts, “head” and “body ” mapping respectively to the <head/>
and <body/>
tags in HTML.
“foot” is included by convention but has no analogue in HTML.
Javascript¶
foot
proves quite useful in placing javascript exclusively after the body, foot_js_...
as opposed to within the head, head_js_...
.
head_js_...
is synonymous with the more canonical js_...
blocks since users should really place their scripts in the <head/>
setting the deferred
attribute to delay their execution when required.
Example
Javascript libraries, commonly, are included in either the <head>
or at the end of the <body>
element within a document.
Correspondingly Web-Templates provides both head_js
and body_js
but it does not provide a default js
block since it should fall to the author to elect one location over the other.
Authors might consdier overriding one location with a default block substitution e.g. One authors {% block head_js %}{% block js %}{% endblock js %}{% endblock head_js %}
would clash with anothers {% block body_js %}{% block js %}{% endblock js %}{% endblock body_js %}
but this should be discouraged.
Note
Were a default js
block to be included the canonical location appears to be within <head>
element.
Importing the code at the end of the <body>
element appears to be a browser/SEO optimization for the most part;
specifically it makes the page structure avilable prior to loading any code that relies upon it.
Tag(s)¶
Tags
are used to identify a group of related blocks within the skeleton.
tag ::=html
|meta
|framework
These are split into roughly three groups.
[1] | The exceptions to this are the “browser” specific groups and the “site”, “view” and “page” tags which are used to distinguish site wide, page wide or extention specific and view wide blocks. |
HTML Tag(s)¶
These are named after the equivalent HTML tag that they enclose possible [#tags].
html ::= "header" | "nav"" | "main" | "aside" | "footer"
Meta Tag(s)¶
This is largely for meta information that is passed between the server and the client.
meta ::= "server" | "client" | "meta" | "css" | "rss" | "js"
The exceptions are for more esoteric blocks
- browser (Rename to client)
- Browser specific settings
- server (Not implemented)
- Server specific settings
- meta
- Provides various meta information .e.g. editorial, locale, location, caching, refresh etc.
- scripts
- The meta section also handles the various scripts e.g. Cascading style sheets, Javascript, RSS Feeds.
Framework Tag(s)¶
The framework tags prevent parts of the framework from clobbering other parts of the framework by splitting up where the various parties include their modification for each template.
framework ::= "site" | "page" | "view"
This splits the tags up as follows
- site
- Site wide settings that are applicable to all pages. Assigned by the website author in their base template; extending the skeleton.
- page
- Extentions specifci settings that are applicable to a group of related pages Assigned by the extention author in their base template; this extends the base template of the website.
- view
- Settings that are specific to a particular view. This serves as a hook for the website author to make any last adjustments for a given extention.
Stem(s)¶
The stem allows for specialization of the block name.
stem ::=part
|item
|end
There are three such specializations.
Part(s)¶
The weplates:part
succeeds the weplates:tag
to distinguishes the individual elements of a group of tags.
part ::= "head" | "body" | "foot" "prefix" | "content" | "suffix"
Parts
are used universally to split a tag into three parts, namely the head
, body
and foot
(Or synonmously the prefix
, contenst
and suffix
).
This allows users control over which part, within a tag group, their code belongs.
Item(s)¶
Items are highly specific and do not generalize especially well. They are mostly used to identify a specific object for substitution.
item ::= ITEM
End(s)¶
A curious scenario arises with certain template engines; when one template inherits another substituting an enclosing block it becomes necessary for child template to fully re-implement the block in the parent template.
Example
Consider modification of the opening tag in an html
block.
The child template has to re-implement the entire structure of the parent.
In the example below the head
block is accidentally excluded.
Parent | Child |
{% block html %}
<html OLD >
{% block head %}<head></head>{% endblock head %}
{% block body %}<body></body>{% endblock body %}
</html>
{% endblock html %}
|
{% block html %}
<html NEW >
{% block body %}<body></body>{% endblock body %}
</html>
{% endblock html %}
|
Jinja2 provides a super()
method that pulls in the structure of the parent block one is inheriting/extending.
The Django Template Engine by contrast provides no such mechanism.
Web-Templates resolves this with a workaround that wraps all of the opening and closing tags with their own blocks, hence the webplates:end
terms in block names.
end ::= "init" | "term"
By consistently wrapping its tags the parent effectively “unwraps” the inner blocks.
Example
Application to the example above eliminates the error within the child template.
Parent | Child |
{% block html %}
{% block html_init %}<html>{% endblock html_init %}
{% block head %}<head></head>{% endblock head %}
{% block body %}<body></body>{% endblock body %}
{% block html_term %}</html>{% endblock html_term %}
{% endblock html %}
|
{% block html_init %}<html>{% endblock html_init %}
{% block body %}<body></body>{% endblock body %}
{% block html_term %}</html>{% endblock html_term %}
|
Default(s)¶
In some cases a loose convention is presumed e.g. content
or main_content
if this is observed to be fairly prevalent and consistent then Web-Templates will nest the block within the canonical variant within the templates.
Such practice is done for convenience but heavily discouraged.
footnotes
[2] | An aside block is provided so that the user may readily populate this should their layout call for it but the skeleton does not otherwise populate the aside block. |