FeaturesSite Builder

Build the whole site inside the CMS

Pages are records in a collection, and a routing middleware matches them as requests arrive. Nothing to generate, nothing to redeploy, no static build to wait on.

Standard Included in Standard and Pro

twig
{# tcms-data/builder/pages/blog-index.twig #}
{% extends 'layouts/default.twig' %}

{% block content %}
	<h1>{{ page.title }}</h1>

	{% for post in cms.collection.objects('blog') %}
		<article>
			<h2><a href="{{ cms.collection.objectUrl('blog', post) }}">{{ post.title }}</a></h2>
			<p>{{ post.summary }}</p>
		</article>
	{% endfor %}
{% endblock %}
A list page reads the collection directly and links to each record through the collection’s own URL.

The Site Builder lets you build a complete frontend website inside Total CMS. A page is an object in the builder-pages collection carrying a URL route, a template name, and its metadata. Templates live in tcms-data/builder/, split into layouts, pages, partials and macros. No router files or PHP stubs are generated — PageRouterMiddleware runs inside T3’s request pipeline and matches URLs dynamically.

Routing has a fixed order, and it protects the CMS from your URLs. Slim matches API and admin routes first; only when nothing claims the URL does the middleware take over. It checks builder page routes — static matches, then dynamic patterns, then catch-alls — and if none match it tries collection URL patterns. If nothing matches at all, it looks for a page whose HTTP status is 404 and renders that. So a builder page at /collections can never collide with the API at /api/collections.

Routes can carry placeholders. /products/{id} captures one segment, /blog/{category}/{slug} captures two, and /docs/{path:.*} matches across slashes. Captured values reach the template as params.*. Builder-page matches receive the page record as page; when the URL matches a collection’s own URL instead, the template is pages/{collection-id}.twig and the record arrives as object.

Each page also declares the HTTP status it returns — 200, 301 and 302 with a redirect target, 404, 410, 451, or 503 for maintenance — and an opt-in list of Features that run before the template does. The built-in auth feature sends logged-out visitors to the login page and returns 403 to logged-in users outside the access groups you listed. Pages are not limited to HTML either: give one a route of /robots.txt or /llms.txt and the content type is set from the extension.

A concrete start: tcms builder:init blog copies the starter’s layouts, pages and partials into place, creates the builder-pages collection, and imports the starter’s JumpStart file — five pages and five sample posts. Visit the site and it renders. From there cms.builder.nav() builds the menu from your pages, and cms.builder.url('blog-post', {id: post.id}) resolves links by page id, so renaming a route rebuilds every link that points at it.

At a glance

What you get

No build step
Pages are content, matched by the router as requests arrive. Add one in the admin and it is live — nothing to regenerate or redeploy.
Routes with placeholders
A route like /products/{id} gives every record its own URL. Catch-alls such as /docs/{path:.*} match across slashes for documentation and file viewers.
Start from a starter
tcms builder:init scaffolds minimal, blog, business or portfolio — templates, the pages collection, and demo content in one command.
Navigation builds itself
cms.builder.nav(), subnav() and navTree() read your page list and order file. cms.builder.url() resolves a page by id, so renamed routes never leave dead links.
Pages you can gate
Tick the auth feature to require a login, and name the access groups allowed through. Draft pages are not routable at all.

Site Builder

Common questions

Do I have to rebuild or redeploy after adding a page?

No. There is no generation step. Page records are matched by the routing middleware at request time, so a page renders as soon as it is saved.

Can a builder page conflict with the API or the admin?

No. Slim matches routes under /api/ and /admin/ before the builder middleware ever sees the request. A page at /collections is safe alongside the API at /api/collections.

Can I put a page behind a login?

Yes. Enable the auth feature on the page. Logged-out visitors are redirected to the login page and returned afterwards; logged-in users outside the access groups you listed get a 403 rather than a login loop.

Can Site Builder serve files that are not HTML?

Yes. A page with a route like /robots.txt, /llms.txt or /feed.xml is served with the content type matched to the extension, and the template has the full Twig surface available.

Try it on a site of your own.

45 days, every Pro feature, no credit card. Build it, hand it to a client, and see what they can and can’t touch.