Eta Template Engine

website·Indexed 30 days ago

https://eta.js.org/

A lightweight templating engine available for Node.js, Deno, and the Browser. Eta provides a flexible alternative to EJS, Handlebars, and Pug, featuring configurable options and a focus on performance.

Tokens
8.6K
Snippets
57
Records
64
Agent score
65%

What's inside Eta

  1. Overview of Eta template engine

    Eta is a lightweight (~2 KB gzipped), zero-dependency embedded JavaScript template engine that can be used server-side or client-side. It is designed to be significantly faster than most other templating engines and is not limited to HTML; it can generate templates for any language (e.g., Markdown). Key features include support for plugins, partials, custom delimiters, and a non-whitespace-sensitive syntax.
  2. Render partials and layouts in Eta

    Eta allows you to include partials and define parent layouts to structure your templates.

    • Partials: Use <%~ include("path") %> to render a partial. You can pass additional data as a second argument which will be merged with the it object.
    • Async Partials: Use <%~ await includeAsync("path") %> for asynchronous partials.
    • Layouts: Use <% layout("path") %> to set a parent layout. In the layout file, use <%~ it.body %> to render the child content.
    • Name Resolution: By default, Eta resolves paths relative to the views directory. To load a template from internal storage (e.g., a programmatically defined string) instead of the filesystem, prefix the name with an @ symbol (e.g., @header).
    <%~ include("./path-to-partial") %>
    <%~ include("./path-to-partial", { option: true }) %>
    <%~ await includeAsync("./path-to-partial") %>
    
    <% layout("./path-to-layout") %>
    <%~ it.body %>
    
    <%~ include("@header") %>
  3. Implement Layouts and Blocks in Eta

    Eta supports a parent-child layout system with named blocks for overridable content sections.
    <!-- base.eta (Layout) -->
    <!DOCTYPE html>
    <html>
    <head>
      <title><%~ block("title", () => { %>Default Title<% }) %></title>
    </head>
    <body>
      <aside>
        <%~ block("sidebar") %>
      </aside>
      <main>
        <%~ it.body %>
      </main>
    </body>
    </html>
    
    <!-- page.eta (Child Template) -->
    <% layout("./base", { title: "My Page" }) %>
    
    <% block("title", () => { %>
      My Page Title
    <% }) %>
    
    <% block("sidebar", () => { %>
      <nav>Page-specific sidebar</nav>
    <% }) %>
    
    <p>Main content goes in it.body as usual.</p>
  4. Install and initialize Eta

    Eta is an ESM-only template engine. It is exported as a class and must be instantiated before use. In Node.js (v20.11+), use import.meta.dirname to resolve the templates directory path.
    npm install eta
    import { Eta } from "eta"
    import path from "node:path"
    
    const eta = new Eta({
      views: path.join(import.meta.dirname, "templates")
    })
    
  5. Use Eta in the browser

    For browser environments, import the core build from eta/core using ES modules.
    <script type="module">
      import { Eta } from "eta/core"
      const eta = new Eta()
      document.body.innerHTML = eta.renderString("Hello <%= it.name %>", { name: "Ben" })
    </script>
  6. Integrate Eta with Express.js

    To use Eta as the view engine in Express, configure both the Express app and the Eta instance. Note that as of Eta v2.0.0, cache and views must be configured separately for both Express and Eta to prevent vulnerabilities.
    var express = require("express")
    var app = express()
    var eta = require("eta")
    
    app.engine("eta", eta.renderFile)
    eta.configure({ views: "./views", cache: true })
    app.set("views", "./views")
    app.set("view cache", true)
    app.set("view engine", "eta")
    
    app.get("/", function (req, res) {
      res.render("template", {
        favorite: "Eta",
        name: "Ben",
        reasons: ["fast", "lightweight", "simple"]
      })
    })
  7. Interpolate data into Eta templates

    Interpolation outputs data into the template. By default, the data passed to the template is stored in an object named it. Use the = prefix for escaped output and the ~ prefix for raw (unescaped) output.
    <% = it.value %>
    <% = 2 + 4 %>
    <%~ it.value %>
    <%~ "<p>HTML</p>" %>
  8. Manage templates and partials using the Cacher

    Templates and partials are stored in Eta.templates (a Cacher object). You can manually define partials to be reused across templates using the include syntax.
    // Define a partial
    Eta.templates.define("my-partial", Eta.compile("This is a partial speaking"))
    
    // Use the partial in a render call
    Eta.render('... <%~ include("my-partial") %>', {})
    
    // Define a partial that accepts data
    Eta.templates.define("my-partial-2", Eta.compile("Name: <%= it.name %>"))
    Eta.render(
      '... <%~ include("my-partial-2", {name: it.name}) %>',
      { name: "Ben" }
    )
    
    // Cache management
    Eta.templates.get('my-partial') // Retrieve
    Eta.templates.clear()           // Reset cache
  9. Control whitespace in Eta templates

    Eta provides delimiters to trim whitespace around tags. These modifiers can be added to the opening or closing tags:

    • _: Trims all whitespace. _ at the start trims whitespace before the tag; _ at the end trims whitespace after.
    • -: Trims exactly one newline. - at the start trims one newline before; - at the end trims one newline after.
    Hi
    <%- = it.myname %>
    <% /* The newline after "Hi" will be stripped */ %>
  10. Install Eta for Node.js, Deno, and Browser

    Eta is available for multiple environments. It is packaged as a UMD module, supporting CommonJS, ES Modules, and AMD.
    # Node.js
    npm install eta --save
    # or
    yarn add eta
    // Node.js Import
    import * as Eta from "eta"
    // or
    var Eta = require("eta")
    
    // Deno Import
    import * as eta from "https://deno.land/x/eta@v1.6.0/mod.ts"
    <!-- Browser via Unpkg -->
    <script src="https://unpkg.com/eta"></script>
    
    <!-- Browser via JSDelivr -->
    <script src="https://cdn.jsdelivr.net/npm/eta"></script>
  11. Render template files in Node.js

    To render files from the filesystem, use eta.configure() to set the views directory and then call eta.renderFile(). Eta assumes the .eta extension if it is not explicitly provided in the filename.
    var eta = require("eta")
    var path = require("path")
    
    eta.configure({
      views: path.join(__dirname, "views")
    })
    
    await eta.renderFile("./template", { food: "cake" })
  12. Implement Async Blocks in Eta

    For blocks that require asynchronous operations, use blockAsync() in the child template and await blockAsync() in the layout.
    // In child template
    <% layout("./base") %>
    <% blockAsync("data", async () => { %>
      <%= await fetchSomeData() %>
    <% }) %>
    
    // In layout
    <%~ await blockAsync("data") %>