Read this guide first. Core dna is hosted, so there is nothing to install; your repository holds only templates and front-end assets; and a new kind of page starts in the admin, with a layout. In half a day, from what the platform is to a page you built, deployed and rendered in Smarty or Twig.
L0
Unit 04 · From URL to rendered page
Module route to controller
From URL to rendered pagePage 22 of 28Updated
On the public site, the start of the path picks a module and the module's own routes pick a controller; anything no module claims goes to Pages. Why a site builder almost never writes a route, the exceptions, and the one place a URL maps straight to a template.
Who this is for. Theme developers, and anyone who has looked for the route table in a theme repository and not found it. After this page you will know how a public URL reaches a controller, and why that is the platform's business rather than yours.
Two tiers of routing
The module. The platform compares the start of the path with each module's prefix: /blogs, /books, /faq, /forms, /products, /search, /cart, /checkout, /my-account, /login, /files and others. A path that matches no prefix goes to Pages, whose prefix is empty, so Pages is where everything else ends up.
The controller. Inside the module, its own routes map the rest of the path to a controller. Pages has essentially one for visitors: show page, which takes the whole path as the page's full slug and looks the page up by it.
/blogs/... prefix "blogs" matches -> Blogs -> one of its controllers
/my-account/orders prefix "my-account" matches -> My account -> orders
/news/my-first-article no prefix matches -> Pages -> show page, full slug "news/my-first-article"
/ no prefix matches -> Pages -> show page, the home page
A site can give a module a different prefix. That is the reason templates build links with _url from route names, such as getPath('login'), rather than writing /login: the link follows the prefix wherever it is.
What the controller does
For a page, the show controller:
finds the page whose full slug is the path, among the records the visitor may see. An unpublished page, or one scheduled for later, does not exist for a visitor, who gets a 404;
checks the visitor's permission, for a page restricted to some members;
hands the page to the template as page, and also as record;
The show controllers of the other modules, for a blog post, a product or a book page, work the same way, each handing over its record under the record's own name.
Why you almost never write a route
A theme cannot add a route of its own: the routing tables are the platform's. It rarely needs to, because the built-in modules already cover pages, blog posts, books, FAQ, forms, products, the cart and checkout, search and the member area, and the rest is covered three ways:
Custom entities get public URLs from their definition: a path for the listing and one for each record, if the definition gives them.
Custom URLs give a single record an address of its own, outside the page tree: Taxonomy, URLs and SEO.
Under /my-account/, a path the member area has no route of its own for maps straight to a template file: /my-account/requests/show renders templates/my-account/requests/show.html. No layout and no record is involved; the page is for signed-in visitors only, and a path with no matching template is a 404. How the member area is routed covers the convention.