Skip to content

Kirby 3.6.6

Layout

A visual editor for complex multi-column layouts

Getting started

By default the layout field comes with a single 1-column layout and all the default fieldsets from the Blocks field.

fields:
  layout:
    type: layout

Defining your own layouts

Defining available layouts is simple: each layout is list of column widths. i.e. 1/2, 1/2 or 1/4, 3/4

If the sum of the layout is greater than one, the other columns will be wrapped to the next line.

fields:
  layout:
    type: layout
    layouts:
      - "1/1"
      - "1/2, 1/2"
      - "1/4, 1/4, 1/4, 1/4"
      - "1/1, 1/3, 2/3"
      - "1/1, 2/3, 1/3"
      - "1/2, 1/2, 1/3, 1/3, 1/3"

Those layouts will then show up in the layout selector when an editor creates a new row:

Available widths

The layout field supports up to 12 columns and all are listed below.

  • 1/1 1/2 1/3 1/4 1/6 1/12
  • 2/2 2/3 2/4 2/6 2/12
  • 3/3 3/4 3/6 3/12
  • 4/4 4/6 4/12
  • 5/6 5/12
  • 6/6 6/12
  • 7/12
  • 8/12
  • 9/12
  • 10/12
  • 11/12
  • 12/12

Fieldsets

The layout field also accepts the fieldsets option from the blocks field to control blocks in columns.

The fieldsets setup is exactly the same. You can follow the instructions from the Blocks field.

fields:
  layout:
    type: layout
    layouts:
      - "1/1"
      - "1/2, 1/2"
      - "1/4, 1/4, 1/4, 1/4"
      - "1/3, 2/3"
      - "2/3, 1/3"
      - "1/3, 1/3, 1/3"
    fieldsets:
      - heading
      - text
      - image

Layout settings

It's often useful to set additional class names, IDs or even something like background colors and images for layout sections. This can be achieved with layout settings.

Layout settings are defined globally. Each layout will then get a "Settings" button in its dropdown and open a settings drawer with the configured fields.

fields:
  layout:
    type: layout
    layouts:
      - "1/1"
      - "1/2, 1/2"
      - "1/4, 1/4, 1/4, 1/4"
      - "1/3, 2/3"
      - "2/3, 1/3"
      - "1/3, 1/3, 1/3"
    fieldsets:
      - heading
      - text
      - image
    settings:
      fields:
        class:
          type: text
          width: 1/2
        id:
          type: text
          width: 1/2
        image:
          label: Background image
          type: files

Tabs

If you have a lot of settings, you can organize them in tabs:

fields:
  layout:
    type: layout
    layouts:
      # …
    fieldsets:
      # …
    settings:
      tabs:
        content:
          fields:
            link:
              type: url
            text:
              type: text
        styles:
          fields:
            class:
              type: text
            id:
              type: text

Reusing and extending layout settings

If you always use the same options in layouts and want to easily update all of them from a single file without repeating the options, you can reuse or extend the layout settings. Let's see how:

Sample settings fields

/site/blueprints/fields/settings.yml
fields:
  class:
    type: text
    width: 1/2
  id:
    type: text
    width: 1/2
  image:
    label: Background image
    type: files

Simple reuse

fields:
  layout:
    type: layout
    settings: fields/settings

Extended reuse

fields:
  layout:
    type: layout
    settings:
      extends: fields/settings
      fields:
        color:
          label: Background color
          type: text
          default: FFF

How to render layouts in templates?

Using the toLayouts field method, you can retrieve a Layouts collection - a collection of Kirby\Cms\Layout objects:

<?php foreach ($page->layout()->toLayouts() as $layout): ?>
<section class="grid" id="<?= $layout->id() ?>">
  <?php foreach ($layout->columns() as $column): ?>
  <div class="column" style="--span:<?= $column->span() ?>">
    <div class="blocks">
      <?= $column->blocks() ?>
    </div>
  </div>
  <?php endforeach ?>
</section>
<?php endforeach ?>

Calculate the column span value

Each column in a layout has a $column->width() method which will return the width defined in the blueprint. (i.e. 1/2) but for many grid systems you need to know how many columns the current column should span in the grid. This can be done with the $column->span() method. The method calculates with a 12-column grid by default. So for example, if your column width is 1/2 the span method would return a value of 6. If you are working with a different kind of grid system you can pass the number of columns like this: $column->span(6):

<?php foreach ($page->layout()->toLayouts() as $layout): ?>
<section class="6-column-grid" id="<?= $layout->id() ?>">
  <?php foreach ($layout->columns() as $column): ?>
  <div class="column" style="--span:<?= $column->span(6) ?>">
    <div class="blocks">
      <?= $column->blocks() ?>
    </div>
  </div>
  <?php endforeach ?>
</section>
<?php endforeach ?>

Working with individual blocks

In some cases, you might even want to controll the way blocks within layouts are rendered. $column->blocks() will return a blocks collection that you can work with and create another nested foreach loop.

<?php foreach ($page->layout()->toLayouts() as $layout): ?>
<section class="6-column-grid" id="<?= $layout->id() ?>">
  <?php foreach ($layout->columns() as $column): ?>
  <div class="column" style="--span:<?= $column->span(6) ?>">
    <div class="blocks">
      <?php foreach ($column->blocks() as $block): ?>
      <div class="block block-type-<?= $block->type() ?>">
        <?= $block ?>
      </div>
      <?php endforeach ?>
    </div>
  </div>
  <?php endforeach ?>
</section>
<?php endforeach ?>

Passing the layout object to the block snippet

If you need to access the layout object in a block snippet, you need to pass it to the snippet manually.

<?php foreach ($page->layout()->toLayouts() as $layout): ?>
<section class="6-column-grid" id="<?= $layout->id() ?>">
  <?php foreach ($layout->columns() as $column): ?>
  <div class="column" style="--span:<?= $column->span(6) ?>">
    <div class="blocks">
      <?php foreach ($column->blocks() as $block): ?>
      <div class="block block-type-<?= $block->type() ?>">
        <?php snippet('blocks/' . $block->type(), ['block' => $block, 'layout' => $layout]) ?>
      </div>
      <?php endforeach ?>
    </div>
  </div>
  <?php endforeach ?>
</section>
<?php endforeach ?>