Basic functionality

<ul>
  for (var i = 0; i != 5; i++) {
    <li data-index="${ i }">Item ${ i + 1 }</li>
  }
</ul>
<ul>
    <li data-index="0">Item 1</li>
    <li data-index="1">Item 2</li>
    <li data-index="2">Item 3</li>
    <li data-index="3">Item 4</li>
    <li data-index="4">Item 5</li>
</ul>

Templates are compiled down to valid JavaScript. Markup is usually echoed as a template literal which allows you to output expressions while in the markup context.

// child.nhp
// ---------
// <p>${ input.name.toUpperCase() }</p>
// exports.value = 42;

var a = 5;

var child = await include('./modules/child.nhp', {
  name: 'John'
});

<h1>Value: ${ child.value }</h1>
<p>JOHN</p>
<h1>Value: 42</h1>

You can pass arguments to included templates. Those templates, on the other hand, can export data—just like a Node module!

// data.json
// ---------
// {
//   "text": "This is JSON!"
// }

var ms = require('ms');
var data = require('./modules/data.json');

<h1>${ ms(Math.random() * 10e4) }</h1>
<pre>${ data.text }</pre>
<h1>45s</h1>
<pre>This is JSON!</pre>

The Node.js require() function works the same way in templates as it does in modules. In this case, it loads the ms utility and a local file.

var content = capture(() => {
  <div>
    <p>Hello!</p>
  </div>
});

<div>
  echo(content.toUpperCase());
</div>

exports.markup = content;
<div>
  <DIV>
    <P>HELLO!</P>
  </DIV>
</div>

You can capture markup in a variable by using the special capture() function. Then, you can export that markup for usage elsewhere.

<echo plain>
  with the "plain" option, you can echo stuff like:
  ` ' " \ \n \r ${ not a template literal }
</echo>

<echo escape>
  "escape" simply escapes
  <strong>all tags</strong>
  and other "HTML entities"
</echo>

<echo strip>
  <span>
    <p>
      "strip" removes whitespace between tags
    </p>
  </span>
</echo>

  with the "plain" option, you can echo stuff like:
  ` ' " \ \n \r ${ not a template literal }

  &quot;escape&quot; simply escapes
  &lt;strong&gt;all tags&lt;/strong&gt;
  and other &quot;HTML entities&quot;
<span><p>
      "strip" removes whitespace between tags
    </p></span>

To export larger chunks of markup, you can use the special <echo> tags that are used solely by the compiler. You can also specify options that alter the output.

Asynchronicity ✨

var promises = [];

for (var i = 0; i != 5; i++) {
  let wait = Math.random() * 250;

  promises.push(new Promise((resolve, reject) => {
    setTimeout(() => {
      <h1>Waited ${ wait }ms!</h1>
      resolve();
    }, wait);
  }));
}

<p>About to wait for stuff...</p>
await Promise.all(promises);
<p>Stuff happened, continue.</p>
<p>About to wait for stuff...</p>
      <h1>Waited 3.6968332802943538ms!</h1>
      <h1>Waited 78.33391169045417ms!</h1>
      <h1>Waited 175.93215305826422ms!</h1>
      <h1>Waited 181.37412831926304ms!</h1>
      <h1>Waited 246.68529125043025ms!</h1>
<p>Stuff happened, continue.</p>

Templates are compiled down to an async function. This means you can use await to resolve the template only after a certain asynchronous action (a Promise) has resolved first.

var axios = require('axios');
var endpoint = 'https://baconipsum.com/api/?type=all-meat&paras=1';

await axios({
  method: 'get',
  url: endpoint,
  timeout: 2000
}).then((res) => {
  res.data.forEach((para) => {
    <p>${ para }</p>
  });
}).catch((err) => {
  <p>Could not load bacon. 🐷</p>
});
    <p>Burgdoggen jowl drumstick fatback.  Ground round turkey burgdoggen flank leberkas tongue.  Ham hock chicken ball tip swine jowl turducken pork belly jerky frankfurter cow biltong beef ribs brisket.  Tail frankfurter turkey boudin flank meatball tri-tip ham hock jowl shoulder doner spare ribs capicola chicken.</p>

You can easily fetch data from an external source. In this case, we use the axios module to quickly load some bacon ipsum.


Note: These demos are run when you load the page and the output you've seen above is the actual output they've produced. See for yourself.