@accordproject/template-engine

中文文档
5.3.0发布于 2026/10/20Apache-2.0TypeScriptCommonJS构建来源已验证近 30 天下载 3618

Generation of AgreementMark from TemplateMark + JSON Data

原始使用文档
文档目录19 节
  1. Resources
  2. Execution Pipeline Overview
  3. Hello World Template
  4. Template Data Model
  5. TemplateMark (extended markdown)
  6. Generate AgreementMark from Data (JSON)
  7. Output AgreementMark (JSON)
  8. Next Steps
  9. Why create a new template engine?
  10. 1. Input and Output Format Agnostic
  11. 2. TemplateMark as a Defined Format
  12. 3. Full Logic Support
  13. 4. Type-safety
  14. 5. Data Model
  15. 6. Compilation
  16. Install
  17. Browser usage
  18. LLM providers
  19. License

Template Engine

This is the Accord Project template engine. Rich-text templates are defined in TemplateMark (either as markdown files, or JSON documents) and are then merged with JSON data to produce output documents. Templates may contain TypeScript expressions.

Resources

The core template engine is a JSON to JSON transformation that converts TemplateMark JSON + agreement data (JSON) to AgreementMark JSON.

Note: Use the @accordproject/markdown-transform project to convert markdown templates to TemplateMark JSON and to convert AgreementMark JSON to output formats (HTML, PDF, DOCX etc.). For command-line usage please use @accordproject/template-cli.

TemplateMark is a document object model that describes a rich-text template, with embedded variables, conditional sections, formulae etc. TemplateMark uses embedded TypeScript expressions for conditionals and calculations.

The format of both TemplateMark and AgreementMark is specified using the Concerto data modeling language.

At a high-level the template engine converts a TemplateMark DOM to an AgreementMark DOM, evaluating TypeScript expressions for conditional sections and formulae, and replaces variable references with variable values from the supplied agreement data.

Template Interpreter

Execution Pipeline Overview

Internally, the Template Engine evaluates templates through a structured execution pipeline:

  1. Type Validation
    The TemplateMark JSON document and the incoming agreement data are validated against their respective Concerto models to ensure structural and type correctness.

  2. TypeScript Compilation
    Embedded TypeScript expressions (such as conditionals, clauses, and formulae) are compiled into JavaScript using the TemplateMarkToJavaScriptCompiler.

  3. User Code Evaluation
    During agreement generation, compiled JavaScript expressions are evaluated using the JavaScriptEvaluator.
    The evaluator supports two execution strategies:

    • evalDangerously() — Executes JavaScript directly within the current process. This should only be used with trusted code or in a sandboxed environment (e.g., browser).
    • evalChildProcess() — Executes JavaScript in an isolated Node.js child process for improved safety and isolation and is recommended for untrusted template content on the server.
  4. AgreementMark Generation
    The TemplateMark document is traversed, evaluated values are inserted into the document structure, and an AgreementMark JSON document is produced.

  5. Output Validation
    The generated AgreementMark document is validated before being returned.

This layered architecture ensures type-safety, deterministic execution of template logic, and isolation during runtime evaluation.

Hello World Template

Let's create the simplest template imaginable, the infamous "hello world"!

The code for this test is available at: https://github.com/accordproject/template-engine/blob/main/test/HelloWorld.test.ts

Template Data Model

First create a template data model in Concerto syntax. The data model defines the structure of the data to be merged with the template. In this case the template model contains a single property message of type String. The property is required (it is not optional).

namespace [email protected]

@template
concept TemplateData {
    o String message
}

TemplateMark (extended markdown)

Next define the TemplateMark for the template. In this case it is the plain-text world "Hello" followed by a space, then the variable message followed by ".".

Hello {{message}}.

Note that in this case the template is defined using an extended markdown syntax (rich-text with embedded variables etc.). The @accordproject/markdown-transform packages are used to convert the markdown to TemplateMark JSON, for use by the template engine.

Generate AgreementMark from Data (JSON)

Define an instance of the [email protected] data model. In this case setting the value of the message property to the string "World".

const data = {
    $class: '[email protected]',
    message: 'World',
};

Output AgreementMark (JSON)

When the TemplateMark and the data JSON is passed to the Template Engine it merges the two, in this case by simply replacing the reference to the message variable with its value from the data JSON and to produce an AgreementMark JSON document.

