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>55s</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 33.51622121045883ms!</h1>
      <h1>Waited 48.01753504788231ms!</h1>
      <h1>Waited 113.08600730059764ms!</h1>
      <h1>Waited 221.71896231284722ms!</h1>
      <h1>Waited 234.2395926978797ms!</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>Shankle spare ribs frankfurter chuck sausage pork chop, meatball ground round picanha landjaeger.  Tenderloin turducken beef ribs short loin hamburger, doner burgdoggen sirloin ribeye spare ribs chicken tongue.  Burgdoggen alcatra tri-tip, pastrami tenderloin capicola kielbasa beef flank turducken fatback strip steak picanha.  Andouille leberkas prosciutto bresaola rump pork belly.  Meatloaf brisket alcatra tongue sirloin.  Pork belly leberkas tongue doner, bacon shankle frankfurter capicola.  Pastrami prosciutto jowl drumstick fatback t-bone chicken capicola ham hock doner pork loin.</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.