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

Templates

Templates contain the HTML for your pages, spiced up with some PHP to dynamically pull in your content.

Screencast

Your first template

Connect the content from your content folder with your static HTML and bring your pages to life.

This video is loaded from YouTube servers with your consent. Read more…

TL;DR

  • All templates are stored in the /site/templates folder
  • To create a new template for a page, create a .php file with a filename that matches the filename of the content file
  • You can use the $page, $site and $pages variables to easily access the content of your pages/site

Naming your templates

When you open a page in the browser, Kirby reads the name of the text file to determine what template to use to render the page. If Kirby finds a template with the same name as the text file, it loads it and executes the code contained in it. If there is no matching template, the default template is used instead.

Here are some example of content file and template file counterparts:

Text file Template
/content/home/home.txt /site/templates/home.php
/content/projects/projects.txt /site/templates/projects.php
/content/projects/project-1/project.txt /site/templates/project.php
/content/projects/project-2/project.txt /site/templates/project.php

Template names must be lowercase, for example default.php or blog.php.

The default template

The default template is the only required template. It is called default.php and must exist in your /site/templates folder. When you get started with a completely new site you might want to start with just the default template as your foundation.

Shared templates

Pages with the same or a similar content structure can share a single template. For example, all the notes subpages in the /notes page or the album subpages of the /photography page of the Starterkit share the same template called note.php and album.php respectively.

Basic usage

Let's start with looking at a very simple HTML template and how we can replace parts of it with the content of our text files.

<html>
<head>
  <meta charset="UTF-8">
  <title>My first page</title>
</head>
<body>
  <h1>Hello world!</h1>
</body>
</html>

Nothing very special here, just a static HTML page with a title tag in the head and a headline in the body.

Kirby provides some API variables for each template that are instantly available and allow us to fetch content from our pages, namely the $site, the $page and the $pages variables.

The $site variable

The $site object contains important information about the site in general and the data stored in /content/site.txt. Let's replace the hard-coded document title with something more dynamic:

<html>
<head>
  <meta charset="UTF-8">
  <title><?= $site->title()->html() ?></title>
</head>
<body>
  Hello world!
</body>
</html>

With $site->title() we fetch the value of the title field from /content/site.txt.

The site.txt file of the Starterkit looks like this:

/content/site.txt
Title: Kirby Starterkit

----

Author: Content Folder GmbH & Co. KG

----

Description: This is Kirby's Starterkit.

----

Copyright: © 2009–2024 <a href="http://getkirby.com">The Kirby Team</a>

The above code would therefore render "Kirby Starterkit" as our document title.

The $site object is the perfect place for storing any data that you want to reuse throughout your site. Next to typical things like data for the title and description meta tags, you can also store copyright information or social media accounts.

All this data can be used in your templates instantly:

<html>
<head>
  <meta charset="UTF-8">
  <meta name="description" content="<?= $site->description()->html() ?>">
  <title>
    <?= $site->title()->html() ?>
  </title>
</head>
<body>

  <header>
    <h1 class="logo">
      <a href="<?= $site->url() ?>">
        <?= $site->title()->html() ?>
      </a>
    </h1>
  </header>

  Hello world!

  <footer>
    <p class="copyright"><?= $site->copyright()->html() ?></p>
  </footer>

</body>
</html>

As you can see, the $site object also contains the main URL of your site, which can be used to link the logo back to your homepage for example. The $site object has many more methods you can find in the Reference.

The $page variable

The $page object is probably the variable you will use the most throughout your templates. $page always refers to the currently active page.

Like the $site variable, the $page variable has many methods that allow us to get information from the page. You can find all available methods in the Reference.

<html>
<head>
  <meta charset="UTF-8">
  <meta name="description" content="<?= $site->description() ?>">
  <meta name="keywords" content="<?= $site->keywords() ?>">
  <title>
    <?= $page->title()->html() ?> | <?= $site->title()->html() ?>
  </title>
</head>
<body>

  <header>
    <h1>
      <a href="<?= $site->url() ?>">
        <?= $site->title()->html() ?>
      </a>
    </h1>
  </header>

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

  <footer>
    <p class="copyright"><?= $site->copyright()->html() ?></p>
  </footer>

</body>
</html>

The document title and the main container of the page are now completed with data from the currently visited page.

With

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

we fetch the title of the page and with

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

we get the data from the text field of the page. The html() field method is used to escape content.

All fields we added to our page content files are accessible like this.

Fieldnames are converted to lowercase and any punctuation is replaced with underscores as PHP does not support special characters in method names.

Reserved words

If you use field names in your text file, which are also used by native Kirby methods, e.g. "image", "videos", "audio", or "num", you cannot fetch the data like described above. To fetch the content of such fields, you have to use the content() method:

Field name Variable
Image: $page->content()->image()
Videos: $page->content()->videos()
Audio: $page->content()->audio()

Response types

In your templates, you can set different response types depending on content.

For example, to send an application/json response:

<?php

$kirby->response()->json();
echo json_encode(['your' => 'data']);

You can also send other response types by extension or MIME type:

<?php

$kirby->response()->type('txt');
$kirby->response()->type('text/plain');

The $kirby->response() object provides several other methods to customize the response (e.g. caching, HTTP headers and the HTTP status code). Learn more in the reference ›