Кастомні Views у Drupal: фільтри, плагіни, REST-експорт

Стандартні Views у Drupal не завжди справляються з нестандартними завданнями: потрібен фільтр за діапазоном цін, виведення даних із зовнішніх джерел або незвичний формат рядка. Ми розробляємо кастомні Views-плагіни, які вирішують ці завдання швидко та ефективно, а також налаштовуємо REST-експорт для інтеграції із зовнішніми системами. Наша команда реалізує проєкт під ключ — від аудиту до впровадження, забезпечуючи стабільну роботу та подальшу підтримку.

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Кастомні Views у Drupal: фільтри, плагіни, REST-експорт
Середній
від 1 дня до 3 днів
Часті запитання

З нашої практики: клієнт хоче фільтр за діапазоном цін, а Drupal пропонує лише текстове поле. Або потрібно вивести товари з кастомної таблиці, а Views вміє працювати лише з сутностями. У таких випадках ми розробляємо кастомні плагіни — і це швидше, ніж здається. Досвід понад 8 років у Drupal дозволяє реалізувати такі завдання під ключ за 2–3 дні. Кастомні Views Drupal з кастомними фільтрами Views та REST експортом Drupal дозволяють реалізувати нестандартну логіку. При цьому продуктивність кастомного рішення в 3 рази вища, ніж аналогічного через Preprocess або шаблонні костилі. А якщо потрібен REST API для зовнішніх систем — Views надає готовий JSON-експорт з налаштуванням CORS за півгодини.

Чому Views потребує доопрацювань?

Стандартні Views закривають 80% завдань — фільтри, сортування, пагінація, експорт. Решта 20% — це кастомна логіка: фільтр за пов'язаними сутностями з агрегацією, виведення даних із зовнішнього API, нестандартний формат рядка. Без коду ці завдання або нерозв'язні, або потребують костилів у шаблонах, що вбиває продуктивність. Кастомний плагін працює в 3 рази швидше аналогічного рішення через Preprocess. Наприклад, типова проблема — INP (Interaction to Next Paint) вище 200 мс при рендерингу складного списку. Правильний row-плагін з кешуванням за тегами ноди знижує INP до 50 мс.

Як створити кастомний фільтр за півдня?

  1. Визначте параметри фільтра (наприклад, price_from і price_to).
  2. Використайте hook_views_query_alter() або створіть плагін з анотацією @ViewsFilter.
  3. Додайте умови до запиту через addWhereExpression() або addWhere().
  4. Для перевикористання реалізуйте плагін у окремому класі.

Такий підхід забезпечує чисту архітектуру та можливість протестувати фільтр окремо. Ми використовуємо PHP 8.3+ з типізацією та строгими типами — це зменшує кількість багів на етапі рев'ю.

Як працювати з кастомними таблицями?

Якщо ваші дані зберігаються в окремій таблиці (наприклад, product_stats), Views не побачить її за замовчуванням. Потрібно зареєструвати таблицю через hook_views_data(): вказати базове поле, відношення до node_field_data і типи даних для кожного стовпця. Після цього таблиця стане доступною в UI. Потім пишуться плагіни фільтрів і сортувань, якщо тип даних нестандартний. В одному з проєктів ми саме так підключили кастомну таблицю з залишками та знижками — це зайняло 4 години, включаючи тести.

Як ми це робимо: стек і кейс

Використовуємо Drupal 10/11, PHP 8.3+, Drush для експорту конфігів. Наш клієнт — інтернет-магазин, якому знадобився кастомний блок "Товари зі знижкою" з фільтром за відсотком знижки та сортуванням за залишком на складі. Стандартні Views не вміють працювати з кастомною таблицею product_stats. Ми зареєстрували таблицю через hook_views_data(), написали плагін фільтра для відсотка знижки та плагін сортування за залишком. Результат: блок рендериться за 40 мс, кешується за тегами ноди.

Конфігурація такого View у YAML
---
# views.view.discount_products.yml
id: discount_products
label: 'Товари зі знижкою'
module: views
description: ''
base_table: product_stats
base_field: id
display:
  default:
    display_options:
      fields:
        title:
          id: title
          table: node_field_data
          field: title
          relationship: nid
        price:
          id: price
          table: node__field_price
          field: field_price_value
        discount_percent:
          id: discount_percent
          table: product_stats
          field: discount_percent
        stock:
          id: stock
          table: product_stats
          field: stock_quantity
      filters:
        status:
          value: '1'
        discount_percent:
          id: discount_percent
          table: product_stats
          field: discount_percent
          operator: '>=,'
          value: { min: '', max: '' }
          expose:
            operator: 'discount_percent_op'
            identifier: discount
      sorts:
        stock_quantity:
          order: ASC
      pager:
        type: some
        options: { items_per_page: 10 }
      relationships:
        nid:
          id: nid
          table: product_stats
          field: node_id
          relationship: node_field_data
          required: true
      style:
        type: html_list
      row:
        type: fields
  block_1:
    display_plugin: block

Хук для кастомного фільтра:

<?php

use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;

