begin/end blocks: sub-templates

Nested templates are the def, the macro, the callable block, the sub-template of Evoque.

The $begin{label} and the $end{label} pair of directives define a sub-template, that is a template nested within a template (file or string). The label may be considered just as a named anchor, a destination inside the file to which one can point to directly--a sub-template is addressed via the label, using a syntax similar to fragment identifiers of a URL, i.e. #label. When being addressed locally, i.e. from within the body of the same parent (sub-)template, a sub-template may be addressed with just #label.

Outer sub-templates (i.e. sub-templates at the top level) are addressable from any other template;

Inner sub-templates (i.e. sub-templates within sub-templates) are private to their direct parent sub-template i.e. their scope is local to their parent sub-template.

Parameters

There is really only one parameter, and that is the label that is what is used to address the template.

$begin{ label } ...template body... $end{ label }

Execution

To be executed, they are evoque'd:

$evoque{template_name#label}

This will evaluate the nested template using a copy of the caller's context. Note that a nested template is a full-fledged template in its own right, and may therefore specify its own $prefer{} and $overlay{} directives i.e. it may specify its own preferences e.g. its own default data to use should the caller's context not specify a needed variable, or whether it is itself an overlay over another template.

Nested template principles

  • A label (for a begin/end block) that defines a nested template is unique within the parent template's scope.
  • All begin/end blocks contained in a template must be properly nested such that they do not overlap (same well-formedness principle as in XML).
  • Inner sub-templates may only be addessed locally i.e via #label from within the code body of the sub-template in which they are defined. Note, in case of the parent sub-template being an overly, and it does not locally define a #label sub, the inner sub-template is of course looked up from the overlaid template.
  • Outer sub-templates may be addessed both locally, as for inner sub-templates, as well as externally from within other templates--in which case the information to identify the top-level template must also be specified i.e name#label for an explicitly named template, or by something like template.html#label for a template implicitly named by its file name.
  • Within overlay templates it is possible to explicitly specify what level the lookup for a locally addressed nested template should start from i.e. if the name starts with a single "#" then start lookup from current level, if with "##" then from one level down, if with "###" then from two levels down, etc.
  • If only one of the begin or end directives is present, then the other is implied by, respectively, the beginning or the end of the string.
  • An outer nested template has all the characteristics of a standalone file or string template. The only apparent difference is in how it is addressed--as sub-templates are addressed with #label, one can consider that a standalone template is the special-case sub-template having the empty string as the label (and with both the begin and end directives being omitted and thus being simply just implied by the beginning and end of the template string).
  • A nested template is not automatically rendered when the template that defines it is rendered; it must be explicitly evoque'd.
  • Everything already established about directives applies, e.g. both begin and end may all be on same line, or each may span many lines; any of the two allowed delimeter pairs may be used; any whitespace around the label is ignored, etc.