Switching themes programmatically in Drupal 8

dynamic Theming
Sometimes you need to have a separate theme based on the user group or some scenario. At that time you need to switch your currently active theme to another theme.

UseCase

For example consider this scenario, when the user wants to see the Drupal site in the lighter version means you have to switch your theme to a lighter version. Consider you have one theme with more graphical and heavy load image, suppose the user has a low bandwidth network that time user wants to see the site in a light version theme means we need to provide one control like “You want to see a basic version” button this will switch the site into lighter version theme.

Solution

So we need do define a service and service class in your MODULENAME.services.yml
services:

MODULENAME.theme:

class: Drupal\MODULENAME\Theme\LighterThemeNegotiator

tags:

- { name: theme_negotiator, priority: 1000 }
If you want to take over all existing routes you have to choose a high priority.In case you want to just change the default theme dynamically but let route-specific theme negotiators still apply, use a priority < 0.
Here the service class (/MODULENAME/src/Theme/LighterThemeNegotiator.php)
<?php

namespace Drupal\MODULENAME\Theme;


use Drupal\Core\Routing\RouteMatchInterface;

use Drupal\Core\Theme\ThemeNegotiatorInterface;

/**

* Class LighterThemeNegotiator.

*

* @package Drupal\MODULENAME

*/

class LighterThemeNegotiator implements ThemeNegotiatorInterface {

/**

* If user select lighter version control.

*

* @param \Drupal\Core\Routing\RouteMatchInterface $route_match

*   The current route match object.

*

* @return bool

*   TRUE if this negotiator should be used or FALSE to let other negotiators

*   decide.

*/

public function applies(RouteMatchInterface $route_match) {

if (...) { //In our case if user clicks on the lighter version switch button

return TRUE;

}

return FALSE;

}


/**

* Determine the active theme for the request.

*

* @param \Drupal\Core\Routing\RouteMatchInterface $route_match

*   The current route match object.

*

* @return string|null

*   The name of the theme, or NULL if other negotiators, like the configured

*   default one, should be used instead.

*/

public function determineActiveTheme(RouteMatchInterface $route_match) {

return 'lighter_version'; //Theme Machine Name

}

}
Here we can use two methods, “applies” method will decide whether this theme negotiator needs to apply or not. Then “determineActiveTheme” method will return the machine name of the theme that should Drupal set.
For more information, https://www.drupal.org/node/2158619

Conclusion

I hope this tutorial will help you to manipulate Drupal themes programmatically and also this will give you an idea in which scenario you can use this theme switching in your Drupal setup. So this way you can handle the complex logic to determine whether and which theme needs to be used in a certain case.

Leave a Comment