[New templating] Allow invoking a template from within another template
This would be tremendously helpful in particular to build a library of widgets and reuse them in templates. A basic example would be something like this (syntax to be refined):
<!-- Define a base template. -->
<a ws-template="Button" ws-attr="Attr">${Text}</a>
<!-- Use the above template within another template. -->
<div ws-template="Page">
<ws-Button>
<Attr id="button-in-page" ws-onclick="BtnClick" />
<Text>Click me!</Text>
</ws-Button>
</div>
<!-- Resulting HTML: -->
<div>
<a id="button-in-page" onclick="F# code filled as BtnClick">Click me!</a>
</div>
Here Page fills all of Button's holes, and notably it fills Attr using holes of its own; in the end the Page template has one hole, BtnClick. If Page left any of Button's holes unfilled, then it would "inherit" them.
This is a big feature with some intricacies that need to be addressed:
-
What's the syntax to invoke a template? Ideas:
-
<TemplateName>: looks nice, but ambiguous ifTemplateNameis a valid HTML element name. -
<.TemplateName>looks weird but would have the advantage of consistency when we introduce templates that can reference across files (#101) which would then be written as<FileName.TemplateName>. -
<ws-TemplateName>(like in the example above) looks consistent with the rest of the DSL. Cross-file could be written as<ws-FileName.TemplateName>. I think this is the best solution.
-
-
What's the syntax to fill the various types of holes that we have?
-
${X}: attributeX="value"? child element<X>value</X>(like in the example above)? I think we can allow both. -
ws-hole="X"orws-replace="X": child element named<X>content...</X>, whose children are the content. Do we also want a syntax to provide an element that is itself the content, something like<X-div>...</X-div>maybe? -
ws-attr="X": child element<X attrs... />with attributes on it. -
ws-onfoo="X": the only thing I can think of is using an attributeX="Y"to define that this can be filled by a hole namedYin the containing template; and if it's not there, then the containing template has a hole namedX. -
ws-var="X": same asonfoo="X".
-
After discussing with Andras, we think it will be more consistent with these changes:
-
${X}text holes: only filled by a child element<X>value</X>, not by an attribute. - Unfilled holes are not inherited.
- All types of holes can be "mapped" into holes for the containing template as described for
ws-onfoo.
This gives a much more consistent scheme:
- Attributes on the
<ws-...>element always define hole mappings. - Child elements always define hole fillings.
- A hole that is neither mapped nor filled is simply ignored.