CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-liquidjs

A simple, expressive and safe Shopify / Github Pages compatible template engine in pure JavaScript.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

core-engine.mddocs/

Core Template Engine

The Liquid class is the main entry point for LiquidJS, providing comprehensive template parsing and rendering capabilities with support for both synchronous and asynchronous operations.

Capabilities

Liquid Class

Main engine class for parsing and rendering Liquid templates with extensive configuration options.

/**
 * Main LiquidJS template engine
 */
class Liquid {
  readonly options: NormalizedFullOptions;
  readonly renderer: Render;
  readonly parser: Parser; // @deprecated
  readonly filters: Record<string, FilterImplOptions>;
  readonly tags: Record<string, TagClass>;
  
  constructor(opts?: LiquidOptions);
}

Template Parsing

Parse template strings or files into Template arrays for rendering.

/**
 * Parse template string into Template array
 * @param html - Template string to parse
 * @param filepath - Optional filepath for error reporting
 * @returns Array of parsed templates
 */
parse(html: string, filepath?: string): Template[];

/**
 * Parse template file asynchronously
 * @param file - Path to template file
 * @param lookupType - Type of lookup (Root, Partials, Layouts)
 * @returns Promise resolving to Template array
 */
parseFile(file: string, lookupType?: LookupType): Promise<Template[]>;

/**
 * Parse template file synchronously
 * @param file - Path to template file  
 * @param lookupType - Type of lookup (Root, Partials, Layouts)
 * @returns Template array
 */
parseFileSync(file: string, lookupType?: LookupType): Template[];

Usage Examples:

import { Liquid } from "liquidjs";

const engine = new Liquid();

// Parse template string
const templates = engine.parse("Hello {{ name }}!");

// Parse template file
const fileTemplates = await engine.parseFile("template.liquid");

// Parse with specific lookup type
const partialTemplates = await engine.parseFile("header.liquid", "partials");

Template Rendering

Render parsed templates with data context, supporting multiple output formats.

/**
 * Render templates asynchronously
 * @param tpl - Array of parsed templates
 * @param scope - Data context for rendering
 * @param renderOptions - Rendering options
 * @returns Promise resolving to rendered output
 */
render(tpl: Template[], scope?: object, renderOptions?: RenderOptions): Promise<any>;

/**
 * Render templates synchronously
 * @param tpl - Array of parsed templates
 * @param scope - Data context for rendering
 * @param renderOptions - Rendering options
 * @returns Rendered output
 */
renderSync(tpl: Template[], scope?: object, renderOptions?: RenderOptions): any;

/**
 * Render templates to Node.js readable stream
 * @param tpl - Array of parsed templates
 * @param scope - Data context for rendering
 * @param renderOptions - Rendering options
 * @returns Node.js ReadableStream
 */
renderToNodeStream(tpl: Template[], scope?: object, renderOptions?: RenderOptions): NodeJS.ReadableStream;

Usage Examples:

const templates = engine.parse("Hello {{ name | capitalize }}!");
const data = { name: "world" };

// Async rendering
const result = await engine.render(templates, data);
console.log(result); // "Hello World!"

// Sync rendering
const resultSync = engine.renderSync(templates, data);

// Stream rendering (Node.js only)
const stream = engine.renderToNodeStream(templates, data);
stream.pipe(process.stdout);

Combined Parse and Render

Convenience methods that combine parsing and rendering in a single operation.

/**
 * Parse and render template string asynchronously
 * @param html - Template string to parse and render
 * @param scope - Data context for rendering
 * @param renderOptions - Rendering options
 * @returns Promise resolving to rendered output
 */
parseAndRender(html: string, scope?: Context | object, renderOptions?: RenderOptions): Promise<any>;

/**
 * Parse and render template string synchronously
 * @param html - Template string to parse and render
 * @param scope - Data context for rendering
 * @param renderOptions - Rendering options
 * @returns Rendered output
 */
parseAndRenderSync(html: string, scope?: Context | object, renderOptions?: RenderOptions): any;

Usage Examples:

// One-step async parsing and rendering
const result = await engine.parseAndRender(
  "Hello {{ name }}!",
  { name: "Alice" }
);

// One-step sync parsing and rendering
const resultSync = engine.parseAndRenderSync(
  "{% for item in items %}{{ item }}{% endfor %}",
  { items: [1, 2, 3] }
);

File Operations

Render templates directly from files with automatic parsing.

