Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend templating with HTML5 templates #252

Closed
3 tasks done
granicz opened this issue Nov 7, 2022 · 1 comment
Closed
3 tasks done

Extend templating with HTML5 templates #252

granicz opened this issue Nov 7, 2022 · 1 comment

Comments

@granicz
Copy link
Member

granicz commented Nov 7, 2022

This is a proposal to extend the UI templating syntax (using ws-... attributes to mark templates, placeholders, event handlers, etc.) with simple HTML5 templates using the <template> and <slot> elements.

The HTML5 format more or less(*) corresponds to a WebSharper.UI templates with a ws-children-template \ ws-hole configuration. So this HTML5 template:

<template id="person-with-age">
  Hello <slot name="FirstName"></slot>!
  Are you really <slot name="Age"></slot> years old?
</template>

can be thought of as the equivalent of:

<template ws-children-template="PersonWithAge">
  Hello <slot ws-hole="FirstName"></slot>
  Are you really <slot ws-hole="Age"></slot> years old?
</template>

The primary use of HTML5 templates is with web components and their shadow DOM, but bringing them into UI templating can utilize them in any markup. Conveniently, <template> elements are not rendered by browsers, but they can still be cloned.

A typical web component setup in JS would be something like:

customElements.define('person-with-age', class extends HTMLElement {
 constructor() {
   super();
   let template = document.getElementById("person-with-age").content;
   const shadowRoot = this.attachShadow({ mode: "open" });
   shadowRoot.appendChild(template.cloneNode(true));
 }
});

When using this web component, one can instantiate FirstName and Age by giving named sub-nodes:

<person-with-age>
 <span slot="FirstName">John</span>
 <span slot="Age">32</span>
</person-with-age>

(*) There are a couple details that require special handling when we bring in HTML5 templates into UI templating, however:

  • Default slots - these occur when an nameless <slot> element is used. If there are multiple such elements in a template, the first occurrence should be assumed to be the default slot. For these, we should generate a custom member with a name that can't otherwise be used in the template source. One idea would be to generate .Default and giving an error if the template contains a "Default" named slot.

  • Being able to just use the template text as is, without zeroing out any placeholders. Here, no .Elt(keepUnfilled=true) is available or possible, so we should provide a .Text() : string and a .Content(): DocumentFragment member (just for HTML5 templates, not the regular UI ones.)

  • Normalizing template/slot names when exposing them as template code members - here, just use the "capitalize each word" method, so person-with-age becomes PersonWithAge, etc.

@granicz
Copy link
Member Author

granicz commented Nov 9, 2022

Clarification/enhancement: when a <template> element without an id attribute is encountered, we can still interpret it as a valid UI template if it has a name attribute. Any other form should not be parsed as a template.

Jooseppi12 added a commit that referenced this issue Nov 14, 2022
@granicz granicz added this to High priority for current version in Releases Nov 16, 2022
granicz pushed a commit that referenced this issue Dec 14, 2022
* #252 - HTML5 based templates

* Cleanup, comments
@Jand42 Jand42 closed this as completed Dec 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Releases
High priority for current version
Development

No branches or pull requests

3 participants