ui icon indicating copy to clipboard operation
ui copied to clipboard

[New templating] Allow invoking a template from within another template

Open Tarmil opened this issue 8 years ago • 1 comments

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 if TemplateName is 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}: attribute X="value"? child element <X>value</X> (like in the example above)? I think we can allow both.

    • ws-hole="X" or ws-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 attribute X="Y" to define that this can be filled by a hole named Y in the containing template; and if it's not there, then the containing template has a hole named X.

    • ws-var="X": same as onfoo="X".

Tarmil avatar Mar 23 '17 22:03 Tarmil

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.

Tarmil avatar Mar 26 '17 01:03 Tarmil