From d977aff9e20d2314d89d984cb9dfc88cc5da78c8 Mon Sep 17 00:00:00 2001
From: ressa <53072-ressa@users.noreply.drupalcode.org>
Date: Tue, 13 May 2025 11:44:28 +0000
Subject: [PATCH 1/5] Add current user roles as classes in body

---
 core/themes/claro/claro.theme     | 13 +++++++++++++
 core/themes/olivero/olivero.theme |  7 +++++++
 core/themes/stable9/stable9.theme | 13 +++++++++++++
 3 files changed, 33 insertions(+)

diff --git a/core/themes/claro/claro.theme b/core/themes/claro/claro.theme
index a031dc860c35..f5e5f0684c12 100644
--- a/core/themes/claro/claro.theme
+++ b/core/themes/claro/claro.theme
@@ -21,6 +21,19 @@
 use Drupal\views\ViewExecutable;
 use Drupal\views_ui\Form\Ajax\ViewsFormInterface;
 
+/**
+ * Implements hook_preprocess_HOOK() for HTML document templates.
+ *
+ * Insert all roles of current user as classes in body field.
+ */
+function claro_preprocess_html(&$variables): void {
+  $current_user = \Drupal::currentUser();
+  $roles = $current_user->getRoles();
+  foreach ($roles as $role) {
+    $variables['attributes']['class'][] = \Drupal\Component\Utility\Html::cleanCssIdentifier($role . '-role');
+  }
+}
+
 /**
  * Implements hook_theme_suggestions_HOOK_alter() for form_element.
  */
diff --git a/core/themes/olivero/olivero.theme b/core/themes/olivero/olivero.theme
index b2f3bff26841..5f56deb63e8b 100644
--- a/core/themes/olivero/olivero.theme
+++ b/core/themes/olivero/olivero.theme
@@ -45,6 +45,13 @@ function olivero_preprocess_html(&$variables): void {
       'href' => $variables['olivero_path'] . '/css/components/navigation/nav-primary-no-js.css?' . $query_string,
     ],
   ];
+
+  // Insert all roles of current user as classes in body field.
+  $current_user = \Drupal::currentUser();
+  $roles = $current_user->getRoles();
+  foreach ($roles as $role) {
+    $variables['attributes']['class'][] = \Drupal\Component\Utility\Html::cleanCssIdentifier($role . '-role');
+  }
 }
 
 /**
diff --git a/core/themes/stable9/stable9.theme b/core/themes/stable9/stable9.theme
index c40f668b15c5..73188a5b02e5 100644
--- a/core/themes/stable9/stable9.theme
+++ b/core/themes/stable9/stable9.theme
@@ -5,6 +5,19 @@
  * Functions to support theming in the Stable9 theme.
  */
 
+/**
+ * Implements hook_preprocess_HOOK() for HTML document templates.
+ *
+ * Insert all roles of current user as classes in body field.
+ */
+function stable9_preprocess_html(&$variables): void {
+  $current_user = \Drupal::currentUser();
+  $roles = $current_user->getRoles();
+  foreach ($roles as $role) {
+    $variables['attributes']['class'][] = \Drupal\Component\Utility\Html::cleanCssIdentifier($role . '-role');
+  }
+}
+
 /**
  * Implements hook_preprocess_item_list__search_results().
  *
-- 
GitLab


From ccf9d024b9f1bdfd438786b83f78b4654bf2379f Mon Sep 17 00:00:00 2001
From: ressa <53072-ressa@users.noreply.drupalcode.org>
Date: Tue, 13 May 2025 11:52:30 +0000
Subject: [PATCH 2/5] Fix code standard

---
 core/themes/claro/claro.theme     | 2 +-
 core/themes/olivero/olivero.theme | 2 +-
 core/themes/stable9/stable9.theme | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/core/themes/claro/claro.theme b/core/themes/claro/claro.theme
index f5e5f0684c12..ccbed5af09ac 100644
--- a/core/themes/claro/claro.theme
+++ b/core/themes/claro/claro.theme
@@ -30,7 +30,7 @@ function claro_preprocess_html(&$variables): void {
   $current_user = \Drupal::currentUser();
   $roles = $current_user->getRoles();
   foreach ($roles as $role) {
-    $variables['attributes']['class'][] = \Drupal\Component\Utility\Html::cleanCssIdentifier($role . '-role');
+    $variables['attributes']['class'][] = Html::cleanCssIdentifier($role . '-role');
   }
 }
 
diff --git a/core/themes/olivero/olivero.theme b/core/themes/olivero/olivero.theme
index 5f56deb63e8b..87487e62fac9 100644
--- a/core/themes/olivero/olivero.theme
+++ b/core/themes/olivero/olivero.theme
@@ -50,7 +50,7 @@ function olivero_preprocess_html(&$variables): void {
   $current_user = \Drupal::currentUser();
   $roles = $current_user->getRoles();
   foreach ($roles as $role) {
-    $variables['attributes']['class'][] = \Drupal\Component\Utility\Html::cleanCssIdentifier($role . '-role');
+    $variables['attributes']['class'][] = Html::cleanCssIdentifier($role . '-role');
   }
 }
 
diff --git a/core/themes/stable9/stable9.theme b/core/themes/stable9/stable9.theme
index 73188a5b02e5..547cd8c1025a 100644
--- a/core/themes/stable9/stable9.theme
+++ b/core/themes/stable9/stable9.theme
@@ -14,7 +14,7 @@ function stable9_preprocess_html(&$variables): void {
   $current_user = \Drupal::currentUser();
   $roles = $current_user->getRoles();
   foreach ($roles as $role) {
-    $variables['attributes']['class'][] = \Drupal\Component\Utility\Html::cleanCssIdentifier($role . '-role');
+    $variables['attributes']['class'][] = Html::cleanCssIdentifier($role . '-role');
   }
 }
 
-- 
GitLab


From 7f609a439aa4e539b357fedd45947d36ffa0a93e Mon Sep 17 00:00:00 2001
From: ressa <53072-ressa@users.noreply.drupalcode.org>
Date: Tue, 13 May 2025 12:04:24 +0000
Subject: [PATCH 3/5] Fix unknown class Html

---
 core/themes/stable9/stable9.theme | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/core/themes/stable9/stable9.theme b/core/themes/stable9/stable9.theme
index 547cd8c1025a..966bb4f69c23 100644
--- a/core/themes/stable9/stable9.theme
+++ b/core/themes/stable9/stable9.theme
@@ -5,6 +5,8 @@
  * Functions to support theming in the Stable9 theme.
  */
 
