Разработка кастомных Ruby-плагинов для Jekyll под ключ

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

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Разработка кастомных Ruby-плагинов для Jekyll под ключ
Средний
~2-3 дня
Часто задаваемые вопросы

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

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

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

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

Почему нужен кастомный плагин Jekyll?

Представьте: на блоге 150 постов, разбитых по 20 тегам. Без кастомного плагина придётся вручную создавать index.md для каждого тега. Это неэффективно и чревато ошибками. Jekyll написан на Ruby и предоставляет полноценный Jekyll Plugins API через плагины. Плагины — это Ruby-классы, которые встраиваются в pipeline генерации сайта. Через них можно добавить новые теги Liquid, фильтры, генераторы страниц, конверторы форматов и хуки. GitHub Pages не запускает произвольные плагины (только белый список) — поэтому для их использования нужен собственный CI/CD. Мы разрабатываем кастомные плагины под ключ: от идеи до деплоя с тестами и документацией. Наши инженеры имеют 10+ лет опыта с Ruby и Jekyll, что гарантирует стабильность и производительность. Использование кастомных плагинов сокращает время сборки на 40% и ускоряет генерацию страниц в среднем в 2 раза. В одном из проектов для крупного медиа мы заменили набор из 5 готовых плагинов одним кастомным, что уменьшило время сборки с 12 до 7 минут и устранило конфликты зависимостей.

Сравнение с готовыми плагинами: когда кастомный лучше?

Готовые плагины из RubyGems экономят время, но часто не удовлетворяют специфическим требованиям. Кастомный плагин, написанный под вашу архитектуру, работает в среднем в 2 раза быстрее при генерации страниц тегов и не содержит лишнего кода. Он избавляет от конфликтов версий и позволяет точно контролировать поведение. Если нужно что-то уникальное — кастомный плагин оказывается единственным рабочим вариантом.

Типы плагинов и когда что использовать

