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

Чому потрібен кастомний плагін Jekyll?

Розробка та обслуговування будь-яких видів сайтів:

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

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

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

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

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1418
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1243
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    998

Чому потрібен кастомний плагін Jekyll?

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

Порівняння з готовими плагінами: коли кастомний кращий?

Готові плагіни з RubyGems економлять час, але часто не задовольняють специфічні вимоги. Кастомний плагін, написаний під вашу архітектуру, працює в середньому вдвічі швидше при генерації сторінок тегів і не містить зайвого коду. Він позбавляє від конфліктів версій і дозволяє точно контролювати поведінку. Якщо потрібно щось унікальне — кастомний плагін виявляється єдиним робочим варіантом.

Типи плагінів і коли що використовувати

Тип Суперклас Застосування
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 день.