Markdown and trusted HTML in Forge templates

forge_markdown and forge_html are two template functions that cover different rendering needs. The same content pipeline feeds your browser output, your API responses, and your AI-readable formats.

Forge includes two template functions for rendering content: forge_markdown and forge_html. They solve different problems and have different security models. Knowing when to use each one matters.

forge_markdown

Used on fields where authors write in markdown -- with the option to drop raw HTML blocks into the same field.

{{ forge_markdown .Body }}

The renderer processes markdown syntax normally. Lines that start with < are emitted verbatim -- they bypass the markdown renderer and go straight to output. This means an author can write an article in markdown and embed custom HTML blocks in the same field:

Forge handles content lifecycle at the framework level.

<div class="terminal-block">
  <span class="prompt">$</span> forge-cli publish my-post
</div>

The publish command transitions the content from Draft to Published.

The markdown sections render as prose. The HTML block is passed through as-is. No special delimiter, no separate field.

forge_html

Used when a field already contains rendered HTML and you want to output it directly in a template without Go's template engine escaping it.

{{ forge_html .RenderedContent }}

Go templates HTML-escape output by default. forge_html marks the string as trusted and bypasses escaping. Use this when a field stores pre-rendered content -- from an external system, a migration, or a field that is maintained as HTML directly.

The difference

forge_markdownforge_html
Input formatMarkdown with optional HTML blocksAlready-rendered HTML
HTML passthroughLines starting with < emitted verbatimEntire field emitted verbatim
Use caseAuthor-written contentPre-rendered or imported content

A practical example: a tech article with inline terminal blocks uses forge_markdown. A field populated by an import script that produces HTML uses forge_html.

Security model

Neither function sanitizes its input. Both emit content verbatim.

This is intentional. Forge is self-hosted. Content authors are trusted operators -- not anonymous public contributors on a multi-tenant platform. The security model matches the deployment model.

If you are building something where untrusted users submit content, sanitize before storage -- not at render time.

The rendering pipeline

The same content that renders in the browser via these template functions also feeds the AI-readable formats. .aidoc responses and /llms-full.txt draw from the same content fields. Consistent rendering at the source means consistent content across all four delivery channels -- browser, API, and both AI layers.