🚚 How to migrate to Kirby Tips & tutorials
Skip to content

PHP templating

In this post you are going to learn the basics of how to write clean templates with Kirby's PHP template engine.

Keep your code tidy

This is not only a rule for Kirby templates, but for all the HTML code you write – always keep it tidy, consistent and polished. I know it's often difficult with tight budgets or when you just started to learn how to code. But the cleaner you keep your templates right from the beginning, the easier it will be to maintain those later.

Get a good editor with great syntax highlighting

It's vital to feel comfortable with the editor and its syntax highlighting. It doesn't matter if it's Microsoft's Code, GitHub's Atom, an IDE like PHPStorm or something like SublimeText. Take what fits you.

Don't be afraid of PHP

I know that PHP looks a bit scary in the beginning, when you come from front-end developer background. But it's far less complicated than you might think. Here are the basics:

Display a variable

<?= $page->title() ?>

If clauses

<?php if ($page->isHomePage()): ?>
Welcome to the home page
<?php endif ?>

If / else

<?php if ($page->title()->isEmpty()): ?>
<h1>No title</h1>
<?php else: ?>
<h1><?= $page->title() ?></h1>
<?php endif ?>

foreach loops

<ul>
  <?php foreach ($site->children() as $subpage): ?>
    <li><?= $subpage->title()->link() ?></li>
  <?php endforeach ?>
</ul>

Those are the most basic tools you will need in your templates.
That wasn't too hard, right?

So let's move on with some rules to write beautiful PHP.

Indentation

Always make sure to use proper indentation. It doesn't really matter if you use spaces or tabs to indent your lines, just make sure it's tidy. Considering PHP blocks as HTML blocks makes it easier to structure templates and makes them look cleaner in the end.

<html>
  <head>
    <title><?= $site->title() ?></title>
  </head>
  <body>
    <nav>
      <ul>
        <?php foreach ($pages as $child): ?>
          <li><?= $child->title()->link() ?></li>
        <?php endforeach ?>
      </ul>
    </nav>
  </body>
</html>

Don't use curly brackets

Bad

<?php if ($page->hasChildren()) { ?>

  <ul>
    <?php foreach($page->children() as $child) { ?>
      <li>…</li>
    <?php } ?>
  </ul>

<?php } ?>

This becomes an unreadable mess when you have more than just one nested condition or loop and lots of html between it. Better use alternative syntax, which will help you to understand where blocks start and end.

Good

<?php if ($page->hasChildren()): ?>

  <ul>
    <?php foreach ($page->children() as $child): ?>
      <li>…</li>
    <?php endforeach ?>
  </ul>

<?php endif ?>

Never ever create entire HTML parts with PHP

Bad

<header>
<?php

echo '<nav>';
echo '<ul>';
foreach($page->children() as $child) {
  echo '<li>' . $child->title()->link() . '</li>';
}
echo '</ul>';
echo '</nav>';

?>
</header>

This will always end up in unreadable Spaghetti code.
It might be ok to do that inside a function sometimes. But most of the times you really should avoid this.

Good

<header>
  <nav>
    <ul>
      <?php foreach ($page->children() as $child): ?>
        <li><?= $child->title()->link() ?></li>
      <?php endforeach ?>
    </ul>
  </nav>
</header>

Use <?= instead of echo

Since PHP 5.4 the echo "short tag" is permanently enabled, so you can use

<?= instead of <?php echo

in your templates without having to make any php.ini or .htaccess settings.

There's also a short PHP tag (<? instead of <?php), which you can enable in your php.ini or your .htaccess file. However, we do not recommend using this short tag to keep your code as compatible and portable as possible.

By using the short echo tag in conjunction with the standard PHP opening tag (<?php), your templates become very readable and you can visually distinguish a control structure from an echo easily.

<html>
  <head>
    <title><?= $site->title() ?></title>
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <?php foreach ($pages as $child): ?>
          <li><?= $child->title()->link() ?></li>
          <?php endforeach ?>
        </ul>
      </nav>
    </header>
    <article>
      <h1><?= $page->title() ?></h1>
      <?= $page->text()->kirbytext() ?>
    </article>
    <footer><?= $site->copyright() ?></footer>
  </body>
</html>

Use snippets

Kirby has built-in includes for your templates called snippets. In other systems they are often called partials or stubs or something similar. There's an entire page in the docs about them, which you should definitely read.

Snippets can simplify your templates drastically, which will lead to better template readability.

No:

<html>
  <head>
    <title><?= $site->title() ?></title>
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <?php foreach ($pages as $child): ?>
          <li><?= $child->title()->link() ?></li>
          <?php endforeach ?>
        </ul>
      </nav>
    </header>
    <article>
      <h1><?= $page->title() ?></h1>
      <?= $page->text()->kirbytext() ?>
    </article>
    <footer><?= $site->copyright() ?></footer>
  </body>
</html>

Yes:

/site/snippets/header.php
<html>
  <head>
    <title><?= $site->title() ?></title>
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <?php foreach ($pages as $child): ?>
          <li><?= $child->title()->link() ?></li>
          <?php endforeach ?>
        </ul>
      </nav>
    </header>
/site/snippets/footer.php
<footer><?= $site->copyright() ?></footer>
</body>
</html>
/site/templates/mytemplate.php
<?php snippet('header') ?>

<article>
  <h1><?= $page->title() ?></h1>
  <?= $page->text()->kirbytext() ?>
</article>

<?php snippet('footer') ?>

Using snippets makes entire parts of your templates reusable for other templates and reduces the amount of code per template.

Use the js() and css() helpers

Kirby has a lot of built-in helpers to simplify your templates.

To simplify loading css and javascript files, you can use the following helpers:

<?= css('assets/css/mystyle.css') ?>
<?= js('assets/js/jquery.js') ?>

Use the url() function

Working with absolute URLs in templates is a nightmare. That's why Kirby has the url() function to help you build correct links:

Bad

<a href="http://mydomain.com/my/path/to/a/subpage">My subpage</a>

Good

<a href="<?= url('my/path/to/a/subpage') ?>">My subpage</a>

Simplify your if clauses

In many situations you don't have to write a full if clause in your templates. There are shorter versions, which you should know about:

Bad

<?php if ($page->hasChildren()): ?>
Yay, children!
<?php else: ?>
No children
<?php endif ?>

Good

<?= $page->hasChildren() ? 'Yay, children!' : 'No children' ?>

Even simpler: Use the e() function

A typical problem when writing templates is to switch on HTML attributes on demand.
(ie. for an active class on menu items)

Kirby has a built in e() function, which works like a compressed if/else clause:

<body<?php e($page->isHomePage(), ' class="home"') ?>>

In the example above, class="home" will only be added to the body tag, when the current page is the home page.

This even works with alternatives, when the condition is not matched:

<body class="<?php e($page->isHomePage(), 'home', 'other') ?>">

This will apply the home selector to the home page and the other selector whenever the current page is not the home page.

And one last trick:

You often have to check for an existing object first, before you can use it. For example when you want to find out if an image exists, before you render an image tag.

Bad

<?php $image = $page->images()->first() ?>
<?php if ($image): ?>
<img src="<?= $image->url() ?>" />
<?php endif ?>

Good

<?php if ($image = $page->images()->first()): ?>
<img src="<?= $image->url() ?>" />
<?php endif ?>

Still no friend of PHP templates?

We keep our template engine as simple and effective as possible, but we also don't want to lock you in. Our plugin system offers a simple way to embed your own template engine and there are plugins for Twig and other template engines available.

Further reading

Author