+use Drupal\Component\Utility\Html;
+
 /**
  * Implements hook_preprocess_HOOK() for HTML document templates.
  *
-- 
GitLab


From 9bf9053c15e99133c22fe29339c0f76c17ff355f Mon Sep 17 00:00:00 2001
From: ressa <53072-ressa@users.noreply.drupalcode.org>
Date: Tue, 13 May 2025 13:18:19 +0000
Subject: [PATCH 4/5] Use template variables and Twig instead

---
 core/modules/user/src/Hook/UserHooks.php          |  6 ++++++
 core/themes/claro/claro.theme                     | 13 -------------
 .../claro/templates/classy/layout/html.html.twig  |  2 ++
 core/themes/olivero/olivero.theme                 |  7 -------
 .../olivero/templates/layout/html.html.twig       |  2 ++
 core/themes/stable9/stable9.theme                 | 15 ---------------
 .../stable9/templates/layout/html.html.twig       |  1 +
 7 files changed, 11 insertions(+), 35 deletions(-)

diff --git a/core/modules/user/src/Hook/UserHooks.php b/core/modules/user/src/Hook/UserHooks.php
index 4ed9f071a223..13b6b5cc51ae 100644
--- a/core/modules/user/src/Hook/UserHooks.php
+++ b/core/modules/user/src/Hook/UserHooks.php
@@ -220,6 +220,12 @@ public function templatePreprocessDefaultVariablesAlter(&$variables): void {
     unset($variables['user']->pass, $variables['user']->sid, $variables['user']->ssid);
     $variables['is_admin'] = $user->hasPermission('access administration pages');
     $variables['logged_in'] = $user->isAuthenticated();
+    $roles = $user->getRoles();
+    $all_roles = '';
+    foreach ($roles as $role) {
+      $all_roles .= Html::cleanCssIdentifier($role) . '-role ';
+    }
+    $variables['roles'] = trim($all_roles);
   }
 
   /**
diff --git a/core/themes/claro/claro.theme b/core/themes/claro/claro.theme
index ccbed5af09ac..a031dc860c35 100644
--- a/core/themes/claro/claro.theme
+++ b/core/themes/claro/claro.theme
@@ -21,19 +21,6 @@
 use Drupal\views\ViewExecutable;
 use Drupal\views_ui\Form\Ajax\ViewsFormInterface;
 
-/**
- * Implements hook_preprocess_HOOK() for HTML document templates.
- *
- * Insert all roles of current user as classes in body field.
- */
-function claro_preprocess_html(&$variables): void {
-  $current_user = \Drupal::currentUser();
-  $roles = $current_user->getRoles();
-  foreach ($roles as $role) {
-    $variables['attributes']['class'][] = Html::cleanCssIdentifier($role . '-role');
-  }
-}
-
 /**
  * Implements hook_theme_suggestions_HOOK_alter() for form_element.
  */
diff --git a/core/themes/claro/templates/classy/layout/html.html.twig b/core/themes/claro/templates/classy/layout/html.html.twig
index 48729c56e057..3a86c870880a 100644
--- a/core/themes/claro/templates/classy/layout/html.html.twig
+++ b/core/themes/claro/templates/classy/layout/html.html.twig
@@ -5,6 +5,7 @@
  *
  * Variables:
  * - logged_in: A flag indicating if user is logged in.
