Theming Drupal 8 pages based on URL

We’ve been all heads down over here, digging in to Drupal 8. We are trying to figure out best practices for the front end, now that we are no longer building new sites in Drupal 7, and documenting as we go. It has been fun picking things up, and I’d like to try to share more as I discover new things.

One little snippet I can share from today is how to target a certain page (or group of pages) based on the URL you have assigned it using path alias (called “routes” in Drupal 8.)

Out of the box, the Classy theme will give you a class on your body tag based on what Drupal assigns as a path, such as “path-node-53.” That’s great — but what if you gave it a URL Alias — or, even better, have Path Auto set up to give it a smart path — and want to leverage that with a body class for theming?

Borrowing from the path body-class work, this is actually pretty straightforward.

In YOURTHEME.theme:

use Drupal\Component\Utility\Html;

/**
 * Preprocess variables for html templates.
 * @param $variables
 */
 function advostarterkit_preprocess_html(&$variables) {
   // Get the route (this will give you the entire post-domain url)
   $route = str_replace('.','-',\Drupal::request()->getRequestUri());
   // break it up into args
   $route_args = explode('/', $route);
   // print them together or individually
   $variables['route_info']['args'] = Html::cleanCssIdentifier(ltrim($route, '/'));
   if (isset($route_args[1]) {
     $variables['route_info']['arg_1'] = Html::cleanCssIdentifier(ltrim($route_args[1], '/'));
   }
   if (isset($route_args[2]) {
     $variables['route_info']['arg_2'] = Html::cleanCssIdentifier(ltrim($route_args[2], '/'));
   }
   // etc.
 }

Then add it to your html.html.twig template:

{%
  set body_classes = [
    route_info.args ? 'route--' ~ route_info.args,
    route_info.arg_1 ? 'route--' ~ route_info.arg_1,
    route_info.arg_2 ? 'route--' ~ route_info.arg_2,
  ]
%}

Hopefully others find this useful! Visit the Classy theme in your Core theme directory to see how to apply other useful classes to your body tag.