Кастомные 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 дня. При этом производительность кастомного решения в 3 раза выше, чем аналогичного через Preprocess или шаблонные костыли. А если нужен REST API для внешних систем — Views предоставляет готовый JSON-экспорт с настройкой CORS за полчаса.

Почему Views требует доработок?

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

Как создать кастомный фильтр за полдня?

Самый быстрый путь — hook_views_query_alter(). Допустим, нужно фильтровать товары по цене от и до. Передаём GET-параметры price_from и price_to, добавляем условия в запрос. Это не требует создания плагина, но логика остаётся в модуле. Для переиспользования пишем плагин фильтра с аннотацией @ViewsFilter. Такой подход обеспечивает чистую архитектуру и возможность протестировать фильтр отдельно. Мы используем PHP 8.3+ с типизацией и строгими типами — это уменьшает количество багов на этапе ревью.

Что делать, если стандартные Views не работают с кастомной таблицей?

Если ваши данные хранятся в отдельной таблице (например, 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 vs плагин

Критерий hook_views_query_alter Плагин фильтра
Скорость разработки 30 минут 2–4 часа
Переиспользование Нет Да
Тестируемость Низкая Высокая
Кэширование По умолчанию Кастомные cache tags

Процесс работы: от аналитики до деплоя

Этап Длительность Результат
Аналитика 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 дня. Стоимость рассчитывается индивидуально. В среднем такие доработки экономят до 60% бюджета по сравнению с костылями в шаблонах. Свяжитесь с нами — оценим ваш проект. Получите консультацию по архитектуре и оптимизации.

Подробнее о Views API читайте в официальной документации Drupal. Закажите разработку — получите готовое решение с гарантией совместимости и производительности.

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

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

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1060