diff options
Diffstat (limited to 'specs/~inheritance.yml')
-rw-r--r-- | specs/~inheritance.yml | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/specs/~inheritance.yml b/specs/~inheritance.yml new file mode 100644 index 0000000..07fa081 --- /dev/null +++ b/specs/~inheritance.yml @@ -0,0 +1,226 @@ +overview: | + Like partials, Parent tags are used to expand an external template into the + current template. Unlike partials, Parent tags may contain optional + arguments delimited by Block tags. For this reason, Parent tags may also be + referred to as Parametric Partials. + + The Parent tags' content MUST be a non-whitespace character sequence NOT + containing the current closing delimiter; each Parent tag MUST be followed by + an End Section tag with the same content within the matching Parent tag. + + This tag's content names the Parent template to inject. Set Delimiter tags + Preceding a Parent tag MUST NOT affect the parsing of the injected external + template. The Parent MUST be rendered against the context stack local to the + tag. If the named Parent cannot be found, the empty string SHOULD be used + instead, as in interpolations. + + Parent tags SHOULD be treated as standalone when appropriate. If this tag is + used standalone, any whitespace preceding the tag should be treated as + indentation, and prepended to each line of the Parent before rendering. + + The Block tags' content MUST be a non-whitespace character sequence NOT + containing the current closing delimiter. Each Block tag MUST be followed by + an End Section tag with the same content within the matching Block tag. This + tag's content determines the parameter or argument name. + + Block tags may appear both inside and outside of Parent tags. In both cases, + they specify a position within the template that can be overridden; it is a + parameter of the containing template. The template text between the Block tag + and its matching End Section tag defines the default content to render when + the parameter is not overridden from outside. + + In addition, when used inside of a Parent tag, the template text between a + Block tag and its matching End Section tag defines content that replaces the + default defined in the Parent template. This content is the argument passed + to the Parent template. + + The practice of injecting an external template using a Parent tag is referred + to as inheritance. If the Parent tag includes a Block tag that overrides a + parameter of the Parent template, this may also be referred to as + substitution. + + Parent templates are taken from the same namespace as regular Partial + templates and in fact, injecting a regular Partial is exactly equivalent to + injecting a Parent without making any substitutions. Parameter and arguments + names live in a namespace that is distinct from both Partials and the context. +tests: + - name: Default + desc: Default content should be rendered if the block isn't overridden + data: { } + template: | + {{$title}}Default title{{/title}} + expected: | + Default title + + - name: Variable + desc: Default content renders variables + data: { bar: 'baz' } + template: | + {{$foo}}default {{bar}} content{{/foo}} + expected: | + default baz content + + - name: Triple Mustache + desc: Default content renders triple mustache variables + data: { bar: '<baz>' } + template: | + {{$foo}}default {{{bar}}} content{{/foo}} + expected: | + default <baz> content + + - name: Sections + desc: Default content renders sections + data: { bar: {baz: 'qux'} } + template: | + {{$foo}}default {{#bar}}{{baz}}{{/bar}} content{{/foo}} + expected: | + default qux content + + - name: Negative Sections + desc: Default content renders negative sections + data: { baz: 'three' } + template: | + {{$foo}}default {{^bar}}{{baz}}{{/bar}} content{{/foo}} + expected: | + default three content + + - name: Mustache Injection + desc: Mustache injection in default content + data: {bar: {baz: '{{qux}}'} } + template: | + {{$foo}}default {{#bar}}{{baz}}{{/bar}} content{{/foo}} + expected: | + default {{qux}} content + + - name: Inherit + desc: Default content rendered inside inherited templates + data: { } + template: | + {{<include}}{{/include}} + partials: + include: "{{$foo}}default content{{/foo}}" + expected: "default content" + + - name: Overridden content + desc: Overridden content + data: { } + template: "{{<super}}{{$title}}sub template title{{/title}}{{/super}}" + partials: + super: "...{{$title}}Default title{{/title}}..." + expected: "...sub template title..." + + - name: Data does not override block + desc: Context does not override argument passed into parent + data: { var: 'var in data' } + template: "{{<include}}{{$var}}var in template{{/var}}{{/include}}" + partials: + include: "{{$var}}var in include{{/var}}" + expected: "var in template" + + - name: Data does not override block default + desc: Context does not override default content of block + data: { var: 'var in data' } + template: "{{<include}}{{/include}}" + partials: + include: "{{$var}}var in include{{/var}}" + expected: "var in include" + + - name: Overridden parent + desc: Overridden parent + data: { } + template: "test {{<parent}}{{$stuff}}override{{/stuff}}{{/parent}}" + partials: + parent: "{{$stuff}}...{{/stuff}}" + expected: "test override" + + - name: Two overridden parents + desc: Two overridden parents with different content + data: { } + template: | + test {{<parent}}{{$stuff}}override1{{/stuff}}{{/parent}} {{<parent}}{{$stuff}}override2{{/stuff}}{{/parent}} + partials: + parent: "|{{$stuff}}...{{/stuff}}{{$default}} default{{/default}}|" + expected: | + test |override1 default| |override2 default| + + - name: Override parent with newlines + desc: Override parent with newlines + data: { } + template: "{{<parent}}{{$ballmer}}\npeaked\n\n:(\n{{/ballmer}}{{/parent}}" + partials: + parent: "{{$ballmer}}peaking{{/ballmer}}" + expected: "peaked\n\n:(\n" + + - name: Inherit indentation + desc: Inherit indentation when overriding a parent + data: { } + template: "{{<parent}}{{$nineties}}hammer time{{/nineties}}{{/parent}}" + partials: + parent: | + stop: + {{$nineties}}collaborate and listen{{/nineties}} + expected: | + stop: + hammer time + + - name: Only one override + desc: Override one parameter but not the other + data: { } + template: "{{<parent}}{{$stuff2}}override two{{/stuff2}}{{/parent}}" + partials: + parent: "{{$stuff}}new default one{{/stuff}}, {{$stuff2}}new default two{{/stuff2}}" + expected: "new default one, override two" + + - name: Parent template + desc: Parent templates behave identically to partials when called with no parameters + data: { } + template: "{{>parent}}|{{<parent}}{{/parent}}" + partials: + parent: "{{$foo}}default content{{/foo}}" + expected: "default content|default content" + + - name: Recursion + desc: Recursion in inherited templates + data: {} + template: "{{<parent}}{{$foo}}override{{/foo}}{{/parent}}" + partials: + parent: "{{$foo}}default content{{/foo}} {{$bar}}{{<parent2}}{{/parent2}}{{/bar}}" + parent2: "{{$foo}}parent2 default content{{/foo}} {{<parent}}{{$bar}}don't recurse{{/bar}}{{/parent}}" + expected: "override override override don't recurse" + + - name: Multi-level inheritance + desc: Top-level substitutions take precedence in multi-level inheritance + data: { } + template: "{{<parent}}{{$a}}c{{/a}}{{/parent}}" + partials: + parent: "{{<older}}{{$a}}p{{/a}}{{/older}}" + older: "{{<grandParent}}{{$a}}o{{/a}}{{/grandParent}}" + grandParent: "{{$a}}g{{/a}}" + expected: c + + - name: Multi-level inheritance, no sub child + desc: Top-level substitutions take precedence in multi-level inheritance + data: { } + template: "{{<parent}}{{/parent}}" + partials: + parent: "{{<older}}{{$a}}p{{/a}}{{/older}}" + older: "{{<grandParent}}{{$a}}o{{/a}}{{/grandParent}}" + grandParent: "{{$a}}g{{/a}}" + expected: p + + - name: Text inside parent + desc: Ignores text inside parent templates, but does parse $ tags + data: { } + template: "{{<parent}} asdfasd {{$foo}}hmm{{/foo}} asdfasdfasdf {{/parent}}" + partials: + parent: "{{$foo}}default content{{/foo}}" + expected: + hmm + + - name: Text inside parent + desc: Allows text inside a parent tag, but ignores it + data: {} + template: "{{<parent}} asdfasd asdfasdfasdf {{/parent}}" + partials: + parent: "{{$foo}}default content{{/foo}}" + expected: default content |