Skip to content

Developers

Knap Template Renderer

Knap Template Renderer

Beta

Write a Knap template, paste JSON data, and get Markdown. Knap is the Liquid-style template language behind Obsidian Web Clipper and Importer, with 70 Markdown-aware filters for headings, tables, wikilinks and YAML frontmatter. The engine runs in your browser with no eval, and the same renderer is available over the FindUtils API and MCP server.

  • Free, no sign-up
  • Updated
  • Reviewed by Olgun Ozoktas

Renders as you type. The template and the data stay in this tab; nothing is uploaded.

Knap template
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Data (JSON)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Markdown

The rendered Markdown will appear here..

Why Render Knap Templates Here?

Knap is the template language that Obsidian Web Clipper and Obsidian Importer use to turn a web page or an imported record into a Markdown note: variables in double braces, filters after a pipe, if and for blocks, and a set of filters that know Markdown, so a list of names becomes a table, a tag becomes a wikilink, and a field becomes a YAML frontmatter line. Writing a template inside the Clipper's settings is slow, because every change means clipping a page again. This page is the loop you actually want: template on the left, data in the middle, Markdown on the right, rendered as you type, with each error reported at its line and column. The engine is the MIT knap package, an AST interpreter with no eval, and it runs entirely in your browser.

Knap is a small template language published by the Obsidian team under the MIT licence at knap.md. Its syntax is the familiar one: {{ variable }} for output, a pipe for filters with colon-separated quoted arguments, {% if %} with elseif and else, {% for item in list %} with loop variables, {% set %} for a local value, and {# #} for a comment that never reaches the output. What sets it apart is the filter set, which is written for Markdown: bold, italic, code and code_block, h1 to h6, blockquote, callout, list, table, link, image, wikilink, footnote, yaml and yaml_property, next to the usual text, date, number and collection filters. This page lists every filter in the running engine under the editors, read from the engine's own registry.

The renderer on this page is the knap package itself, loaded in your browser on first use. It is an AST interpreter: templates are parsed into a tree and evaluated, never turned into JavaScript, and the engine runs here with native regular expressions disabled. The link and image filters escape their labels and drop javascript:, vbscript: and data: destinations. A template is capped at 200,000 characters and the output at 1,000,000. Errors come back with a code, a line and a column, and non-fatal problems come back as warnings under the output.

The Preview tab renders the Markdown through the site's own Markdown to HTML converter inside a sandboxed frame that may load nothing from the network, so a template can never run a script or fetch a resource on this page. The Source tab is the exact text that Copy and Download produce. The same renderer is exposed on the FindUtils API and MCP server as knap_render, so a script or an agent can produce Markdown from a JSON object with one call.

How it compares

The knap.md site has a playground of its own, and it is the reference for the language. This page adds three things: a data panel that takes a full JSON object rather than a fixed example, a download of the result as a .md file named after the title, and the same renderer as an API and MCP tool for scripts and agents. Everything else about the language, including every filter's behaviour, is Knap's own; nothing is re-implemented here.

Knap Tips

  • Filter arguments use a colon and quotes: {{ date | date:"YYYY-MM-DD" }} and {{ tags | join:", " }}. Chain filters with more pipes: {{ title | trim | upper }}.
  • The value on the left of a pipe is the subject. {{ url | link:"Read more" }} makes a link whose destination is url and whose label is the argument.
  • Inside {% for item in items %}, loop.index starts at 1, loop.index0 at 0, and loop.first and loop.last are booleans. {% if not loop.last %}, {% endif %} puts a separator between items.
  • yaml_property writes a YAML line from a value or a list, and wikilink wraps each item in double brackets, so {{ tags | wikilink | yaml_property:"tags" }} builds a tags: list for frontmatter.
  • The table filter reads an array of objects and uses the keys as columns. Sort first with sort:"Key" when the order matters.

Frequently Asked Questions

What is Knap?

Knap is a template language for producing Markdown, published by the Obsidian team under the MIT licence at knap.md. It is the engine behind the templates in Obsidian Web Clipper and Obsidian Importer. A template mixes literal Markdown with {{ variables }}, filters after a pipe, {% if %} and {% for %} blocks, and comments in {# #}. Its filters know Markdown: they can write headings, tables, wikilinks, callouts and YAML frontmatter lines from plain data.

How do I write a variable, a filter and a loop?

A variable is {{ title }}; a nested value is {{ book.author }}. A filter follows a pipe, with colon-separated quoted arguments: {{ published | date:"YYYY-MM-DD" }} or {{ tags | join:", " }}, and filters chain left to right. A loop is {% for item in items %} ... {% endfor %}, with loop.index, loop.index0, loop.first and loop.last available inside. A condition is {% if author %} ... {% elseif site %} ... {% else %} ... {% endif %}, with ==, !=, and, or, not, contains and parentheses.

Which filters are available?

The standard set of the knap package, which the page lists under the editors from the running engine so the list is always exact. It covers Markdown formatting (bold, italic, code, code_block, h1 to h6, blockquote, callout, list, table, link, image, wikilink, footnote, yaml, yaml_property), text (trim, upper, lower, capitalize, title, kebab, snake, camel, replace, truncate, indent), dates (date, date_modify, duration), numbers (calc, number_format, round), collections (join, split, sort, unique, where, map, first, last, slice, compact, sum) and HTML cleanup (strip_tags, remove_tags, html_to_json). The DOM-dependent filters from knap/html are not loaded.

What does the data panel expect?

One JSON object. Each top-level key becomes a variable, so {"title": "Deep Work", "tags": ["books"]} makes {{ title }} and {{ tags }} available, and nested objects and arrays are reached with dots and loops. A JSON syntax error is shown under the data panel with the parser's message. An empty panel renders the template with no variables, which is a quick way to see which placeholders it uses.

Is the template run as code?

No. Knap is an AST interpreter: the template is parsed into a tree and evaluated node by node. No JavaScript is generated or evaluated, and this page creates the engine with native regular expressions disabled. The link and image filters escape their labels and drop javascript:, vbscript: and data: destinations. The Preview tab renders inside a sandboxed frame that may not load scripts, images from the network, or fonts.

How do I write YAML frontmatter?

Put the three dashes in the template and use yaml_property for the lines. {{ tags | wikilink | yaml_property:"tags" }} writes tags: followed by one quoted [[wikilink]] per item, which is what Obsidian expects in a note's properties. A plain string works too: {{ year | yaml_property:"year" }}. The sample template on this page starts that way.

Can I use this to test an Obsidian Web Clipper template?

Yes, for the template logic. Paste the template and a JSON object with the variables the Clipper would provide, such as title, author, published, description, content and tags, and iterate here instead of clipping a page after each change. The Clipper's own variable extraction, such as selectors and schema lookups, happens in the extension and is not simulated on this page.

Is my template or data uploaded?

No. The knap package is fetched once as a script, and after that the template, the data and the rendered Markdown stay in your browser; no request carries them. You can confirm that in the browser's network panel while editing.

Can I render Knap templates from a script or an AI agent?

Yes. The same code runs on the FindUtils API and MCP server as the knap_render tool. Send the template text and a JSON object of variables, optionally trim_output, and read the Markdown from the markdown field along with any warnings. A syntax error comes back with its line and column. Templates are capped at 200,000 characters and output at 1,000,000.

How is this different from a Liquid or Handlebars template?

The shape is the same as Liquid: double braces, pipes, if and for tags. The differences are the filter set, which is written for Markdown rather than HTML, the colon-and-quotes argument syntax (date:"YYYY-MM-DD" rather than date: "%Y-%m-%d"), elseif rather than elsif, loop.* rather than forloop.*, and the ?? fallback operator. The JSON to Liquid tool on this site can convert a Knap template into Shopify Liquid and lists the constructs that do not map.

Rate This Tool

0/1000

Get Weekly Tools

Suggest a Tool