Bagaimana saya bisa mengubah tema aktif secara terprogram?

20

Bagaimana saya bisa mengubah tema Drupal 8 yang aktif secara terprogram?

Di Drupal 6, kami menggunakan kode berikut.

global $custom_theme;
$custom_theme = 'garland';

Di Drupal 7, kami menggunakan hook_custom_theme().

Di Drupal 8, apa cara yang benar untuk melakukan ini?

visabhishek
sumber

Jawaban:

22

Di Drupal 8, Anda menggunakan negosiator tema , yang pada dasarnya adalah layanan menggunakan tag tertentu. Lihat negosiator tema yang diterapkan oleh Drupal, untuk memahami dengan tepat bagaimana mereka bekerja; contoh yang diberikan dalam catatan perubahan tidak diperbarui.

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

}

Kode ini cukup mudah dimengerti: applies()Metode ini kembali TRUEketika rute saat ini adalah yang modul Anda ingin mengubah tema; yang determineActiveTheme()metode mengembalikan tema nama mesin tema untuk menerapkan.

Lihat juga ThemeNegotiator :: determActiveTheme () seharusnya tidak memerlukan RouteMatch untuk diteruskan untuk kemungkinan perubahan pada argumen yang diterima dari metode yang digunakan oleh negosiator tema; jika tambalan itu diterapkan, Anda juga perlu mengubah kode negosiator tema Anda.

kiamlaluno
sumber
Tidakkah seharusnya berlaku () ditulis sebagaimana berlaku ($ route_match) dalam contoh di atas? Diposting pertanyaan yang sama ke halaman do yang ditautkan. Terima kasih!
Stefanos Petrakis
@StefanosPetrakis Hmmm ... Setiap implementasi saat ini mendapatkan itu sebagai parameter, bertentangan dengan apa yang dikatakan oleh catatan perubahan.
kiamlaluno
Saya telah memperbarui jawabannya, menggunakan kode inti Drupal yang sebenarnya digunakan di salah satu negosiator temanya.
kiamlaluno