¿Cómo puedo cambiar el tema activo mediante programación?

20

¿Cómo puedo cambiar el tema activo de Drupal 8 mediante programación?

En Drupal 6, utilizamos el siguiente código.

global $custom_theme;
$custom_theme = 'garland';

En Drupal 7, utilizamos hook_custom_theme().

En Drupal 8, ¿cuál es la forma correcta de hacer esto?

visabhishek
fuente

Respuestas:

22

En Drupal 8, utiliza negociadores de temas , que esencialmente son servicios que utilizan una etiqueta específica. Vea el tema de los negociadores implementados por Drupal, para comprender exactamente cómo funcionan; El ejemplo dado en el registro de cambios no se actualiza.

user.services.yml

  theme.negotiator.admin_theme:
    class: Drupal\user\Theme\AdminNegotiator
    arguments: ['@current_user', '@config.factory', '@entity.manager', '@router.admin_context']
    tags:
      - { name: theme_negotiator, priority: -40 }

AdminNegotiator.php

namespace Drupal\user\Theme;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Routing\AdminContext;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Theme\ThemeNegotiatorInterface;

/**
 * Sets the active theme on admin pages.
 */
class AdminNegotiator implements ThemeNegotiatorInterface {

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $user;

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The entity manager.
   *
   * @var \Drupal\Core\Entity\EntityManagerInterface
   */
  protected $entityManager;

  /**
   * The route admin context to determine whether a route is an admin one.
   *
   * @var \Drupal\Core\Routing\AdminContext
   */
  protected $adminContext;

  /**
   * Creates a new AdminNegotiator instance.
   *
   * @param \Drupal\Core\Session\AccountInterface $user
   *   The current user.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
   *   The entity manager.
   * @param \Drupal\Core\Routing\AdminContext $admin_context
   *   The route admin context to determine whether the route is an admin one.
   */
  public function __construct(AccountInterface $user, ConfigFactoryInterface $config_factory, EntityManagerInterface $entity_manager, AdminContext $admin_context) {
    $this->user = $user;
    $this->configFactory = $config_factory;
    $this->entityManager = $entity_manager;
    $this->adminContext = $admin_context;
  }

  /**
   * {@inheritdoc}
   */
  public function applies(RouteMatchInterface $route_match) {
    return ($this->entityManager->hasHandler('user_role', 'storage') && $this->user->hasPermission('view the administration theme') && $this->adminContext->isAdminRoute($route_match->getRouteObject()));
  }

  /**
   * {@inheritdoc}
   */
  public function determineActiveTheme(RouteMatchInterface $route_match) {
    return $this->configFactory->get('system.theme')->get('admin');
  }

}

El código es bastante fácil de entender: el applies()método regresa TRUEcuando la ruta actual es aquella para la cual su módulo desea cambiar el tema; el determineActiveTheme()método devuelve el nombre de la máquina del tema para aplicar.

Vea también ThemeNegotiator :: determineActiveTheme () no debería requerir que se pase un RouteMatch para un posible cambio en los argumentos recibidos de los métodos utilizados por los negociadores del tema; si se aplica ese parche, también deberá cambiar su código de negociador de tema.

kiamlaluno
fuente
¿No debería apply () escribirse como aplica ($ route_match) en el ejemplo anterior? Ha publicado la misma pregunta en la página vinculada de hacer. ¡Gracias!
Stefanos Petrakis
@StefanosPetrakis Hmmm ... Cualquier implementación actual obtiene eso como parámetro, al contrario de lo que dice ese registro de cambio.
kiamlaluno
He actualizado la respuesta, usando el código que Drupal core está usando en uno de sus negociadores temáticos.
kiamlaluno