Who this is for. Content modellers and lead developers responsible for a site that keeps growing; two hundred layouts and ninety-five input types is a normal end state. After this page you have naming rules to hand to the team and an audit to run each quarter.
What the names are for
Authors find layouts by name, and nothing else organises the lists they choose from:
- The layout picker on a record lists the layouts for that kind of record (pages, blog posts and so on) that belong to the record's site or to no site, plus the record's current layout. It is one flat list, sorted alphabetically by name.
- The component picker, used when an author adds a component to an area, shows the component layouts (layouts with no controller) that are not hidden and belong to the current site or to none. Each is a tile: the layout's thumbnail, or a generic icon, and its name. The area's supported layouts narrow the set, and the author can search by name.
- Layout categories play no part in either picker. They appear on the layout's own form, on the screen that manages them and in the API, and nowhere an author chooses a layout.
So the name is the only thing that groups related layouts where authors browse them. The admin's side of this is on Thumbnails, categories and the author's picker.
Naming layouts
- Lead with the family, then the variant, so that the alphabetical sort keeps siblings together: “Hero, split”, “Hero, full width”, “Card, person”, “Card, event”. “Split hero” and “Full-width hero” sort apart.
- Name a layout for what the author gets, in the author's words, not after the template file or the design ticket.
- Keep the template path parallel to the name, such as
components/hero-split.html, so that a developer can go from one to the other. - Give every component layout a thumbnail: in the component picker the tile is the thumbnail and the name, nothing more.
Naming input types
An input type is chosen when a layout area is created, by whoever builds layouts, so its name serves them rather than authors. Name it for what it holds and how it is edited (“Button style”, “Content width”, “Heading level”), not for the first layout that used it. A select's name says which set of options it offers, because two selects with different options are two input types. Before creating one, look for an existing type with the same category, editor and options.
Naming layout areas
- Use camelCase, the form the shorthand reads:
heading,preHeading,componentStyle, printed as{$component->preHeading}. A flag named after its class, such ascolumns--reverse(Pattern: attributes to CSS classes), is the exception: it is only read withgetAreaText(), so the shorthand does not need to reach it. - Use the same name for the same meaning on every layout. A heading is
headingeverywhere; shared templates, the attributes helper and the audit below all depend on it. - Name a select after the property it sets (
componentWidth,textAlignment), and its option keys after the classes they produce. - Avoid the names in the next table.
Names a getter already takes
The shorthand calls the record's own getter when one exists, and the getter wins over an area of the same name. An area called url on a page is never reached by {$page->url}, which prints the page's URL. The area can still be read with getAreaHtml('url') or getAreaText('url'), but every template author has to know that. Each kind of record has its own getters; these are examples from two of them, not one list for every record:
| Record | Area names its getters take |
|---|---|
| A page | id, name, url, slug, fullPath, position, created, modified, published, site, language, owner, parent, children, html, tags, categories, revisions, activeRevision, seoSettings, customUrl, externalId |
| A component | layout. A component has no url getter, so url is free there. |
Before naming an area anything short, check the record's methods in the Models reference.
Area names are effectively permanent
Content is linked to its layout area by the area's id, not its name, so renaming an area in the admin keeps every record's content: it is read under the new name from then on. What breaks is everything that still asks for the old name, and nothing warns you: no compiler or editor checks a template against the layout. In Smarty the shorthand raises Property intro does not exist; what the other reads and the API do with the old name is on Where content is stored, and what a change does to it. Treat a name that is in use as permanent, and when one must change, follow Renaming and retiring without losing content.
A quarterly audit
Run it every quarter and give it a named owner: someone who can hide layouts and knows whom to ask before anything is deleted. Write down what was found and what was changed, so that the next audit starts from it.
The platform has no report of which records use a layout, or of whether a component layout is still placed anywhere. Global components are the exception: the global component model counts its uses with getNumUsedInContent(), which counts every collection element that holds it, but a direct use in a component area only as present or absent. Everything else is built from two sides: the templates in the repository, and the content, through the admin's listings or the API.
Unused layouts
- Start from the admin's Layouts list: every layout, with its template path.
- For each page layout, list the records on it. A layout that no record uses and no one plans to use is a candidate.
- For each component layout, look for it in the content of the records that can hold it. The include count below shows only where templates include a component directly; a component an author placed is rendered through its layout, so a template the count never finds can still be in use.
- Hide the candidates. Do not delete them: deleting a layout runs no check for records that use it, and only users of the Developer type can do it. A hidden layout drops out of both pickers, while the records already on it keep it.
- Delete a hidden layout in a later quarter, if nothing has asked for it back.
Layouts whose template is missing
A layout names its template by path. If the file is gone, a page on that layout answers HTTP 500, and a component on it renders blank with HTTP 200. Check for this case specifically, since the page still loads. Compare each layout's template path with the files in the repository.