Skip to content

Git-First Templates Since 3.5.0

By default, Site Builder templates live in tcms-data/builder/ and you edit them in the dashboard. That’s perfect for content-led sites, but developers usually want their templates in git — edited in an IDE, reviewed in pull requests, and deployed like any other code.

Total CMS supports this with zero configuration. If a builder/ folder exists at your project root, templates are git-managed; if it doesn’t, nothing changes. This mirrors how Total CMS already detects tcms-data — by directory presence, not a setting.

Move your builder templates to the project root (alongside public/, config/, frontend/):

Terminal window
mv tcms-data/builder ./builder

That’s the entire switch. The folder’s presence is what activates git-managed mode. (A fresh project can instead run tcms builder:init <starter>, which scaffolds straight into ./builder when it exists, or your composer create-project setup can create it for you.)

Now commit ./builder — there’s nothing special to ignore. tcms-data/ stays gitignored as always (your content and media are not in git), and edit-history snapshots live under tcms-data/, never in ./builder — so the whole ./builder folder is clean to commit.

What changes when templates are git-managed

Section titled “What changes when templates are git-managed”
Admin-first (default)Git-managed (./builder exists)
Templates live intcms-data/builder/./builder/ (committed)
EditingIn the dashboardIn your IDE → commit → deploy
Dashboard editorEditableRead-only (“Editing Disabled”) in every environment
Template syncVia the Sync ManagerDisabled — templates travel by git

Templates resolve in this order (first match wins):

  1. ./builder/ — your committed templates
  2. tcms-data/builder/ — anything edited in the dashboard (legacy / leftover)
  3. Total CMS’s built-in defaults (e.g. layouts/default.twig) — the floor, so a bare builder still renders

So your committed templates always win, and you can extend the shipped layouts/default.twig without copying it.

Once ./builder exists, the template and builder editors show an “Editing Disabled” notice and hide Save/Delete — in every environment, including local dev. This is deliberate: the repo is the single source of truth, so there’s never a second, conflicting way to change a template. Edit the files in your editor and reload to preview.

Because templates are committed and the dashboard can’t write them, your production working tree stays clean — a deploy webhook’s git pull never hits an uncommitted-changes conflict:

Terminal window
cd /var/www/your-site
git pull # brings in template changes
# clear caches as usual — see the Deployment guide

See the Deployment guide for webhook and cache-clearing details.

Git-first templates cover templates only. Your pages (the builder-pages records: routes, template bindings, nav, content) and other collection data are not git-controlled — they’re promoted local → production with the Sync Manager, exactly as before. Each artifact has one delivery channel:

  • Templates → git
  • Pages & content → Sync

So a fresh git clone brings up your templates; running a sync brings the pages and content over.

Delete (or move back) the ./builder folder and the site returns to admin-first: templates live in tcms-data/builder/ and are editable in the dashboard again. There’s no setting to flip.