Разработка кастомной темы Ghost (Handlebars)

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

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

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка кастомной темы Ghost (Handlebars)
Средняя
~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

Разработка кастомной темы Ghost (Handlebars)

Ghost темы используют Handlebars — логически упрощённый шаблонизатор. В отличие от PHP-шаблонов WordPress, в Handlebars нет произвольного кода — только хелперы Ghost и встроенные выражения. Это ограничение обеспечивает безопасность, но требует понимания системы хелперов.

Структура темы и обязательные файлы

my-theme/
├── package.json        # обязательно: name, version, engines.ghost
├── index.hbs           # главная страница / список постов
├── post.hbs            # шаблон поста
├── page.hbs            # статические страницы
├── error.hbs           # страницы ошибок (404, 500)
├── tag.hbs             # архив по тегу (опционально, fallback на index)
├── author.hbs          # страница автора (опционально)
├── partials/           # переиспользуемые части
│   ├── header.hbs
│   ├── footer.hbs
│   └── post-card.hbs
└── assets/
    ├── css/screen.css  # основной CSS
    └── js/main.js
// package.json
{
  "name": "my-theme",
  "description": "Custom Ghost theme",
  "version": "1.0.0",
  "engines": { "ghost": ">=5.0.0", "ghost-api": "v5" },
  "license": "MIT",
  "config": {
    "posts_per_page": 12,
    "image_sizes": {
      "xs": { "width": 300 },
      "s": { "width": 600 },
      "m": { "width": 1200 },
      "l": { "width": 2000 }
    },
    "card_assets": true,
    "custom": {
      "header_style": {
        "type": "select",
        "options": ["Center", "Left", "Right"],
        "default": "Center"
      },
      "show_reading_time": {
        "type": "boolean",
        "default": true
      }
    }
  }
}

Основные хелперы и контекст

{{! index.hbs — список постов}}
{{#foreach posts}}
  <article class="post-card {{post_class}}">
    {{#if feature_image}}
      <figure>
        <img srcset="{{img_url feature_image size="s"}} 300w,
                     {{img_url feature_image size="m"}} 600w,
                     {{img_url feature_image size="l"}} 1000w"
             sizes="(max-width: 768px) 100vw, 50vw"
             src="{{img_url feature_image size="m"}}"
             alt="{{title}}">
      </figure>
    {{/if}}

    <div class="post-card-content">
      <header>
        {{#primary_tag}}
          <a href="{{url}}" class="post-tag">{{name}}</a>
        {{/primary_tag}}
        <h2><a href="{{url}}">{{title}}</a></h2>
      </header>

      {{#if excerpt}}
        <p>{{excerpt words="30"}}</p>
      {{/if}}

      <footer>
        {{#primary_author}}
          <img src="{{img_url profile_image size="xs"}}" alt="{{name}}">
          <a href="{{url}}">{{name}}</a>
        {{/primary_author}}

        <time datetime="{{date format="YYYY-MM-DD"}}">
          {{date format="DD MMM YYYY"}}
        </time>

        {{#if @custom.show_reading_time}}
          <span>{{reading_time}}</span>
        {{/if}}
      </footer>
    </div>
  </article>
{{/foreach}}

{{pagination}}

Страница поста

{{! post.hbs}}
{{#post}}
<article class="{{post_class}}">
  <header>
    {{#unless primary_tag.name}}{{else}}
      <a href="{{primary_tag.url}}" class="tag">{{primary_tag.name}}</a>
    {{/unless}}

    <h1>{{title}}</h1>

    {{#if custom_excerpt}}
      <p class="excerpt">{{custom_excerpt}}</p>
    {{/if}}

    <div class="meta">
      {{#foreach authors}}
        <a href="{{url}}">{{name}}</a>{{#unless @last}}, {{/unless}}
      {{/foreach}}
      &middot;
      <time>{{date published_at format="DD MMMM YYYY"}}</time>
      &middot; {{reading_time}}
    </div>
  </header>

  {{#if feature_image}}
    <figure class="hero-image">
      {{!-- Ghost генерирует srcset автоматически --}}
      <img src="{{img_url feature_image size="l"}}"
           alt="{{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}}">
      {{#if feature_image_caption}}
        <figcaption>{{feature_image_caption}}</figcaption>
      {{/if}}
    </figure>
  {{/if}}

  <div class="post-content gh-content">
    {{content}}
  </div>

  {{! Блок для Members — только платный контент}}
  {{#if access}}
    <div class="premium-content">
      {{content}}
    </div>
  {{else}}
    <div class="paywall">
      <h3>Эта статья для подписчиков</h3>
      {{#unless @member}}
        <a href="#/portal/signup" class="btn-subscribe">Подписаться</a>
      {{/unless}}
    </div>
  {{/if}}

  {{! Связанные посты}}
  {{#get "posts" limit="3" filter="tag:[{{primary_tag.slug}}]+id:-{{id}}"}}
    <section class="related-posts">
      <h3>Похожие материалы</h3>
      {{#foreach posts}}
        {{> post-card}}
      {{/foreach}}
    </section>
  {{/get}}
</article>
{{/post}}

Helper {{#get}} для динамических данных

{{! Последние посты по тегу на главной}}
{{#get "posts" limit="5" filter="tag:javascript" order="published_at desc"}}
  {{#foreach posts}}
    <a href="{{url}}">{{title}}</a>
  {{/foreach}}
{{/get}}

{{! Количество подписчиков (публичная статистика)}}
{{#get "tiers" limit="all"}}
  {{#foreach tiers}}
    <div>{{name}}: доступно за {{monthly_price}}/мес</div>
  {{/foreach}}
{{/get}}

Кастомные настройки темы

Ghost 5 позволяет редакторам менять параметры темы через Admin без кода:

{{! Использование custom setting}}
<header class="site-header style-{{@custom.header_style}}">
  {{#if @custom.show_newsletter_signup}}
    {{> newsletter-form}}
  {{/if}}
</header>

Карточные блоки (Card CSS)

Ghost Koenig-редактор вставляет карточки (Gallery, Video, Bookmark, Product) с собственным HTML и CSS. Тема должна подключить эти стили:

// package.json
"config": {
  "card_assets": true  // Ghost автоматически добавит card CSS в <head>
}

Сборка и валидация

# Валидация темы (официальный инструмент Ghost)
npm install -g gscan
gscan /path/to/my-theme

# Или через API (CI/CD)
gscan /path/to/my-theme --json

# Загрузка через API
curl -X POST https://myblog.com/ghost/api/admin/themes/upload/ \
  -H "Authorization: Ghost $ADMIN_API_KEY" \
  -F "[email protected]"

Сроки разработки

Тема Время
Минимальная рабочая тема 2–3 дня
Полноценная тема (index, post, tag, author) 5–8 дней
Тема с Members/paywall и кастомными настройками 8–12 дней
Тема с Newsletter-шаблонами +1–2 дня