4

Am creating my own theme and have successfully added the URL into the node class in node.html.twig with {% set classes = [ 'url' ~ url|clean_class, ] %} but I need to be able to style each page individually as a whole, not just at the node level - how do I add the URL or the taxonomy of the node to the page or body classes?

2 Answers 2

9

The answer provided by mradcliffe was what I needed. One improvement that will yield a css-friendly class name is to use the Twig |clean_class filter. Here is the code:

In MY_THEME.theme

<?php
function MY_THEME_preprocess_html(&$variables) {
  $current_path = \Drupal::service('path.current')->getPath();
  $variables['current_path'] = \Drupal::service('path.alias_manager')->getAliasByPath($current_path);
}
?>

In html.html.twig:

{%
  set body_classes = [
    logged_in ? 'user-logged-in',
    not root_path ? 'path-frontpage' : 'path-' ~ root_path|clean_class,
    node_type ? 'page-node-type-' ~ node_type|clean_class,
    db_offline ? 'db-offline',
    current_path ? 'context' ~ current_path|clean_class,
  ]
%}
<body{{ attributes.addClass(body_classes) }}>

Don't forget to clear your cache!

1
3

You may do something similar in the html.html.twig template, but the full url is not available by default. That means you would need to add a THEMENAME_preprocess_html() to your THEMENAME.theme file. The path.current service provides the current path (similar to current_path(), and the path.alias_manager service will do path/alias lookup (similar to drupal_lookup_path() although there is no change record for this change). Setting it into variables should expose that in the template with which you can add a class to attributes.

my_theme.theme:

function my_theme_preprocess_html(&$variables) {
  $current_path = \Drupal::service('path.current')->getPath();
  $variables['current_path'] = \Drupal::service('path.alias_manager')->getAliasByPath($current_path);
}

templates/html.html.twig:

<body{{attributes.addClass(current_path)}}>
4
  • 1
    This works, thanks! It adds the node ID (e.g, /node/8 - so I can actually call it in CSS as .\/node\/8) - but is there a way to add the path name (pathauto alias)? This would be more intuitive. Incidentally, I needed to add an apostrophe after path in $variables['current_path']
    – Molesworth
    Commented Jan 29, 2016 at 15:14
  • The path.alias_manager service will do a path/alias lookup. I am not certain on performance impact of this though. Thanks for the note on the syntax typo.
    – mradcliffe
    Commented Jan 29, 2016 at 16:52
  • 1
    Brilliant. I tested this a few times with the path.current and path.alias_manager services as well as without either and there seems to be no discernible increase in milliseconds load time. It would be perfect if the slash could be eliminated, or substituted with a css-friendly separator like a hyphen in the event of a subpage such as /abc/xyz. I believe something like this should be readily available in html.html.twig - path and taxonomy for example: it can be critical to be able to target individual pages or categories of pages outside just the node with stylistic variations. Thanks again!
    – Molesworth
    Commented Jan 29, 2016 at 20:35
  • I thought there was a function to make a valid css class from a string in Drupal. :(
    – mradcliffe
    Commented Jan 29, 2016 at 20:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.