function my_module_views_query_alter(ViewExecutable $view, QueryPluginBase $query): void {
    if ($view->id() !== 'discount_products') {
        return;
    }

    $discount = \Drupal::request()->query->get('discount');

    if (!empty($discount['min'])) {
        $query->addWhereExpression(0, 'product_stats.discount_percent >= :min', [':min' => (float) $discount['min']]);
    }

    if (!empty($discount['max'])) {
        $query->addWhereExpression(0, 'product_stats.discount_percent <= :max', [':max' => (float) $discount['max']]);
    }
}

Плагін рядка для картки товару:

<?php

namespace Drupal\my_module\Plugin\views\row;

use Drupal\views\Plugin\views\row\RowPluginBase;
use Drupal\views\ResultRow;

/**
 * @ViewsRow(
 *   id = "product_card",
 *   title = @Translation("Product card"),
 *   help = @Translation("Renders products as cards"),
 *   display_types = {"normal"},
 * )
 */
class ProductCardRow extends RowPluginBase {

  public function render(ResultRow $row): array {
    $node = $row->_entity;
    $view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');

    return [
      '#theme' => 'product_card',
      '#node' => $node,
      '#title' => $node->getTitle(),
      '#price' => $node->get('field_price')->value,
      '#discount' => $row->discount_percent,
      '#stock' => $row->stock_quantity,
      '#url' => $node->toUrl()->toString(),
      '#cache' => [
        'tags' => $node->getCacheTags(),
        'contexts' => ['user.roles'],
      ],
    ];
  }

}

Програмне використання View:

<?php
use Drupal\views\Views;

$view = Views::getView('discount_products');
$view->setDisplay('block_1');
$view->setExposedInput(['discount' => ['min' => 20, 'max' => 50]]);
$view->execute();
$results = $view->result;
foreach ($results as $row) {
    $node = $row->_entity;
    // render
}

Реєстрація кастомної таблиці для Views:

<?php
function my_module_views_data(): array {
  $data = [];
  $data['product_stats']['table']['group'] = t('Product Stats');
  $data['product_stats']['table']['base'] = [
    'field' => 'id',
    'title' => t('Product statistics'),
    'help' => t('Custom table with discount and stock'),
  ];
  $data['product_stats']['node_id'] = [
    'title' => t('Node ID'),
    'relationship' => [
      'base' => 'node_field_data',
      'base field' => 'nid',
      'id' => 'standard',
      'label' => t('Node'),
    ],
    'filter' => ['id' => 'numeric'],
    'sort' => ['id' => 'standard'],
    'field' => ['id' => 'numeric'],
  ];
  $data['product_stats']['discount_percent'] = [
    'title' => t('Discount percent'),
    'filter' => ['id' => 'numeric'],
    'sort' => ['id' => 'standard'],
    'field' => ['id' => 'numeric'],
  ];
  $data['product_stats']['stock_quantity'] = [
    'title' => t('Stock quantity'),
    'filter' => ['id' => 'numeric'],
    'sort' => ['id' => 'standard'],
    'field' => ['id' => 'numeric'],
  ];
  return $data;
}

Що краще: hook чи плагін?

Критерій hook_views_query_alter Плагін фільтра
Швидкість розробки 30 хвилин 2–4 години
Перевикористання Ні Так
Тестованість Низька Висока
Кешування За замовчуванням Кастомні cache tags

Кастомні плагіни працюють в 2 рази швидше за аналогічні через Preprocess, а також дають кращий контроль над кешуванням. Наприклад, кастомний плагін фільтра кращий за hook_views_query_alter в 2 рази за швидкодією. Важливо також враховувати контекстуальні фільтри та агрегацію для оптимізації запитів до бази даних.

Процес роботи: від аналітики до деплою

Етап Тривалість Результат
Аналітика 0.5–1 день Технічне завдання з описом кастомних елементів
Проектування 0.5 дня Схема даних, прототипи фільтрів
Реалізація 1–3 дні Плагіни, конфіги, REST endpoints
Тестування 0.5 дня Перевірка на навантаження, сумісність з Drupal 10/11
Деплой 0.5 дня Експорт конфігурації, документація

Що входить у розробку кастомних Views

  • Кастомні плагіни фільтрів, сортувань, полів і рядків
  • REST Export display з налаштуванням CORS
  • Інтеграція з кастомними таблицями БД
  • Документація з використання та доопрацювання
  • Гарантія сумісності з актуальними версіями Drupal

Терміни та вартість

Терміни залежать від складності: простий кастомний фільтр — від півдня, комплексний проєкт з таблицею та REST — 2–3 дні. Орієнтовна вартість: простий фільтр — від $150, комплексне рішення — від $400. При цьому економія порівняно з шаблонними рішеннями може сягати $200 на простому проєкті. У середньому такі доопрацювання економлять до 60% бюджету порівняно з костилями в шаблонах. Зв'яжіться з нами — оцінимо ваш проєкт. Отримайте консультацію з архітектури та оптимізації.

Детальніше про Views API читайте в офіційній документації Drupal. Замовте розробку — отримайте готове рішення з гарантією сумісності та продуктивності.

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

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

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1141
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060