+ * - roles: The roles of the current user.
  * - root_path: The root path of the current page (e.g., node, admin, user).
  * - node_type: The content type for the current node, if the page is a node.
  * - head_title: List of text elements that make up the head_title variable.
@@ -29,6 +30,7 @@
     not root_path ? 'path-frontpage' : 'path-' ~ root_path|clean_class,
     node_type ? 'page-node-type-' ~ node_type|clean_class,
     db_offline ? 'db-offline',
+    roles ? roles,
   ]
 %}
 <!DOCTYPE html>
diff --git a/core/themes/olivero/olivero.theme b/core/themes/olivero/olivero.theme
index 87487e62fac9..b2f3bff26841 100644
--- a/core/themes/olivero/olivero.theme
+++ b/core/themes/olivero/olivero.theme
@@ -45,13 +45,6 @@ function olivero_preprocess_html(&$variables): void {
       'href' => $variables['olivero_path'] . '/css/components/navigation/nav-primary-no-js.css?' . $query_string,
     ],
   ];
-
-  // Insert all roles of current user as classes in body field.
-  $current_user = \Drupal::currentUser();
-  $roles = $current_user->getRoles();
-  foreach ($roles as $role) {
-    $variables['attributes']['class'][] = Html::cleanCssIdentifier($role . '-role');
-  }
 }
 
 /**
diff --git a/core/themes/olivero/templates/layout/html.html.twig b/core/themes/olivero/templates/layout/html.html.twig
index 4558ab2a5f0e..d5e0f87fac62 100644
--- a/core/themes/olivero/templates/layout/html.html.twig
+++ b/core/themes/olivero/templates/layout/html.html.twig
@@ -5,6 +5,7 @@
  *
  * Variables:
  * - logged_in: A flag indicating if user is logged in.
+ * - roles: The roles of the current user.
  * - root_path: The root path of the current page (e.g., node, admin, user).
  * - node_type: The content type for the current node, if the page is a node.
  * - head_title: List of text elements that make up the head_title variable.
@@ -31,6 +32,7 @@
     not root_path ? 'path-frontpage' : 'path-' ~ root_path|clean_class,
     node_type ? 'page-node-type-' ~ node_type|clean_class,
     db_offline ? 'db-offline',
+    roles ? roles,
   ]
 %}
 <!DOCTYPE html>
diff --git a/core/themes/stable9/stable9.theme b/core/themes/stable9/stable9.theme
index 966bb4f69c23..c40f668b15c5 100644
--- a/core/themes/stable9/stable9.theme
+++ b/core/themes/stable9/stable9.theme
@@ -5,21 +5,6 @@
  * Functions to support theming in the Stable9 theme.
  */
 
-use Drupal\Component\Utility\Html;
-
-/**
- * Implements hook_preprocess_HOOK() for HTML document templates.
- *
- * Insert all roles of current user as classes in body field.
- */
-function stable9_preprocess_html(&$variables): void {
-  $current_user = \Drupal::currentUser();
-  $roles = $current_user->getRoles();
-  foreach ($roles as $role) {
-    $variables['attributes']['class'][] = Html::cleanCssIdentifier($role . '-role');
-  }
-}
-
 /**
  * Implements hook_preprocess_item_list__search_results().
  *
diff --git a/core/themes/stable9/templates/layout/html.html.twig b/core/themes/stable9/templates/layout/html.html.twig
index 0180ed85d9e3..2fed64773822 100644
--- a/core/themes/stable9/templates/layout/html.html.twig
+++ b/core/themes/stable9/templates/layout/html.html.twig
@@ -5,6 +5,7 @@
  *
  * Variables:
  * - logged_in: A flag indicating if user is logged in.
+ * - roles: The roles of the current user.
  * - root_path: The root path of the current page (e.g., node, admin, user).
  * - node_type: The content type for the current node, if the page is a node.
  * - head_title: List of text elements that make up the head_title variable.
-- 
GitLab


From 98f792e10be3f7321850625fec072e091fe2c8d1 Mon Sep 17 00:00:00 2001
From: ressa <53072-ressa@users.noreply.drupalcode.org>
Date: Tue, 13 May 2025 13:23:21 +0000
Subject: [PATCH 5/5] Add Html utility

---
 core/modules/user/src/Hook/UserHooks.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/core/modules/user/src/Hook/UserHooks.php b/core/modules/user/src/Hook/UserHooks.php
index 13b6b5cc51ae..65a533d2a2a2 100644
--- a/core/modules/user/src/Hook/UserHooks.php
+++ b/core/modules/user/src/Hook/UserHooks.php
@@ -10,6 +10,7 @@
 use Drupal\Component\Assertion\Inspector;
 use Drupal\user\RoleInterface;
 use Drupal\Component\Render\PlainTextOutput;
+use Drupal\Component\Utility\Html;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\image\Plugin\Field\FieldType\ImageItem;
 use Drupal\Core\Render\Element;
-- 
GitLab