The ThemeNegotiatorInterface in Drupal 8/9 allows developers to associate themes with content by enabling theme switches based on user profile or role.
Implement a Custom Module:
Modules in Drupal are located in the /modules folder. We'll create two custom and contrib folders inside the /modules folder. Additional modules from drupal.org will be stored in the contrib folder, and our custom modules will be stored in the custom folder.
To change theme dynamically based on following scenario or condition:
- Dynamically change theme based on routinmg name.
- Dynamically change the theme based on the path.
- Dynamically change theme based on user roles.
Create a .info.yml file:
Let's name our custom module dynamic_theme. Create the folder /modules/custom/dynamic_theme. In this folder, we'll need to create the dynamic_theme.info.yml file and add the following code.
name: Dynamic Theme
description: Change theme dynamically using negotiator interface.
type: module
core_version_requirement: ^8 || ^9
Implement The Interface:
In dynamic_theme/src/Theme/ThemeNegotiator.php and implement the interface class as follows:
<?php
/**
* @file
* Contains \Drupal\dynamic_theme\Theme\ThemeNegotiator
*/
namespace Drupal\dynamic_theme\Theme;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Theme\ThemeNegotiatorInterface;
class ThemeNegotiator implements ThemeNegotiatorInterface {
/**
* @param RouteMatchInterface $route_match
* @return bool
*/
public function applies(RouteMatchInterface $route_match)
{
return $this->negotiateRoute($route_match) ? true : false;
}
/**
* @param RouteMatchInterface $route_match
* @return null|string
*/
public function determineActiveTheme(RouteMatchInterface $route_match)
{
return $this->negotiateRoute($route_match) ?: null;
}
/**
* Function that does all of the work in selecting a theme
* @param RouteMatchInterface $route_match
* @return bool|string
*/
private function negotiateRoute(RouteMatchInterface $route_match)
{
$userRolesArray = \Drupal::currentUser()->getRoles();
$path = \Drupal::request()->getpathInfo();
// dynamically change theme based on routinmg name.
if ($route_match->getRouteName() == 'user.login')
{
return 'seven';
}
// here welcome_message.front_page route name of custom module.
if ($route_match->getRouteName() == 'welcome_message.front_page')
{
return 'batrik';
}
// dynamically change the theme based on the path.
// here simple is a custom theme machine name.
if ( $path == '/node/add')
{
return 'simple';
}
// dynamically change theme based on user roles.
if (in_array("administrator", $userRolesArray))
{
return 'batrik';
}
return false;
}
}
Implement Symfony Service:
In dynamic_theme/dynamic_theme.services.yml and describe its dependencies.
services:
dynamic_theme.theme.negotiator:
class: Drupal\dynamic_theme\Theme\ThemeNegotiator
tags:
- { name: theme_negotiator, priority: 1000 }
- The tag theme_negotiator informs Drupal that this is a class that implements ThemeNegotiatorInterface and should be used to determine the theme in the current request.
- Drupal uses the tag priority to determine how important this class is in comparison to other ThemeNegotiatorInterface implementations in your project.
Enable the module:
For all possible ways to enable a module click here.
Using the Manage administrative menu, navigate to the Extend page in the list of modules, search the Dynamic Theme module, and select its checkbox. Scroll down to the bottom of the webpage, and then click Install.
Finally, check to switch the theme based on conditions.
Conclusion:
Many modules in Drupal 8 and 9 provide rule-based tools for switching themes, such as Administration Theme, Theme Switcher, and ThemeKey, to name a few. That's all! You have successfully created a custom module for changing themes dynamically based on conditions using the negotiator interface programmatically in Drupal 8/9.
Comments