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
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!
-
Works perfect! And instead of clearing caches, consider disabling caching during development :) Commented Aug 19, 2016 at 20:42
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)}}>
-
1This 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'] 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. Commented Jan 29, 2016 at 16:52
-
1Brilliant. 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! Commented Jan 29, 2016 at 20:35
-
I thought there was a function to make a valid css class from a string in Drupal. :( Commented Jan 29, 2016 at 20:48