Тип Суперкласс Применение
Generator Jekyll::Generator Создание страниц программно, агрегация данных
Converter Jekyll::Converter Новые форматы контента (AsciiDoc, reStructuredText)
Command Jekyll::Command Новые CLI-команды (jekyll mycommand)
Tag Liquid::Tag Кастомные теги {% mytag %}
Block Liquid::Block Теги с контентом {% block %}...{% endblock %}
Filter включение в Liquid::Template.register_filter Кастомные фильтры `{{ value

Примеры плагинов

Фильтр для форматирования чисел

Фильтр для форматирования числа в российский формат:

# _plugins/filters/number_format.rb
module NumberFormatFilter
  def ru_number(number, decimals = 0)
    return number unless number.is_a?(Numeric)

    formatted = number.to_f.round(decimals)
    parts = formatted.to_s.split('.')
    integer_part = parts[0].gsub(/(\d)(?=(\d{3})+$)/, '\\1 ')

    if decimals > 0 && parts[1]
      "#{integer_part},#{parts[1].ljust(decimals, '0')}"
    else
      integer_part
    end
  end

  def ru_currency(number, currency = '₽')
    "#{ru_number(number)} #{currency}"
  end

  def reading_time(content)
    words = content.split.length
    minutes = (words / 200.0).ceil
    "#{minutes} мин"
  end
end

Liquid::Template.register_filter(NumberFormatFilter)

Кастомный тег для вставки видео

Тег с lazy loading:

# _plugins/tags/video_embed.rb
module Jekyll
  class VideoEmbedTag < Liquid::Tag
    PROVIDERS = {
      'youtube' => 'https://www.youtube.com/embed/%s',
      'vimeo'   => 'https://player.vimeo.com/video/%s',
    }.freeze

    def initialize(tag_name, markup, tokens)
      super
      @params = {}
      markup.scan(/(\w+)="([^"]*)"/) do |key, value|
        @params[key] = value
      end
    end

    def render(context)
      provider = @params['provider'] || 'youtube'
      video_id = @params['id']
      title    = @params['title'] || 'Видео'
      aspect   = @params['aspect'] || '16-9'

      return "<!-- video_embed: missing id -->" unless video_id

      url = format(PROVIDERS[provider], video_id)

      <<~HTML
        <div class="video-embed video-embed--#{aspect}">
          <iframe
            src="#{url}"
            title="#{title}"
            allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
            allowfullscreen
            loading="lazy"
          ></iframe>
        </div>
      HTML
    end
  end
end

Liquid::Template.register_tag('video_embed', Jekyll::VideoEmbedTag)

Generator для страниц тегов

Jekyll нативно генерирует _site/tags/ только через сторонние плагины. Реализация:

# _plugins/generators/tag_pages.rb
module Jekyll
  class TagPageGenerator < Generator
    safe true
    priority :low

    def generate(site)
      all_tags = site.posts.docs.flat_map { |post|
        post.data['tags'] || []
      }.uniq.sort

      all_tags.each do |tag|
        site.pages << TagPage.new(site, site.source, tag)
      end

      site.pages << TagIndexPage.new(site, site.source, all_tags)
    end
  end

  class TagPage < Page
    def initialize(site, base, tag)
      @site = site
      @base = base
      @dir  = File.join('tags', Jekyll::Utils.slugify(tag))
      @name = 'index.html'

      process(@name)
      read_yaml(File.join(base, '_layouts'), 'tag.html')

      self.data['tag']         = tag
      self.data['title']       = "Посты с тегом: #{tag}"
      self.data['description'] = "Все материалы по теме «#{tag}»"

      self.data['tag_posts'] = site.posts.docs.select { |post|
        (post.data['tags'] || []).include?(tag)
      }.sort_by { |post| post.date }.reverse
    end
  end

  class TagIndexPage < Page
    def initialize(site, base, tags)
      @site = site
      @base = base
      @dir  = 'tags'
      @name = 'index.html'

      process(@name)
      read_yaml(File.join(base, '_layouts'), 'tags-index.html')

      self.data['title'] = 'Все теги'
      self.data['tags_with_counts'] = tags.map { |tag|
        count = site.posts.docs.count { |post|
          (post.data['tags'] || []).include?(tag)
        }
        { 'name' => tag, 'slug' => Jekyll::Utils.slugify(tag), 'count' => count }
      }.sort_by { |t| -t['count'] }
    end
  end
end

Хуки для постобработки

# _plugins/hooks/minify_html.rb
Jekyll::Hooks.register [:pages, :documents], :post_render do |doc|
  next unless doc.output_ext == '.html'
  next if doc.output.nil? || doc.output.empty?

  doc.output = doc.output
    .gsub(/>\s+</, '><')
    .gsub(/\s{2,}/, ' ')
    .strip
end

Jekyll::Hooks.register :site, :post_write do |site|
  puts "  Сайт собран: #{site.pages.length} страниц, #{site.posts.docs.length} постов"
  puts "  Выходная директория: #{site.dest}"
end

Тестирование плагинов

Пример теста для фильтра:

# spec/plugins/number_format_spec.rb
require 'jekyll'
require_relative '../../_plugins/filters/number_format'

RSpec.describe NumberFormatFilter do
  include NumberFormatFilter

  describe '#ru_number' do
    it 'форматирует тысячи с пробелом' do
      expect(ru_number(1234567)).to eq('1 234 567')
    end

    it 'форматирует десятичные дроби' do
      expect(ru_number(1234.5, 2)).to eq('1 234,50')
    end
  end

  describe '#reading_time' do
    it 'вычисляет время чтения' do
      content = Array.new(400, 'слово').join(' ')
      expect(reading_time(content)).to eq('2 мин')
    end
  end
end

Как разрабатывается кастомный плагин?

Процесс разработки включает несколько этапов. Сначала мы анализируем задачу: какие данные нужно обрабатывать, как часто меняется контент, требуется ли интеграция с внешними API. Затем проектируем архитектуру плагина: выбираем тип (Generator, Converter, Tag, Filter), определяем конфигурацию и хуки. Пишем код на Ruby с соблюдением принципов SOLID. После реализации добавляем модульные тесты RSpec с покрытием не менее 95% — это обязательное условие. Финальный шаг — интеграция в ваш проект: настройка Gemfile или директории _plugins/, а также CI/CD для автоматической сборки и деплоя. Для одного из клиентов мы разработали плагин-агрегатор новостей из 5 источников: он парсит RSS, создаёт новые страницы с контентом и генерирует XML-карту сайта за 3 секунды при каждой сборке. Весь процесс от ТЗ до деплоя занял 10 дней.

Пример настройки CI/CD для GitHub Actions
name: Build Jekyll site
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true
      - run: bundle exec jekyll build
      - uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./_site

Почему стоит заказать разработку у нас?

Наши инженеры имеют 10+ лет опыта с Ruby и Jekyll. Мы гарантируем стабильность и производительность: используем ленивую загрузку данных, кеширование и оптимизацию запросов. В каждом проекте мы предоставляем документацию и проводим обучение команды. Свяжитесь с нами для консультации по вашему проекту. Закажите разработку плагина под ключ — мы подготовим код, тесты и CI/CD.

Как интегрировать плагин в проект?

Плагин устанавливается через Gemfile или копируется в _plugins/. После подключения достаточно добавить конфигурацию в _config.yml. Для CI/CD потребуется шаг установки gem-зависимостей. Если вы планируете использовать плагин на GitHub Pages, понадобится сторонний CI, так как Pages не поддерживает произвольные плагины.

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

Тип плагина Ориентировочное время
Фильтр или простой тег 0.5–1 день
Тег с параметрами 1–2 дня
Generator для страниц 2–3 дня
Конвертер формата 3–5 дней
Сложный плагин с API и тестами 1–2 недели

Свяжитесь с нами для консультации по вашему проекту. Получите оценку задачи за 1 день.

Выбор типа сайта — техническая задача, а не маркетинг

Мы видим, как команды тратят бюджет на неподходящий стек. Лендинг на Next.js со статической генерацией и корпоративный сайт с CMS — принципиально разные инфраструктуры, даже если внешне похожи. Ошибка на старте ведёт к переплате за хостинг в 5–10 раз и низкой скорости загрузки. Core Web Vitals (LCP, INP, TTFB) для каждого типа сайта — свой набор приоритетов.

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

Как не ошибиться с выбором CMS?

Сайт-визитка

Самый компактный формат: 1–5 страниц, минимум динамики. Основная задача — дать контактную информацию и создать первое впечатление. Технически здесь нет сложности, но есть типичные ошибки.

Слишком тяжёлый стек. WordPress с 15 плагинами для 5 страниц — это 800ms TTFB на shared хостинге. Мы предлагаем статику: HTML/CSS/JS или Next.js с output: 'export', задеплоенное на Vercel или Cloudflare Pages. Никакого PHP, никакой базы данных — только CDN. TTFB < 50ms гарантированно. Экономия на хостинге — до 50 000 ₽ в год.

Нет контактной формы с backend-валидацией. Форма только с JS-валидацией — это декорация. Бэкенд должен валидировать, rate-limit и отправлять уведомление. Для статического сайта используем Formspree или серверлесс endpoint.

Отсутствие Schema.org разметки. Google Knowledge Panel строится на разметке LocalBusiness или Organization — адрес, телефон, часы работы. Для визитки это критично. Мы делаем её встроенной в шаблон.

Срок разработки: 2–3 недели с дизайном.

Почему скорость лендинга напрямую влияет на конверсию?

Лендинг

Лендинг — страница с одной целью: конверсия. Всё, что не ведёт к целевому действию, лишнее. Core Web Vitals здесь критичны, потому что платный трафик, а Google использует CWV как фактор в Quality Score.

Конкретный кейс: лендинг с hero-видео 8MB autoplay в MP4 без preload="none" + три сторонних скрипта аналитики синхронно в <head>. LCP 9.4s, INP 780ms. Мы заменили видео на poster image с отложенной загрузкой по scroll, скрипты перевели на async/defer и частично в Web Workers через Partytown. LCP 1.8s, INP 140ms. Конверсия выросла на 23% — только за счёт скорости, не дизайна.

A/B тестирование — стандартная практика. Google Optimize закрылся, но есть Growthbook (open source), PostHog, VWO. Для Next.js используем edge middleware для распределения трафика на уровне CDN без лишнего JS.

Срок: 2–4 недели. Закажите разработку под ключ — мы оценим ваш проект за 1 день.

Корпоративный сайт

Корпоративный — это CMS, несколько разделов, мультиязычность, интеграция с CRM. Ключевой вопрос: кто будет редактировать контент и как часто.

Если редакторы нетехнические — нужен visual editor. WordPress с Gutenberg или ACF Pro закрывает это. Для сложных структур — headless CMS (Strapi, Directus) с фронтендом на Next.js. Если сайт обновляется редко — Markdown в Git с Astro или Next.js. Деплой по push в main — никакой CMS.

Производительность. Страница «О компании» с 40 фотографиями в оригинале — LCP 12 секунд на мобильном. <Image> компонент Next.js с WebP и srcset решает без ручной работы.

Мультиязычность: Astrotomic Translatable на Laravel или next-intl / react-i18next. Структура URL — /ru/about, /en/about с hreflang.

Срок: 6–12 недель в зависимости от объёма.

Промо-сайт

Промо — временный или постоянный сайт под кампанию. Нестандартный дизайн, анимации, интерактив. Стек: GSAP, Framer Motion, Three.js, Lottie, Canvas API.

Главная ловушка — анимации, тормозящие на мобильных. GPU-анимации через transform и opacity — нормально. box-shadow в анимации, filter: blur() на каждом кадре, анимация width/height — причина 20fps на iPhone 12. will-change: transform помогает точечно.

prefers-reduced-motion — обязателен для accessibility. Мы всегда добавляем.

Срок: 3–6 недель, зависит от сложности.

Сравнительная таблица

Параметр Визитка Корпоративный Лендинг Промо
Страниц 1–5 10–50+ 1–3 1–10
CMS Не нужна Нужна Не нужна Редко
SEO-приоритет Средний Высокий Высокий Низкий
Анимации Минимум Умеренно Умеренно Интенсивно
Срок (с дизайном) 2–3 нед 6–12 нед 2–4 нед 3–6 нед

Стоимость в каждом случае рассчитывается индивидуально после изучения технического задания. — Google рекомендует TTFB под 0.8s, у нас <0.2s.

Что входит в работу

  • Аналитика и прототипирование (структура, пользовательские сценарии)
  • Дизайн-концепция (адаптивный, mobile-first)
  • Вёрстка с оптимизацией LCP, CLS, INP
  • Выбор и настройка CMS (если нужна)
  • Интеграция с CRM/маркетинговыми инструментами
  • Тестирование (кроссбраузерное, load-testing)
  • Документация и передача доступов
  • Обучение редакторов (видео + письменно)
  • Гарантия 3 месяца (бесплатные правки)

Наша экспертиза

Мы на рынке 10+ лет, реализовали 200+ проектов — от простых визиток до высоконагруженных лендингов с миллионными аудиториями. Каждый проект проходит аудит на Core Web Vitals перед релизом.

Вторая таблица: сравнение подходов

Подход TTFB (мс) Сложность поддержки Стоимость разработки
Static HTML/CSS <50 Низкая Низкая (от 50 000 ₽)
Next.js + headless CMS <200 Средняя Средняя (от 150 000 ₽)
WordPress + плагины 500–1500 Высокая Высокая (от 300 000 ₽)
Подробнее об оптимизации изображений Мы автоматически конвертируем в WebP/AVIF, генерируем srcset для всех разрешений, используем lazy loading с Intersection Observer. Для фоновых изображений — техника progressive loading.

Свяжитесь с нами, чтобы получить консультацию по вашему проекту. Закажите разработку под ключ — мы оценим сроки и бюджет за 1 день.