Разработка кастомного шаблона Kirby (PHP)
Шаблон в Kirby — обычный PHP-файл. Без движка шаблонизации сверху, без компиляции, без абстракций. Файл templates/article.php рендерится, когда страница имеет тип article (имя файла контента article.txt). Переменные $page, $site, $kirby доступны автоматически, остальные передаются через контроллер.
Снипеты — строительные блоки
Снипеты — это include-файлы с возможностью передачи данных:
<?php snippet('header', ['title' => $page->title()]) ?>
<main>
<?php snippet('hero', ['page' => $page]) ?>
<?php snippet('content-blocks', compact('page')) ?>
</main>
<?php snippet('footer') ?>
<?php
// site/snippets/hero.php
/** @var \Kirby\Cms\Page $page */
?>
<section class="hero" style="--bg: url('<?= $page->cover()->toFile()?->url() ?>')">
<div class="hero__inner">
<h1 class="hero__title"><?= $page->title()->html() ?></h1>
<?php if ($page->subtitle()->isNotEmpty()): ?>
<p class="hero__subtitle"><?= $page->subtitle()->html() ?></p>
<?php endif ?>
</div>
</section>
Работа с полями
Kirby возвращает объект поля, а не строку. Методы можно цеплять:
// текст
$page->title()->html()
$page->title()->upper()
$page->title()->slug()
$page->title()->or('Без названия')->html()
// дата
$page->date()->toDate('d.m.Y')
$page->date()->toDate('U') // Unix timestamp
$page->date()->isNotEmpty()
// Markdown → HTML
$page->text()->kirbytext()
// обрезка текста
$page->text()->excerpt(150, true, '...')
// числа
$page->price()->toFloat()
$page->count()->toInt()
// boolean-поля
$page->featured()->isTrue()
$page->active()->toBool()
Сложный шаблон: список с фильтрацией
<?php
// site/templates/products.php
/** @var \Kirby\Cms\Page $page */
/** @var \Kirby\Cms\Pages $products */
/** @var \Kirby\Cms\Pagination $pagination */
/** @var string $activeCategory */
snippet('header');
?>
<div class="products-page">
<aside class="filters">
<nav>
<a href="<?= $page->url() ?>"
class="<?= $activeCategory ? '' : 'active' ?>">
Все
</a>
<?php foreach ($categories as $cat): ?>
<a href="<?= $page->url(['params' => ['category' => $cat]]) ?>"
class="<?= $activeCategory === $cat ? 'active' : '' ?>">
<?= html($cat) ?>
</a>
<?php endforeach ?>
</nav>
</aside>
<section class="products-grid">
<?php foreach ($products as $product): ?>
<?php snippet('product-card', compact('product')) ?>
<?php endforeach ?>
<?php if ($products->isEmpty()): ?>
<p class="empty-state">Ничего не найдено</p>
<?php endif ?>
</section>
<?php if ($pagination->hasPages()): ?>
<nav class="pagination">
<?php if ($pagination->hasPrevPage()): ?>
<a href="<?= $pagination->prevPageURL() ?>">← Назад</a>
<?php endif ?>
<span><?= $pagination->page() ?> / <?= $pagination->pages() ?></span>
<?php if ($pagination->hasNextPage()): ?>
<a href="<?= $pagination->nextPageURL() ?>">Вперёд →</a>
<?php endif ?>
</nav>
<?php endif ?>
</div>
<?php snippet('footer') ?>
Вложенные структуры (structure field)
Структурное поле в Blueprint:
gallery:
type: structure
label: Галерея
fields:
image:
type: files
max: 1
caption:
type: text
alt:
type: text
Вывод в шаблоне:
<?php if ($page->gallery()->isNotEmpty()): ?>
<div class="gallery">
<?php foreach ($page->gallery()->toStructure() as $item): ?>
<?php $img = $item->image()->toFile() ?>
<?php if ($img): ?>
<figure>
<img
src="<?= $img->crop(600, 400)->url() ?>"
alt="<?= $item->alt()->or($img->alt())->html() ?>"
>
<?php if ($item->caption()->isNotEmpty()): ?>
<figcaption><?= $item->caption()->html() ?></figcaption>
<?php endif ?>
</figure>
<?php endif ?>
<?php endforeach ?>
</div>
<?php endif ?>
Блочный редактор (blocks field)
Kirby Blocks — аналог Gutenberg. Каждый блок рендерится отдельным сниппетом:
// templates/article.php
<?= $page->text()->toBlocks() ?>
Кастомный блок callout:
# site/blueprints/blocks/callout.yml
name: Callout
icon: alert
fields:
type:
type: select
options:
info: Информация
warning: Предупреждение
danger: Опасность
text:
type: writer
<?php
// site/snippets/blocks/callout.php
/** @var \Kirby\CMS\Block $block */
?>
<div class="callout callout--<?= $block->type()->html() ?>">
<?= $block->text()->kirbytext() ?>
</div>
Хелперы и глобальные функции
// вывод с экранированием
html($string)
esc($string, 'attr')
esc($string, 'url')
// URL
url('blog/first-post')
url('/', ['params' => ['page' => 2]])
// изображение
thumb($image, ['width' => 800, 'quality' => 85])
// перевод
t('read.more') // из site/languages/*.php
tt('items.count', $count) // с числом для склонения
Условные шаблоны
Kirby позволяет создавать вариантные шаблоны по суффиксу:
-
templates/article.php— основной -
templates/article.preview.php— для режима предпросмотра -
templates/article.rss.php— RSS-версия
Переключение: $page->render(['template' => 'article.rss']).
Сроки
Шаблон для одного типа страниц с блочным редактором и галереей: 2–3 дня. Полный комплект шаблонов для корпоративного сайта (главная, услуги, блог, контакты, 404): 1–2 недели с учётом верстки.







