1

I want users to easily modify the layout of a node by selecting options in a 'Layout' field that the node contains. The field is a entityreference field referencing taxonomy terms. (For example, the user can select term 'hide-images' and the body class 'hide-images' will be used in the css to hide images.)

I have found this code that sets the first value of a field as body class. But how can I add all field values (taxonomy terms) as body classes?

/**
 * Implements hook_preprocess_html
 */
function THEME_preprocess_html(&$vars){
  // Check if on an article node page
  if($node = menu_get_object('node') && $node->type == 'article'){
    // Get field values
    if($term = field_get_items('node', $node, 'field_layout')){
      // Add first term value to body class
      $vars['classes_array'][] = drupal_html_class(reset($term));
     }
  }

}

2 Answers 2

3

Instead of reinventing the wheel, you could take a look at Display Suite. DS has this functionality built in.

DS comes with a sub-module (DS extras) that has a feature that allows users to select a style right from the node edit page.

After enabling ds, ds_ui, ds_extras you can enable /admin/structure/ds/list/extras -> Other Tab -> View mode per node to use the feature.

Description of the feature:

Change view modes for individual nodes. A new tab 'Display settings' will appear on the content create form. You can also pass the name of a view mode through the URL, eg node/x?v=full. If you install the Page manager module and override the node view, Page manager will win.

Update: If you still want to do it the way you started, you can just change this bit to use a foreach:

Change:

if($term = field_get_items('node', $node, 'field_layout')){
  $vars['classes_array'][] = drupal_html_class(reset($term));
}

To:

if ($term = field_get_items('node', $node, 'field_layout')) {
  foreach ($term as $item) {
    $vars['classes_array'][] = drupal_html_class($item['taxonomy_term']->name);
  }
}
3
  • Thank you. However, I want to keep the solution light-weight and installing Display Suite would be an overkill in my case.
    – Yuri
    Apr 11, 2015 at 22:45
  • @Yuri - updated to use your existing code Apr 11, 2015 at 23:36
  • Is there an Drupal 8 version of this answer?
    – ponies
    May 15, 2017 at 18:08
1

For D8:

Using template_preprocess_html()

/**
 * Implements template_preprocess_html().
 */
function themename_preprocess_html(&$variables) {
  // CSS Class on the basis of Color Selection.
  $node = \Drupal::request()->attributes->get('node');
  if ($node->getType() == 'article') {
    $node_array = $node->toArray();
    $field_color = reset($node_array['field_color']);
    $color_class = 'color-' . $field_color['color'];
    $variables['attributes']['class'][] = $color_class;
  }
}

Using template_preprocess_page()

/**
 * Implements template_preprocess_page().
 */
function themename_preprocess_page(&$variables) {
  // CSS Class on the basis of Color Selection.
  $node = \Drupal::routeMatch()->getParameter('node');
  if ($node->getType() == 'article') {
    $node_array = $variables['node']->toArray();
    $field_color = reset($node_array['field_color']);
    $color_class = 'color-' . $field_color['color'];
    $variables['attributes']['class'][] = $color_class;
  }
}
1
  • thank you! Do you have any idea how this code would be when using the Group module, using terms of a Group entity? for D8. I'm actually using the groups in Open Social.
    – Yuri
    Mar 8, 2019 at 13:54

Your Answer

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

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