Template variables

Opt-in {key} substitution from a data.json file. No build step, no fuss.

Template variables

Div projects can opt into a tiny static-site-generator mode: you write your HTML in a src/ folder, drop a data.json next to it, and {key} placeholders get substituted from the JSON whenever you save. The rendered output is what gets served.

This is intentionally minimal. There are no layouts, no includes, no markdown, no collections — just flat key/value substitution. The point is to remove the most common reason you'd reach for a build step (repeating the same bit of copy across pages) without dragging an entire build step into your life.

#When SSG mode activates

Div flips a project to SSG mode the first time anything is placed under src/. There's no flag, no command, no setting. As soon as src/ has content, the editor (and re-renders) start treating it as the source of truth. Magic? Almost.

A plain project:

mysite/
├── div.json
└── index.html

An SSG project:

mysite/
├── div.json
├── src/
│   ├── data.json
│   └── index.html
└── index.html        # auto-rendered from src/index.html

You don't edit the file at the project root — that one's regenerated. You edit src/index.html and src/data.json.

#Syntax

Single curly braces, alphanumeric keys:

<title>{site_name}</title>
<p>Made in {year} by {author}.</p>

With src/data.json:

{
  "site_name": "My Cool Site",
  "year": "2026",
  "author": "Tony"
}

Renders to:

<title>My Cool Site</title>
<p>Made in 2026 by Tony.</p>

#Rules

  • Keys are flat. {key} works; {site.name} and {user.email} don't (yet).
  • Keys must match [A-Za-z_][A-Za-z0-9_]*.
  • Unknown keys pass through literally — {not_in_data} stays as-is in the output. This is on purpose: typos are visible in your preview, not silently erased.
  • Non-scalar values (arrays, objects) leave the placeholder intact.
  • A missing or malformed data.json is treated as empty data — everything passes through literally, nothing throws.

#Re-rendering

  • Saving an HTML file under src/ re-renders that file.
  • Saving src/data.json re-renders every HTML file under src/.
  • Non-HTML files under src/ (CSS, JS, images) mirror to the root verbatim — no substitution.

So if you change site_name in data.json, every page that references {site_name} updates on the next save. One edit, every page in sync.

#Upgrading an existing project to SSG

If you already have a plain project and want to bring template variables to the party, the team app provides an artisan command:

php artisan div:upgrade-ssg <slug>

This:

  1. Moves your root files into src/.
  2. Seeds src/data.json with { "site_name": "..." }.
  3. Re-renders every HTML file.

The command is idempotent — running it on a project that's already in SSG mode is a no-op.

The CLI doesn't have its own equivalent yet. For now, the upgrade is server-side only. If your project is already deployed, you can run the upgrade from the team app's editor, or by SSHing into the server (if you're self-hosting).

#What's reserved for later

Folders under src/ with these names are reserved — Div doesn't do anything special with them today, but it will:

  • assets/ — for an asset pipeline.
  • views/ — for layouts and includes.
  • content/ — for markdown that gets rendered to pages.
  • collections/ — for repeated structures (e.g. blog posts).

There's also a top-level public/ folder reserved for verbatim-passthrough files.

For now, anything dropped in these folders just mirrors verbatim. If you've used a static-site generator before, the names should feel familiar; if you haven't, ignore them with our blessing.

#Example: a portfolio with a shared header

src/data.json:

{
  "name": "Tony Lea",
  "tagline": "I make websites.",
  "email": "tony@example.com"
}

src/index.html:

<!doctype html>
<title>{name}</title>
<header>
  <h1>{name}</h1>
  <p>{tagline}</p>
</header>
<main>
  <p>Hi! I'm {name}. Email me at <a href="mailto:{email}">{email}</a>.</p>
</main>

src/about.html:

<!doctype html>
<title>About | {name}</title>
<header>
  <h1>{name}</h1>
  <p>{tagline}</p>
</header>
<main>
  <p>This is the about page for {name}'s portfolio.</p>
</main>

Now updating your tagline is a one-line edit in data.json, not a find-and-replace across every HTML file. That's the whole pitch — small change, big payoff.

#See also