This AgreementMark JSON document can then be passed to the @accordproject/markdown-transform modules for conversion to markdown, PDF, HTML.

{
    "$class": "[email protected]",
    "xmlns": "http://commonmark.org/xml/1.0",
    "nodes": [
        {
        "$class": "[email protected]",
        "nodes": [
            {
            "$class": "[email protected]",
            "nodes": [
                {
                "$class": "[email protected]",
                "text": "Hello "
                },
                {
                "$class": "[email protected]",
                "value": "World",
                "name": "message",
                "elementType": "String"
                },
                {
                "$class": "[email protected]",
                "text": "."
                }
            ]
            }
        ]
        }
    ]
}

Next Steps

The Hello World example just scratches the surface of what can be accomplished! TemplateMark can define optional sections, conditional sections, TypeScript formulae/calculations and even reference external data.

Refer to the full example for details.

More detailed syntax documentation is to come! Read the existing documentation at: https://docs.accordproject.org/docs/markup-templatemark.html

Why create a new template engine?

There are many great Open Source template engines available, such as Mustache, Handlebars or EJS, so why create yet another?

1. Input and Output Format Agnostic

Most template engines are fundamentally text based — i.e. they treat templates as text strings and are glorified "find and replace" machines. This approach creates a coupling between the input format of the template, say, a DOCX file, and the output of the template engine, which in the case of a DOCX template, has to be a DOCX file. This makes supporting multiple input and output formats difficult.

The Accord Project template engine breaks the coupling between the template input format and the engine output format, and moves data format conversion outside of the core template engine. Templates at the engine level are TemplateMark JSON documents and the output from the template engine is an AgreementMark JSON document. Separate libraries are used to convert source templates into TemplateMark JSON, or to render AgreementMark JSON to an output format.

This flexibility allows a markdown template to be created that is used to create HTML, PDF or DOCX. One can even imagine using DOCX templates to create HTML or PDF files, or other scenarios.

2. TemplateMark as a Defined Format

TemplateMark JSON is a well-defined file format, meaning that powerful template editors can be created to define it: including widgets and user-experience for defining conditional sections, and formulae, and offering template preview and integrated testing. Template editing is closer to programming in our opinion than word-processing.

We encourage community and commercial innovation in this area!

3. Full Logic Support

Unlike some templating systems which prohibit, or minimize, logic in templates, Accord Project templates fully embrace templates that may contain sophisticated logic: conditional logic to determine what text to include, or even calculations, for example to calculate the monthly payments for a mortgage based on the term of the mortgage, the amount and the interest rate.

4. Type-safety

Given the ability for templates to contain logic there's an imperative to ensure that the templates are safe - i.e. when a template is merged with well-structured data it is guaranteed to produce well-structured output.

Too many templating engines fail in unpredictable ways at runtime, or silently generate invalid output, when presented with data — unacceptable for enterprise usage.

Accord Project templates are therefore strongly-typed. The logic in templates is expressed in TypeScript. TypeScript is a strongly-typed, general purpose programming language, supported by a vibrant Open Source and enterprise community. TypeScript compiles to JavaScript for easy execution on most platforms.

5. Data Model

The rich-text with variables of a template is associated with a Concerto data model. The Concerto data model defines the structure of the data required for the template, and is used to statically compile the template and verify type-safety, and is also used at runtime to ensure that incoming data is well structured.

6. Compilation

Templates may be statically compiled to TypeScript programs, enforcing type-safety, ensuring that no unsafe code evaluation ("eval") is required at runtime, and easing integration into applications.

The template compiler is a separate project, hosted here: https://github.com/accordproject/template-compiler

Install

Note that this module is primarily intended for tool authors, or developers embedding template engines within applications. For command-line usage please refer to the @accordproject/template-cli package which implements a full pipeline to convert markdown templates plus JSON data to supported output formats, such as HTML, DOCX or PDF.

npm install @accordproject/template-engine --save

Requires Node.js >= 22.

Browser usage

The package is published with two entry points:

  • lib/index.js — the Node.js build (tsc output, typed via lib/index.d.ts).
  • umd/template-engine.js — a pre-built UMD browser bundle (referenced by the browser field, so bundlers pick it up automatically for web builds).

