---
title: Why Jinja is the right target
description: AsciiDoc preprocessing and Jinja templating express the same three ideas — variables, conditionals, includes. That correspondence is what makes the conversion faithful.
created: "2026-08-18"
author: Gabriel McGoldrick
tags:
  - topic/asciidoc
  - topic/jinja
---

# Why Jinja is the right target {#why-jinja-is-the-right-target}

The key idea behind the DogsBay AsciiDoc to Markdown conversion is keeping the structure of your documentation identical, using Jinja templates to express the features that other converters throw away.

:::note{title="AsciiDoc to Markdown — part 3 of 7"}
1. [Migrating AsciiDoc to Markdown](/blog/migrating-asciidoc-to-markdown/)
2. [Why existing AsciiDoc converters lose your structure](/blog/why-existing-converters-lose-structure/)
3. **Why Jinja is the right target** — you are here
4. [Mapping AsciiDoc variables to Jinja](/blog/asciidoc-variables-in-jinja/)
5. [Mapping AsciiDoc conditionals to Jinja](/blog/asciidoc-conditionals-in-jinja/)
6. [Mapping AsciiDoc ifeval to Jinja](/blog/asciidoc-ifeval-in-jinja/)
7. [Mapping AsciiDoc includes and level offsets to Jinja](/blog/asciidoc-includes-in-jinja/)
:::

## What Jinja is {#what-jinja-is}

Jinja is a fast, expressive and highly extensible templating engine, originally for Python and based on the Django template syntax. It generates text-based files — HTML, XML, Markdown, configuration — by mixing static boilerplate with dynamic variables and logic.

## Why not something bespoke {#why-not-something-bespoke}

Jinja's syntax is popular enough to have been ported well beyond Python — Twig in PHP, Nunjucks in JavaScript — and it is used far outside web development:

- **Infrastructure as code:** Ansible uses Jinja to inject environment variables into server configuration playbooks.
- **Data engineering:** dbt embeds Jinja directly inside SQL to loop over date ranges, switch environments and abstract schema transformations.

Choosing an established templating language means the intermediate form is something your team can already read, and something other tools can already process.

## The syntax that matters {#the-syntax-that-matters}

Three constructs carry the whole conversion:

- **Expressions `{{ ... }}`** output the result of a variable or expression.

  ```html
  <h1>Hello, {{ user.name }}!</h1>
  ```
- **Statements `{% ... %}`** control logic and flow — conditionals, loops, inheritance.

  ```html
  {% if user.is_logged_in %}
    <p>Welcome back!</p>
  {% else %}
    <p>Please log in.</p>
  {% endif %}
  ```
- **Includes `{% include ... %}`** pull a snippet into that exact spot.

  ```html
  {% include 'fragments/header.html' %}
  ```

Those three map onto AsciiDoc's variables, conditionals and `include::` directives almost one for one. The next four posts work through each mapping against real OpenShift source.

Next: [mapping AsciiDoc variables to Jinja](/blog/asciidoc-variables-in-jinja/).
