Template Syntax

The Lessjs component library is developed based on Web Components technology. In page development, some data needs to be obtained asynchronously through API requests. When the page is loaded, the data has not been requested yet, so the content cannot be rendered to the page immediately. Therefore, we can use the <template> element to write markup templates that are not displayed in the page presentation. When the data is returned, the component will immediately render its template.

Specify Template

Templates can be specified in the following two ways:

Template ID

Any template on the page can be specified by its template ID. There must be only one root element inside the template.

<spz-render layout="container" template="render-template"></spz-render>
<template id="render-template">
  <div>
    Render Outer Template
  </div>
</template>

As a Child Element

Nest the template inside the component element, making it a child element of the component element.

<spz-render layout="container">
  <template>
    <div>
      Render Inner Template
    </div>
  </template>
</spz-render>

Template Syntax

Within the template, data can be used to access the data injected by the component. When using the first-level attributes in data, the data field can be omitted.

Syntax rules:

  • No spaces are allowed before and after ||, &&, and the ternary operator (?:), e.g.: ${data.name||data.handle}
  • Avoid == and != (implicit type coercion). Prefer === and !==
  • Comments of any type are not allowed

Text Interpolation

The most basic form of data retrieval is text interpolation, which uses placeholders (an embedded expression delimited by a dollar sign and curly braces: ${}) to extract data. It is consistent with the usage of template strings. When used directly in elements, there is no need to wrap it with backticks. The following example shows text data retrieved from the template:

<template>
  <div>
    <span>${data.name}</span>
    <!-- Equivalent to (display only, comments are not supported inside the template) -->
    <span>${name}</span>
  </div>
</template>

Raw HTML

Using placeholders outside the template will interpret the data as plain text, not as the retrieved data.

<div>${data.name}</div>

Using IIFE Functions

When the data inside the template cannot be used directly and needs to be processed through a function, IIFE (Immediately Invoked Function Expression) can be written inside ${} to process and present the data. We do not recommend performing any DOM operations in the template function, but only using it for data processing. If you want to manipulate DOM elements, we recommend using the spz-script element.

<template>
  <div>
    <h3>${title}</h3>

    ${function() {
      const variants = (data.variants || []).map((variant) => {
        // ...
      });

      return `
        <div>
          <div spz-for="variant in variants">
            <!-- ... -->
          </div>
        </div>
      `;
    }()}
  </div>
</template>

Ternary Expression

Ternary expressions can be written inside placeholders.

<spz-render layout="container">
  <template>
    <div>
      ${name ? name : 'not exist name'}
    </div>
</template>
</spz-render>

Template Commands

Templates support spz-for, spz-if, and spz-else commands.

spz-for

  • Render elements multiple times based on the original data. Expected binding value types: Array | Object | Iterable.
  • The directive value must use special syntax alias in expression or alias of expression to provide an alias for the element being iterated:
<script id="render-json" type="application/json">
  [1, 2, 3, 4, 5]
</script>

<spz-render layout="container" src="script:render-json">
  <template>
    <ul>
      <li spz-for="value in data">${value}</li>
    </ul>
  </template>
</spz-render>

Alternatively, you can also specify an alias for the index (or key if used on an object):

<script id="render-index-json" type="application/json">
  [1, 2, 3, 4, 5]
</script>

<spz-render layout="container" src="script:render-index-json">
  <template>
    <ul>
      <li spz-for="(value, index) in data">${index} - ${value}</li>
    </ul>
  </template>
</spz-render>

spz-for tries to update elements in place without moving them by default. To force it to reorder the elements, you need to provide a sorting hint with a special key attribute:

<script id="render-key-json" type="application/json">
  [1, 2, 3, 4, 5]
</script>

<spz-render layout="container" src="script:render-key-json">
  <template>
    <ul>
      <li spz-for="(value, index) of data" key="value">${index} - ${value}</li>
    </ul>
  </template>
</spz-render>

Note: Inside spz-for, the key and spz-if attributes do not need to use ${} placeholders and should be omitted directly. The component internally will add placeholders for these two attributes within the command.

spz-if and spz-else

These two commands can be used in pairs or spz-if can be used alone for conditional logic.

<script id="render-if-json" type="application/json">
  {
    "name": "lessjs"
  }
</script>

<spz-render layout="container" src="script:render-if-json">
  <template>
    <div>
      <div spz-if="${name === 'lessjs'}">Lessjs</div>
      <div spz-else>Not lessjs</div>

      <div>${name === 'lessjs' ? 'Lessjs' : 'Not Lessjs'}</div>
    </div>
</template>
</spz-render>

Elements Supporting Templates

Components that support fetching data from the API also support this syntax. A special case is the spz-countdown element, which does not fetch data from the API but passes countdown time data to the template, allowing users to customize the presentation style they want.

AI Usage Notes (LLM Ready)

  • Section density: detected 3 level-2 headings.
  • Example density: detected 2 code blocks.
  • Read conclusions first: extract definitions, constraints, and boundary conditions.
  • Then verify with examples: rely on executable snippets rather than prose only.
  • Finally cross-check: open related component pages to avoid doc/runtime drift.