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 будет иметь больший вес чем определитель по умолчанию.
¶Ссылки
- Drupal 8: Theme Negotiator — программное переключение тем, Niklan, 2016.