How-to library · Developer docs

How-to library

Task-shaped pages: a title that starts with a verb, the situation in a few lines, the steps, the working code in both engines, and why this way rather than another. Found from a search, done, and left.

Create your first layout and template, from the admin to the repo

Deploy the template file first, create the layout that points at it in the admin, add the layout areas, then create a page that uses it. The admin only offers templates that already exist on the server.

Context

Context. A page renders through its layout: the layout names the template, and the layout's areas are what the template reads. The order matters because the admin only offers template files that exist on the server, so the file is deployed before the layout is created.

Steps

  1. Create templates/pages/pages/article.html, extending your base template. Commit and push the branch that deploys to the development environment.
  2. In the admin, add a layout: name Article, template pages/pages/article.html from the list, controller Show Page (under Pages). Left at None, it would be a component layout and never appear in the page form.
  3. Add the layout areas: heading (Text), body (Richtext), heroImage (Image), with labels written for the editor.
  4. Add a page, choose the Article layout, fill it in, publish, and open its URL signed out.
  5. Make the template read the layout areas, push, reload.

Code

JSON
{ "areas": { "heading": "Text", "body": "Richtext", "heroImage": "Image" } }
Template code
{extends 'includes/frontend/base-template.html'}
{block name='content'}
  <article>
    <h1>{$page->heading}</h1>
    {$hero = $page->getAreaImage('heroImage')}
    {if !$hero->isBlank()}{$hero->getResized(1200, 600, 'fit')->getHtml(['alt' => $page->getName()|escape])}{/if}
    {$page->body}
  </article>
{/block}
{% extends 'includes/frontend/base-template.html' %}
{% block content %}
  <article>
    <h1>{{ page.heading }}</h1>
    {% set hero = page.getAreaImage('heroImage') %}
    {% if not hero.isBlank() %}{{ hero.getResized(1200, 600, 'fit').getHtml({'alt': page.getName()|e}) }}{% endif %}
    {{ page.body }}
  </article>
{% endblock %}

Why this and not that

Not the layout first: the Add-layout screen refuses a template that is not on the server. Not moving the file later: the layout stores the template path, so a moved file breaks the layout (a page layout errors; a component layout renders blank). Not a slug-like area name chosen in a hurry: renaming a layout area later keeps the content but breaks every template that used the old name, so the names you give the layout areas are the ones you will live with.

Go deeper

Was this page helpful?

Your answer goes to the docs team.