Comment puis-je changer le thème actif par programme?


20

Comment puis-je changer le thème Drupal 8 par programme?

Dans Drupal 6, nous avons utilisé le code suivant.

global $custom_theme;
$custom_theme = 'garland';

Dans Drupal 7, nous avons utilisé hook_custom_theme().

Dans Drupal 8, quelle est la bonne façon de procéder?

Réponses:


22

Dans Drupal 8, vous utilisez des négociateurs de thème , qui sont essentiellement des services utilisant une balise spécifique. Voir les négociateurs thématiques mis en place par Drupal, pour comprendre exactement comment ils fonctionnent; l'exemple donné dans l'enregistrement des modifications n'est pas mis à jour.

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');
  }

}

Le code est assez facile à comprendre: la applies()méthode revient TRUElorsque la route actuelle est celle pour laquelle votre module veut changer de thème; la determineActiveTheme()méthode renvoie le nom de la machine à thème du thème à appliquer.

Voir aussi ThemeNegotiator :: determineActiveTheme () ne doit pas nécessiter la transmission d'un RouteMatch pour une modification possible des arguments reçus des méthodes utilisées par les négociateurs de thème; si ce correctif est appliqué, vous devrez également modifier votre code de négociateur de thème.


Ne devrait pas appliquer () être écrit comme s'applique ($ route_match) dans l'exemple ci-dessus? Posté la même question sur la page do liée. Merci!
Stefanos Petrakis

@StefanosPetrakis Hmmm ... Toute implémentation actuelle obtient cela comme paramètre, contrairement à ce que dit cet enregistrement de changement.
kiamlaluno

J'ai mis à jour la réponse, en utilisant le code que Drupal core utilise actuellement dans l'un de ses négociateurs de thème.
kiamlaluno
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.