1.5.0 • Published 16 days ago

ghtml v1.5.0

Weekly downloads
-
License
MIT
Repository
github
Last release
16 days ago

Replace your template engine with fast JavaScript by leveraging the power of tagged templates.

Inspired by html-template-tag.

Installation

npm i ghtml

API Reference

html

The html function is designed to tag template literals and automatically escape their expressions to prevent XSS attacks. To intentionally bypass escaping for a specific expression, prefix it with !.

htmlGenerator

The htmlGenerator function acts as the generator version of the html function. It facilitates the creation of HTML fragments iteratively, making it ideal for parsing large templates or constructing HTML content dynamically.

htmlAsyncGenerator

This version of HTML generator should be preferred for asynchronous use cases. The output will be generated as the promise expressions resolve.

Note:

Because they return generators instead of strings, a key difference of htmlGenerator and htmlAsyncGenerator is their ability to recognize and properly handle iterable elements within array expressions. This is to detect nested htmlGenerator and htmlAsyncGenerator usage, enabling scenarios such as ${[1, 2, 3].map(i => htmlGenerator`<li>${i}</li>`)}.

includeFile

Available for Node.js users, the includeFile function is a wrapper around readFileSync. It reads and outputs the content of a file while also caching it in memory for faster future reuse.

Usage

html

import { html } from "ghtml";

const username = '<img src="https://example.com/hacker.png">';
const greeting = html`<h1>Hello, ${username}!</h1>`;

console.log(greeting);
// Output: <h1>Hello, &lt;img src=&quot;https://example.com/hacker.png&quot;&gt;</h1>

To bypass escaping:

const img = '<img src="https://example.com/safe.png">';
const container = html`<div>!${img}</div>`;

console.log(container);
// Output: <div><img src="https://example.com/safe.png"></div>

When nesting multiple html expressions, always use ! as they will do their own escaping:

const someCondition = Math.random() >= 0.5;
const data = {
  username: "John",
  age: 21,
};

const htmlString = html`
  <div>
    !${someCondition
      ? html`
          <p>Data:</p>
          <ul>
            !${Object.values(data).map(
              ([key, val]) => html`<li>${key}: ${val}</li>`,
            )}
          </ul>
        `
      : "<p>No data...</p>"}
  </div>
`;

htmlGenerator

import { htmlGenerator as html } from "ghtml";
import { Readable } from "node:stream";
import http from "node:http";

http
  .createServer((req, res) => {
    const htmlContent = html`<html>
      <p>${"...HTML content..."}</p>
    </html>`;
    const readableStream = Readable.from(htmlContent);
    res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" });
    readableStream.pipe(res);
  })
  .listen(3000);

htmlAsyncGenerator

import { htmlAsyncGenerator as html } from "ghtml";
import { readFile } from "node:fs/promises";
import { Readable } from "node:stream";
import http from "node:http";

http
  .createServer((req, res) => {
    const htmlContent = html`<html>
      <code>${readFile("./README.md")}</code>
    </html>`;
    const readableStream = Readable.from(htmlContent);
    res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" });
    readableStream.pipe(res);
  })
  .listen(3000);

includeFile

import { includeFile } from "ghtml/includeFile.js";

const logo = includeFile("static/logo.svg");

console.log(logo);
// Output: content of "static/logo.svg"
1.5.0

16 days ago

1.2.5

1 month ago

1.2.4

1 month ago

1.2.3

1 month ago

1.2.2

1 month ago

1.2.1

2 months ago

1.2.0

2 months ago

1.1.0

2 months ago

1.0.1

4 months ago

1.0.0

4 months ago