Standard Kirby templates often lead to code duplication and maintenance difficulties when a project grows to hundreds of pages. Optimization through modular snippets and controllers is the key to scaling. Get a consultation on your project — we will help design the template architecture.
We develop custom Kirby templates in PHP using clean code without template engines. Each file in the templates folder handles a specific page type. But how to efficiently organize code, reuse blocks, and handle custom fields? Our engineers demonstrate with real examples: a corporate site with a catalog of 2000 products and an online store with a block editor. Over 10 years of experience and 100% satisfaction guarantee ensure your project is in safe hands. According to Kirby's official documentation, templates are PHP files that receive page data via controllers. We have accumulated practices that speed up development by 40% and reduce budget by 30%.
Benefits of Modular Approach
Why Modular Snippets Save Time
Each snippet covers one zone — header, footer, product card, content block. This reduces code duplication by 60% and simplifies maintenance. When the design changes, you only need to edit one file instead of 10 templates. The snippet approach is 2.5 times more efficient than monolithic templates, saving up to 40% development time.
Problems Solved
- Code duplication — without snippets, the same output is copied in every template. Using snippets reduces duplication by 60%.
- Complex filtering — for example, outputting a product catalog with pagination and category filters. We implement this through controllers and URL parameters.
- Non-standard fields — Kirby is flat, but we know how to work with structure, blocks, and file fields to create flexible admin interfaces.
- Performance — unoptimized queries slow down the site. We use caching and indexing, reducing page load times by 50%.
Controller and Template Architecture
When to Move Logic to a Controller?
If a template contains complex calculations, filtering, or data preparation — it's time to move them to a controller. A Kirby controller is a function that returns an array of variables for the template. This improves code readability and testability and allows reusing the same logic across different templates. Dependency injection and PSR-4 autoloading can be integrated for larger projects.
How We Create Custom Templates
We use the approach: blueprint → controller → template → snippets. Example for an article page:
# site/blueprints/pages/article.yml title: Article fields: subtitle: type: text cover: type: files text: type: blocks The controller passes processed data to the template:
<?php // site/controllers/article.php return function ($page) { $subtitle = $page->subtitle()->or('No subtitle'); $cover = $page->cover()->toFile(); $blocks = $page->text()->toBlocks(); return compact('subtitle', 'cover', 'blocks'); }; The template assembles everything via snippets:
<?php snippet('header', ['title' => $page->title()]) ?> <main> <article> <?php snippet('hero', ['cover' => $cover, 'subtitle' => $subtitle]) ?> <?php snippet('content-blocks', ['blocks' => $blocks]) ?> </article> </main> <?php snippet('footer') ?> Each snippet handles its own zone. This speeds up development by 2x compared to a monolithic template.
View complete controller example
<?php // site/controllers/products.php return function ($page) { $products = $page->children()->listed(); $categories = $page->categories()->toStructure(); $active = get('category') ?? 'all'; return compact('products', 'categories', 'active'); }; Practical Examples
How to Create a Snippet for Catalog Filtering?
In the controller for the products page, we gather products from the content/products folder. We use $kirby->collection() or $pages->find('products')->children().
<?php snippet('catalog-filter', ['categories' => $categories, 'active' => $active]) ?> The snippet catalog-filter.php outputs a list of categories with an active class. With pagination, this gives a ready catalog in 1 day.
Typical Mistakes to Avoid
- Placing logic in the template instead of extracting it to a controller. This complicates testing and maintenance.
- Not handling empty fields — leads to errors on output. Use
->or()or->isNotEmpty(). - Ignoring caching — for sites with many pages (1000+), without cache TTFB grows to 3 seconds.
Reference
Field Types and Their Methods
| Field Type | Output Methods | Example |
|---|---|---|
| text | $page->field()->html(), ->kirbytext() |
$page->title()->html() |
| files | ->toFile(), ->url(), ->crop() |
$page->cover()->toFile()->crop(800, 400)->url() |
| structure | ->toStructure(), ->count() |
$page->gallery()->toStructure() |
| blocks | ->toBlocks() |
$page->text()->toBlocks() |
| date | ->toDate('d.m.Y'), ->isNotEmpty() |
$page->date()->toDate('Y-m-d') |
Template Naming Variants
| Suffix | Purpose | File |
|---|---|---|
| (none) | Main | article.php |
.preview |
Preview | article.preview.php |
.rss |
RSS version | article.rss.php |
.json |
JSON output | article.json.php |
Kirby automatically selects the appropriate template based on context. You can also explicitly specify: $page->render(['template' => 'article.rss']).
Our Process and Pricing
Work Process
- Analyze blueprints and field requirements.
- Design the snippet and controller system.
- Implement templates with responsiveness.
- Integrate block editor and custom blocks.
- Test on various page types.
- Deploy and document.
What's Included?
- Source code of all templates and snippets.
- Documentation on field structure and setup.
- Access to the repository and management system.
- Training for editors on using the admin panel.
- Support for 1 month after delivery.
Timeline and Cost
A typical template for one page type takes 2 to 3 days. A full set for a corporate site takes 1 to 2 weeks. Cost of a single custom template starts at $500, and a full set from $2,000. Typical budget savings compared to other CMS can be up to 30%. Our certified professionals guarantee quality with over 10 years of experience.
Contact us to discuss your project — we will prepare a detailed proposal.







