or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli.mdcompilation.mdconfiguration.mdindex.mdrendering.mdtemplate-class.md
tile.json

rendering.mddocs/

Template Rendering

Direct template rendering functionality for processing templates with data and generating output.

Capabilities

Render Function

Renders an EJS template string directly with data, combining compilation and execution in one step.

/**
 * Render the given template with data
 * @param template - EJS template string
 * @param data - Template data object (optional, defaults to {})
 * @param opts - Compilation and rendering options (optional)
 * @returns Rendered string or Promise<String> if async
 */
function render(template, data, opts);

Usage Examples:

const ejs = require("ejs");

// Basic rendering
const html = ejs.render("<h1><%= title %></h1>", { title: "Hello World" });
console.log(html); // <h1>Hello World</h1>

// Rendering with control flow
const listTemplate = `
<ul>
<% users.forEach(function(user) { %>
  <li><%= user.name %> - <%= user.email %></li>
<% }); %>
</ul>`;

const users = [
  { name: "Alice", email: "alice@example.com" },
  { name: "Bob", email: "bob@example.com" }
];

const html = ejs.render(listTemplate, { users });

// Rendering with options
const html = ejs.render(template, data, {
  delimiter: '?',  // Use <? ?> instead of <% %>
  rmWhitespace: true  // Remove extra whitespace
});

// Async rendering
const asyncHtml = await ejs.render(template, data, { async: true });

RenderFile Function

Renders an EJS template from a file, automatically handling file reading and path resolution.

/**
 * Render an EJS file at the given path
 * @param path - Path to the EJS file
 * @param data - Template data object (optional, defaults to {})
 * @param opts - Compilation and rendering options (optional)
 * @param callback - Optional callback function
 * @returns String/Promise or calls callback with (err, str)
 */
function renderFile(path, data, opts, callback);

Usage Examples:

const ejs = require("ejs");

// Callback-based rendering
ejs.renderFile("./views/template.ejs", { title: "Hello" }, (err, str) => {
  if (err) throw err;
  console.log(str);
});

// Promise-based rendering (no callback)
const html = await ejs.renderFile("./views/template.ejs", { title: "Hello" });

// With options
ejs.renderFile("./views/template.ejs", data, {
  cache: true,
  filename: "./views/template.ejs"
}, (err, str) => {
  // Handle result
});

// Express.js integration (renderFile is aliased as __express)
app.set('view engine', 'ejs');
app.get('/', (req, res) => {
  res.render('index', { title: 'My App' });
});

Rendering Options

Options that control both compilation and rendering behavior:

interface RenderingOptions {
  // File and caching options
  filename?: string;
  cache?: boolean;
  
  // Template syntax options
  delimiter?: string;
  openDelimiter?: string;
  closeDelimiter?: string;
  
  // Output control
  rmWhitespace?: boolean;
  escapeFunction?: Function;
  outputFunctionName?: string;
  
  // Execution context
  strict?: boolean;
  _with?: boolean;
  context?: object;
  localsName?: string;
  destructuredLocals?: string[];
  
  // Include system
  views?: string[];
  root?: string | string[];
  includer?: Function;
  legacyInclude?: boolean;
  
  // Debug and async
  debug?: boolean;
  compileDebug?: boolean;
  async?: boolean;
}

Template Data

The data object passed to templates becomes available as variables:

const template = `
<h1><%= title %></h1>
<p>User: <%= user.name %> (<%= user.age %>)</p>
<% if (user.admin) { %>
  <p>Administrator</p>
<% } %>
`;

const data = {
  title: "Dashboard",
  user: {
    name: "Alice",
    age: 30,
    admin: true
  }
};

const html = ejs.render(template, data);

Include System

Templates can include other templates using the include function:

// main.ejs
const mainTemplate = `
<html>
<head><title><%= title %></title></head>
<body>
  <%- include('header', { subtitle: 'Welcome' }) %>
  <main><%= content %></main>
  <%- include('footer') %>
</body>
</html>`;

// Usage with include paths
ejs.renderFile("main.ejs", data, {
  views: ["./views", "./partials"],  // Search paths for includes
  filename: "./templates/main.ejs"   // Required for relative includes
});

Express.js Integration

EJS integrates seamlessly with Express.js as a view engine:

// Express.js alias for renderFile
const __express = renderFile;

Express Setup:

const express = require("express");
const app = express();

// Set EJS as view engine
app.set("view engine", "ejs");
app.set("views", "./views");

// Enable view caching in production
if (app.get("env") === "production") {
  app.set("view cache", true);
}

// Route handler
app.get("/", (req, res) => {
  res.render("index", { 
    title: "My App",
    user: req.user 
  });
});

Error Handling

Rendering errors include source context for debugging:

try {
  const html = ejs.render("<%= undefinedVariable %>", {});
} catch (error) {
  console.log(error.message);
  // ReferenceError: undefinedVariable is not defined
  //     at eval (eval at <anonymous>, <anonymous>:10:13)
  //     at template.ejs:1:3
}

// File rendering errors include filename
ejs.renderFile("missing.ejs", {}, (err, str) => {
  if (err) {
    console.log(err.message); // ENOENT: no such file or directory
  }
});

Async Rendering

Templates can use async/await when the async option is enabled:

const asyncTemplate = `
<h1><%= title %></h1>
<% const data = await fetchData(); %>
<ul>
<% for (const item of data) { %>
  <li><%= item.name %></li>
<% } %>
</ul>`;

// Render with async option
const html = await ejs.render(asyncTemplate, { 
  title: "Async Data",
  fetchData: () => Promise.resolve([{ name: "Item 1" }])
}, { async: true });