Theme Negotiator

Theme Negotiatorсервисы с меткой theme_negotiator позволяющие программно переключать тему оформления.

Введение

Theme Negotiator используется Drupal для определения темы оформления, которая должна быть использована для отрисовки страницы в рамках текущего запроса.

В пределах одного запроса могут сработать сразу несколько Theme Negotiator, в таком случае будет выбрана тема возвращаемая сервисом с самым большим приоритетом.

Стандартные Theme Negotiator

Theme Negotiator сервисы, поставляемые с Drupal:

  • Drupal Core:
    • theme.negotiator.default: Сервис по умолчанию. Применяется ко всем страницам. В качестве темы оформления выбирает ту, что указана в конфигурации system.theme:default.
    • theme.negotiator.ajax_base_page: Сервис для AJAX запросов. Контролирует чтобы AJAX запросы отвечали с темой оформления, которая используется на странице-инициатора данного запроса.
  • Block:
    • theme.negotiator.block.admin_demo: Используется для включения нужной темы оформления и демонстрации регионов данной темы.
  • System:
    • theme.negotiator.system.batch: Устанавливает тему оформления для страниц выполнения Batch операций. В качестве темы старается использовать значение $settings['maintenance_theme'].
    • theme.negotiator.system.db_update: Устанавливает тему оформления для страниц обновления Базы Данных. Как и theme.negotiator.system.batch, отдаёт приоритет $settings['maintenance_theme'].
  • User:
    • theme.negotiator.admin_theme: Включает административную тему оформления для административных маршрутов и если пользователь имеет разрешение view the administration theme. Значение берётся из конфигурации system.theme:admin, если оно не задано, используется текущая тема оформления.

Создание Theme Negotiator

Класс Theme Negotiator должен реализовывать Drupal\Core\Theme\ThemeNegotiatorInterface и быть объявлен как сервис с меткой.

Класс должен реализовывать два обязательных метода:

  • applies(): Должен вернуть логическое значение TRUE, если данный Theme Negotiator подходит для текущего запроса, FALSE, если нет.
  • determineActiveTheme(): Должен вернуть машинное имя темы оформления, которая будет использоваться для отрисовки страницы.

Пример Theme Negotiator, который включает тему оформления special на основе куки use_special_theme:

<?php

namespace Drupal\example\Theme;

use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Theme\ThemeNegotiatorInterface;
use Drupal\Core\Path\PathMatcherInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Provides theme negotiator for 'special' theme.
 */
final class SpecialTheme implements ThemeNegotiatorInterface {

  /**
   * The request stack.
   * 
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  protected $requestStack;

  /**
   * Constructs the SpecialTheme object.
   * 
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack.
   */
  public function __construct(RequestStack $request_stack) {
    $this->requestStack = $request_stack;
  }

  /**
   * {@inheritdoc}
   */
  public function applies(RouteMatchInterface $routeMatch) {
    return $this->requestStack->getCurrentRequest()->cookies->has('use_special_theme');
  }

  /**
   * {@inheritdoc}
   */
  public function determineActiveTheme(RouteMatchInterface $routeMatch) {
    return 'special';
  }

}

Затем необходимо объявить данный класс как сервис:

services:
  theme.negotiator.special_theme:
    class: Drupal\example\Theme\SpecialTheme
    arguments: ['@request_stack']
    tags:
      - { name: theme_negotiator, priority: -40 }

Для нашего сервиса указан приоритет -40, так как у theme.negotiator.default приоритет -100. Таким образом, наш Theme Negotiator будет иметь больший вес чем определитель по умолчанию.

Ссылки

Помощь и обратная связь

Если вы обнаружили ошибку или хотите внести улучшения, и желаете внести изменения самостоятельно при помощи Pull Request
Если вы желаете предложить улучшение для этого документа

Обратиться за помощью

Если вы не нашли то что искали, воспользуйтесь поиском.

Если вам нужна помощь с чем-то конкретным, обратитесь к сообществу.