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

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

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

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

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

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

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

Часто задаваемые вопросы

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

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

Почему нужен кастомный плагин 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 день.