.. _Templates: ----------- Template(s) ----------- .. toctree:: :maxdepth: 2 :caption: Contents: :glob: templates/head templates/body The structure described in the :ref:`introduction ` is a bit "snoep" structurally. The ` `_ and ` `_ elements are fleshed out by |Project| to be more practical. Both elements are enclosed within their own blocks and provided a minimal substructure [#aside]_ that is readily overridden. .. table:: Actual **skeleton** and resulting *scaffold*. :widths: auto :align: center +-----------------------------+-----------------------------+ | Skeleton | Scaffold | +=============================+=============================+ | :: | :: | | | | | {% block html dtd %} | | | | | | {% endblock dtd %} | | | {% block html %} | | | | | | {% block head %} |
| | |
| | | | | {% block body %} |
| | |
| | {% block %} | | |
|
| |
| | | {% endblock %} | | | {% block %} | | | | | | {% endblock %} | | | {% block %} | | |
| | |
| | | {% endblock %} | | | {% block aside %} | | | {% endblock %} | | | {% block %} | | |
| | |
| | | {% endblock %} | | | | | | {% endblock body %} | | | | | | {% endblock html %} | | | | | +-----------------------------+-----------------------------+ The *skeleton* provides a "formally" correct HTML 5 document while allowing the user to modify this per their needs. The :ref:`Head` and :ref:`Body` sections elaborate more upon the basic structure outlined above. Blocks ====== |Project| 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. .. _block-naming: Naming ------ The following naming convention is used within the **skeleton** template. .. productionlist:: webplates block : [`root` + "_"] + `tag` + ["_" + `stem`] .. strings = ["dtd","html","html_init","head","head_init","head_prefix","browser","IE","site","site_prefix","site_content","site_icon","site_title","site_search","site_suffix","page","view","meta","meta_prefix","meta_content","meta_favicon","meta_author","meta_charset","meta_content_type","meta_language","meta_description","meta_browser","meta_compatibility","meta_viewport","meta_devices","meta_generator","meta_application","meta_keywords","meta_othertags","meta_refresh","meta_robots","meta_suffix","links","rss","css","css_prefix","css_content","css_libs","css_layout","css_fonts","css_style","css_site","css_page","css_view","css_suffix","head_js","js","head_js_prefix","js_prefix","head_js_content","js_content","head_js_libs","js_libs","head_js_site","js_site","head_js_page","js_page","head_js_view","js_view","head_js_suffix","js_suffix","head_suffix","head_term","body","body_init","body_content","header","header_init","header_head","header_body","header_banner","header_title","header_route","header_breadcrumb","header_foot","header_term","nav","nav_init","nav_head","nav_body","nav_content","nav_foot","nav_term","main","main_init","main_head","main_body","main_content","content","main_foot","main_term","aside","aside_init","aside_head","aside_body","aside_content","aside_foot","aside_term","footer","footer_init","footer_head","footer_body","footer_breadcrumb","footer_legal","footer_foot","footer_term","body_term","foot","foot_js","foot_js_libs","foot_js_site","foot_js_page","foot_js_view","html_term"] .. regex = re.compile("(?:(?Phead|body|foot)_)?(?P[^_]*)(?:_(?P[^_]*))?") .. [print(string.split("_"),"\n", regex.match(string).groups()) for string in strings] .. pre,tag,suf = map(set,(zip(*(regex.match(string).groups() for string in strings)))) 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 ``
`` element in ``
...`` is referenced as ``main`` in the template language references rather then ``html_body_main``. * Repeated blocks are ideally distinguished by their enclosing tag where possible e.g. ``head_js`` and ``body_js`` is preferrable to ``head_js`` and ``js``. * 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`` and ``css_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_...`` and ``foot_js_...`` instead of ``js_...``. .. _tags:: Root(s) ~~~~~~~ The :token:`weplates:root` that precedes the :token:`weplates:tag` is used to distinguish a group of :ref:`tags `. .. productionlist:: webplates root: "head" | "body" | "foot" This splits the **skeleton** into three parts, "head" and "body " mapping respectively to the ```` and ```` 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 ```` setting the ``deferred`` attribute to delay their execution when required. .. admonition:: Example Javascript libraries, commonly, are included in either the ```` or at the end of the ```` element within a document. Correspondingly |Project| 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 ```` element. Importing the code at the end of the ```` 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) ~~~~~~ :token:`Tags ` are used to identify a group of related blocks within the **skeleton**. .. productionlist:: webplates tag : `html` | `meta` | `framework` These are split into roughly three groups. .. [#tags] 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]. .. productionlist:: webplates html : "header" | "nav"" | "main" | "aside" | "footer" Meta Tag(s) ``````````` This is largely for meta information that is passed between the server and the client. .. productionlist:: webplates 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. .. productionlist:: webplates 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. .. productionlist:: webplates stem: `part` | `item` | `end` There are three such specializations. Part(s) ``````` The :token:`weplates:part` succeeds the :token:`weplates:tag` to distinguishes the individual elements of a group of :ref:`tags `. .. productionlist:: webplates part : "head" | "body" | "foot" : "prefix" | "content" | "suffix" :token:`Parts ` are used universally to split a :ref:`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. .. productionlist:: webplates 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. .. admonition:: 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 %} | {% block html %} | | | | | {% block head %}{% endblock head %} | {% block body %}{% endblock body %} | | {% block body %}{% endblock body %} | | | | {% endblock html %} | | {% endblock html %} | | | | | +------------------------------------------------------+-------------------------------------------------------+ Jinja2 provides a :meth:`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. |Project| resolves this with a workaround that wraps all of the opening and closing tags with their own blocks, hence the :token:`webplates:end` terms in block names. .. productionlist:: webplates end : "init" | "term" By consistently wrapping its tags the parent effectively "unwraps" the inner blocks. .. admonition:: Example Application to the example above eliminates the error within the child template. +------------------------------------------------------+-------------------------------------------------------+ | Parent | Child | +------------------------------------------------------+-------------------------------------------------------+ |:: |:: | | | | | {% block html %} | {% block html_init %}{% endblock html_init %} | | {% block html_init %}{% endblock html_init %} | {% block body %}{% endblock body %} | | {% block head %}{% endblock head %} | {% block html_term %}{% endblock html_term %} | | {% block body %}{% endblock body %} | | | {% block html_term %}{% endblock html_term %}| | | {% endblock html %} | | | | | +------------------------------------------------------+-------------------------------------------------------+ 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 |Project| will nest the block within the canonical variant within the templates. Such practice is done for convenience but heavily discouraged. .. rubric:: footnotes .. [#aside] 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.