Skip to content

Template Tree Elements ​

The Argument ​

The argument x (or however you name it) is an object, containing methods for each valid HTML element. For example, .div() is for creating <div> elements, .p() is for creating <p> elements, and so on. Each of these methods accepts multiple arguments, used for creating text content or child elements.

Here is an example of a simple table with one row and two columns:

js
(x) => {
  x.table(
    x.tr(
      x.td('Row 1, Column 1'),
      x.td('Row 1, Column 2'),
    )
  )
}
html
<table>
  <tr>
    <td>Row 1, Column 1</td>
    <td>Row 1, Column 2</td>
  </tr>
</table>

Element Properties (The First Argument) ​

The first argument also accepts an object, containing global element properties (id, class...) and element-specific properties:

js
(x) => {
  x.a(
    {
      class: 'anchors', // "class" is valid for all elements
      href: 'https://github.com/' // "href" is specific for <a> elements only
    },
    'Go to GitHub'
  )
}
html
<a>Go to GitHub</a>

If the properties object is not the first argument, it is not honored. The following is NOT valid:

js
(x) => {
  x.a(
    'Go to GitHub',
    { href: 'https://github.com/' } // Doesn't work if not the first argument!
  )
}
html
<a>Go to GitHub</a>

By the way, you can pass the text content as a textContent property, or as a second argument:

js
(x) => {
  x.a({ href: 'https://github.com/', textContent: 'Go to GitHub' })
  x.a({ href: 'https://github.com/' }, 'Go to GitHub')
}
html
<a href="https://github.com/">Go to GitHub</a>
<a href="https://github.com/">Go to GitHub</a>

Text Content and Child Elements ​

Each argument can be any of the following.

Text ​

js
(x) => {
  x.div('text')
}
html
<div>text</div>

Number ​

js
(x) => {
  x.div(123456)
}
html
<div>123456</div>

Child Elements ​

js
(x) => {
  x.ul(
    x.li('List Item 1'),
    x.li('List Item 2'),
    x.li('List Item 3'),
  )
}
html
<ul>
  <li>List Item 1</li>
  <li>List Item 2</li>
  <li>List Item 3</li>
</ul>

Array of Child Elements ​

js
(x) => {
  x.ul(
    [
      x.li('List Item 1'),
      x.li('List Item 2'),
      x.li('List Item 3'),
    ]
  )
}
html
<ul>
  <li>List Item 1</li>
  <li>List Item 2</li>
  <li>List Item 3</li>
</ul>

Mixed ​

js
(x) => {
  x.p(
    'The quick brown ',
    x.strong('fox'),
    [' jumped', 3, 'times'],
    [' over the lazy '],
    x.strong('dog')
  )
}
html
<p>The quick brown <strong>fox</strong> jumped 3 times over the lazy <strong>dog</strong></p>

Format Array ​

Where the type of the accepted argument or property is string, you can use format array instead. The idea is similar to the Node's format() function. The first element in the array is the printf-like format string, and the format arguments.

js
(x) => {
  x.p(
    {
      class: ['a', 'b', 'c']
    },
    ['The quick %s jumped %d times over the %s', 'brown fox', 3, 'lazy dog']
  )
}
html
<p class="a b c">The quick brown fox jumped 3 times over the lazy dog</p>

The Template Tree is Synchronous ​

In the following example the <h2> element will not be rendered, because .h2() is executed after the tree has already been rendered:

js
(x) => {
  x.h1('h1 element')
  setTimeout(() => x.h2('h2 element'), 0)
  x.h3('h3 element')
}
html
<h1>h1 element</h1>
<h3>h3 element</h3>