Разработка сайта на CMS Kirby

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка сайта на CMS Kirby
Средняя
~5 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Разработка сайта на CMS Kirby

Kirby — файловая CMS на PHP без базы данных. Контент хранится в папках и текстовых файлах, шаблоны — чистый PHP, панель управления встроена и работает из коробки. Хорошо подходит для корпоративных сайтов, портфолио, блогов, небольших каталогов — там, где нужна простая эксплуатация без MySQL и миграций.

Структура проекта

site/
├── blueprints/       # схемы полей панели
│   ├── pages/
│   └── files/
├── collections/      # переиспользуемые наборы страниц
├── config/           # конфигурация, хуки, маршруты
├── models/           # расширенные модели страниц
├── plugins/          # сторонние и кастомные плагины
├── snippets/         # переиспользуемые части шаблонов
├── templates/        # шаблоны страниц
└── controllers/      # логика перед рендерингом

content/
├── home/
│   └── home.txt
├── about/
│   └── about.txt
└── blog/
    ├── blog.txt
    ├── 2024-01-15_first-post/
    │   └── article.txt
    └── 2024-02-20_second-post/
        └── article.txt

Шаблонная система

Kirby сопоставляет шаблон по имени файла контента. Файл article.txt → шаблон templates/article.php:

<?php snippet('header') ?>

<article class="post">
    <header>
        <h1><?= $page->title()->html() ?></h1>
        <time datetime="<?= $page->date()->toDate('Y-m-d') ?>">
            <?= $page->date()->toDate('d.m.Y') ?>
        </time>
    </header>

    <div class="content">
        <?= $page->text()->kirbytext() ?>
    </div>

    <?php if ($page->tags()->isNotEmpty()): ?>
    <footer class="tags">
        <?php foreach ($page->tags()->split() as $tag): ?>
            <a href="<?= $site->url() ?>/blog/tag:<?= $tag ?>">
                <?= html($tag) ?>
            </a>
        <?php endforeach ?>
    </footer>
    <?php endif ?>
</article>

<?php snippet('footer') ?>

Blueprints — схемы полей

Blueprint описывает, какие поля доступны редактору для каждого типа страницы:

# site/blueprints/pages/article.yml
title: Статья

columns:
  main:
    width: 2/3
    sections:
      content:
        type: fields
        fields:
          title:
            type: text
            label: Заголовок
            required: true
          text:
            type: writer
            label: Текст статьи
            inline: false
            marks:
              - bold
              - italic
              - link
              - code
          cover:
            type: files
            label: Обложка
            max: 1
            query: page.images

  sidebar:
    width: 1/3
    sections:
      meta:
        type: fields
        fields:
          date:
            type: date
            label: Дата публикации
            default: today
          tags:
            type: tags
            label: Теги
          seo_description:
            type: textarea
            label: SEO-описание
            maxlength: 160

Контроллеры

Контроллер отделяет логику от шаблона:

<?php
// site/controllers/blog.php
return function ($page, $site) {
    $tag = param('tag');

    $articles = $page->children()
        ->listed()
        ->when($tag, fn($pages) => $pages->filterBy('tags', $tag, ','))
        ->sortBy('date', 'desc')
        ->paginate(12);

    return [
        'articles'   => $articles,
        'pagination' => $articles->pagination(),
        'activeTag'  => $tag,
        'allTags'    => $page->children()->listed()->pluck('tags', ',', true),
    ];
};

Шаблон blog.php получает $articles, $pagination и $activeTag как готовые переменные.

Модели страниц

Когда нужно добавить методы к конкретному типу страниц:

<?php
// site/models/article.php
class ArticlePage extends Page
{
    public function readingTime(): int
    {
        $words = str_word_count(strip_tags($this->text()->kirbytext()));
        return (int) ceil($words / 200);
    }

    public function isNew(): bool
    {
        return $this->date()->toDate('U') > strtotime('-30 days');
    }

    public function relatedArticles(int $limit = 3): Pages
    {
        $tags = $this->tags()->split();

        return $this->siblings()
            ->listed()
            ->not($this)
            ->filter(function ($article) use ($tags) {
                return count(array_intersect(
                    $article->tags()->split(),
                    $tags
                )) > 0;
            })
            ->sortBy('date', 'desc')
            ->limit($limit);
    }
}

В шаблоне: <?= $page->readingTime() ?> мин чтения.

API и безголовый режим

Kirby отдаёт JSON из коробки — достаточно добавить расширение к URL:

GET /blog.json
GET /blog/first-post.json

Или настроить кастомные маршруты:

// site/config/config.php
return [
    'api' => true,
    'routes' => [
        [
            'pattern' => 'api/articles',
            'action' => function () {
                $articles = page('blog')
                    ->children()
                    ->listed()
                    ->sortBy('date', 'desc')
                    ->limit(20);

                return [
                    'data' => $articles->toArray(function ($article) {
                        return [
                            'id'       => $article->id(),
                            'title'    => $article->title()->value(),
                            'date'     => $article->date()->toDate('Y-m-d'),
                            'excerpt'  => $article->text()->excerpt(200),
                            'url'      => $article->url(),
                        ];
                    }),
                ];
            },
        ],
    ],
];

Медиа и изображения

<?php if ($cover = $page->cover()->toFile()): ?>
<img
    src="<?= $cover->crop(800, 450)->url() ?>"
    srcset="
        <?= $cover->crop(400, 225)->url() ?> 400w,
        <?= $cover->crop(800, 450)->url() ?> 800w,
        <?= $cover->crop(1200, 675)->url() ?> 1200w
    "
    sizes="(max-width: 768px) 100vw, 800px"
    alt="<?= $cover->alt()->or($page->title())->html() ?>"
    loading="lazy"
>
<?php endif ?>

Kirby генерирует производные изображения на лету и кэширует их в media/.

Производительность и кэш

// site/config/config.php
return [
    'cache' => [
        'pages' => [
            'active' => true,
            'type'   => 'file',
            'ignore' => fn($page) => $page->id() === 'search',
        ],
    ],
    'content' => [
        'locking' => false, // отключить блокировку файлов в prod
    ],
];

Для высоконагруженных сайтов кэш страниц выносится в Redis через сторонний драйвер.

Сроки

Корпоративный сайт 5–10 страниц с нестандартным дизайном: 2–3 недели. Блог или каталог с фильтрацией, поиском и кастомными полями: 3–5 недель. Если нужна интеграция с внешним API или безголовый режим для фронтенд-фреймворка — добавляется 3–7 дней.