The full author-and-run loop works in the browser — parse a template to TemplateMark, type-check it, compile its embedded TypeScript logic to JavaScript, and evaluate it — which is what powers the Template Playground. For convenience the bundle also re-exports ModelManager (concerto) and TemplateMarkTransformer (markdown-template), so a single bundle can run the whole model -> template -> agreement flow with one concerto instance:

<script src="https://unpkg.com/@accordproject/template-engine/umd/template-engine.js"></script>
<script>
  const { ModelManager, TemplateMarkTransformer, TemplateMarkInterpreter } = window['template-engine'];
  const modelManager = new ModelManager();
  modelManager.addCTOModel('namespace [email protected]\n@template\nconcept TemplateData { o String name }');
  const templateMark = new TemplateMarkTransformer()
    .fromMarkdownTemplate({ content: 'Hello {{name}}!' }, modelManager, 'contract');
  const engine = new TemplateMarkInterpreter(modelManager, {});
  const agreement = await engine.generate(templateMark, { $class: '[email protected]', name: 'World' });
</script>

Notes on browser limitations:

  • Logic that imports arbitrary 3rd-party packages must be shipped as a compiled archive (JavaScript logic, dependencies already bundled — produced offline in Node.js). In the browser, source archives (TypeScript logic) compile against a fixed set of supported runtime dependencies.
  • Template.fromDirectory()/fromUrl() and child-process logic evaluation are Node-only; in the browser load templates via Template.fromArchive(buffer) and use the default in-process evaluator.

The browser bundle is exercised by the Playwright tests in the e2e/ workspace, which load umd/template-engine.js into a headless Chromium and run a real generate().

LLM providers

The optional LLM executor talks to providers through their official SDKs. These are optional peer dependencies — they are not installed with the template engine, so install the SDK for each provider you use:

ProviderPackage
anthropic@anthropic-ai/sdk
openai, ollama, openai-compatibleopenai
groqgroq-sdk
google@google/genai
mistral@mistralai/mistralai
openrouter@openrouter/sdk
npm install @anthropic-ai/sdk

In Node.js the SDK is loaded by package name on first use. Bundlers (Vite, webpack, ...) cannot resolve that runtime lookup, so browser apps should pass sdkLoaders — one literal import() per provider they support — so their bundler includes the SDK:

const processor = new TemplateArchiveProcessor(template, llmConfig, {
  anthropic: () => import('@anthropic-ai/sdk'),
  openai: () => import('openai'), // also used by `ollama` and `openai-compatible`
});

The same loaders are accepted by new LLMExecutor(template, config, sdkLoaders) and createReasoner(providerConfig, sdkLoaders).

The openai SDK (also used by ollama and openai-compatible) and the @anthropic-ai/sdk SDK refuse to run in a browser unless the provider config opts in with clientOptions: { dangerouslyAllowBrowser: true }. Only do this if you accept that the API key is visible to anyone using the page, for example when users supply their own key; otherwise call the provider from a server.

License

Accord Project source code files are made available under the Apache License, Version 2.0 (Apache-2.0), located in the LICENSE file. Accord Project documentation files are made available under the Creative Commons Attribution 4.0 International License (CC-BY-4.0), available at http://creativecommons.org/licenses/by/4.0/.

版本与发布记录

@accordproject/template-engine 共发布 56 个版本,首次发布于 2023/03/20;过去 12 个月发布了 13 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
5.3.0latest2026/10/2019 天前
5.2.02026/10/071 个月前
5.1.02026/09/151 个月前
5.0.02026/09/151 个月前
4.2.12026/09/022 个月前
4.0.02026/06/045 个月前

关于 @accordproject/template-engine 的常见问题

@accordproject/template-engine 是什么?

Generation of AgreementMark from TemplateMark + JSON Data

如何安装 @accordproject/template-engine?

在项目目录运行 npm install @accordproject/template-engine,或使用 pnpm add / yarn add / bun add。

@accordproject/template-engine 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@accordproject/template-engine 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@accordproject/template-engine 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@accordproject/template-engine 可以商用吗?

@accordproject/template-engine 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@accordproject/template-engine 的下载量有多少?

根据 npm 官方下载统计,@accordproject/template-engine 在 2026/10/05 – 2026/11/03 这 30 天内被下载 3,618 次,日均约 121 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@accordproject/template-engine 还在维护吗?

最新版本 5.3.0 发布于 2026/10/20(19 天前);至今共发布 56 个版本,其中过去 12 个月发布了 13 个;首次发布于 2023/03/20。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。