/**
 * Render template file asynchronously
 * @param file - Path to template file
 * @param ctx - Data context for rendering
 * @param renderFileOptions - File rendering options
 * @returns Promise resolving to rendered output
 */
renderFile(file: string, ctx?: Context | object, renderFileOptions?: RenderFileOptions): Promise<any>;

/**
 * Render template file synchronously
 * @param file - Path to template file
 * @param ctx - Data context for rendering
 * @param renderFileOptions - File rendering options
 * @returns Rendered output
 */
renderFileSync(file: string, ctx?: Context | object, renderFileOptions?: RenderFileOptions): any;

/**
 * Render template file to Node.js readable stream
 * @param file - Path to template file
 * @param scope - Data context for rendering
 * @param renderOptions - Rendering options
 * @returns Promise resolving to Node.js ReadableStream
 */
renderFileToNodeStream(file: string, scope?: object, renderOptions?: RenderOptions): Promise<NodeJS.ReadableStream>;

Usage Examples:

// Render file with data
const html = await engine.renderFile("template.liquid", {
  title: "My Page",
  users: [{ name: "Alice" }, { name: "Bob" }]
});

// Render with lookup type
const partial = await engine.renderFile("header.liquid", data, {
  lookupType: "partials"
});

// Stream rendering from file (Node.js only)
const fileStream = await engine.renderFileToNodeStream("large-template.liquid", data);
fileStream.pipe(process.stdout);

Value Evaluation

Evaluate Liquid expressions and variables outside of full template context.

/**
 * Evaluate Liquid expression asynchronously
 * @param str - Expression string to evaluate
 * @param scope - Data context for evaluation
 * @returns Promise resolving to evaluated value
 */
evalValue(str: string, scope?: object | Context): Promise<any>;

/**
 * Evaluate Liquid expression synchronously
 * @param str - Expression string to evaluate
 * @param scope - Data context for evaluation
 * @returns Evaluated value
 */
evalValueSync(str: string, scope?: object | Context): any;

Usage Examples:

const data = { user: { name: "Alice", age: 25 } };

// Evaluate simple expressions
const name = await engine.evalValue("user.name", data);
// Result: "Alice"

const greeting = await engine.evalValue("user.name | prepend: 'Hello, '", data);
// Result: "Hello, Alice"

// Sync evaluation
const age = engine.evalValueSync("user.age", data);
// Result: 25

Express.js Integration

Built-in support for Express.js template engine integration.

/**
 * Create Express.js template engine function
 * @returns Express-compatible template engine function
 */
express(): (filePath: string, ctx: object, callback: (err: Error | null, rendered: string) => void) => void;

Usage Examples:

import express from "express";
import { Liquid } from "liquidjs";

const app = express();
const engine = new Liquid();

// Register as Express template engine
app.engine("liquid", engine.express());
app.set("view engine", "liquid");

// Use in routes
app.get("/", (req, res) => {
  res.render("index", { title: "Home", user: req.user });
});

Types

Core Engine Types

interface Template {
  token: Token;
  render(ctx: Context, emitter: Emitter): any;
  children?(partials: boolean, sync: boolean): Generator<unknown, Template[]>;
  arguments?(): Arguments;
  blockScope?(): Iterable<string>;
  localScope?(): Iterable<IdentifierToken | QuotedToken>;
  partialScope?(): PartialScope | undefined;
}

interface RenderOptions {
  sync?: boolean;
  globals?: object;
  strictVariables?: boolean;
  ownPropertyOnly?: boolean;
  templateLimit?: number;
  renderLimit?: number;
  memoryLimit?: number;
}

interface RenderFileOptions extends RenderOptions {
  lookupType?: LookupType;
}

enum LookupType {
  Root = 'fs',
  Partials = 'partials',
  Layouts = 'layouts'
}

Engine Properties

interface NormalizedFullOptions {
  // File system configuration
  root: string[];
  partials: string[];
  layouts: string[];
  fs: FS;
  
  // Template processing
  strictFilters: boolean;
  strictVariables: boolean;
  dynamicPartials: boolean;
  
  // Performance limits
  parseLimit: number;
  renderLimit: number;
  memoryLimit: number;
  
  // Additional options...
}

docs

analysis.md

built-in-tags.md

configuration.md

context-and-scoping.md

core-engine.md

extensions.md

filesystem.md

filters.md

index.md

tile.json