1

I have two fields in my view:

field_background_colour and field_heading

The are both being pulled from nodes and displayed in a rotating hero banner. Each node has a different colour and different heading.

The field_background_colour is defined by the color field module and therefore can be any colour they select.

I need to add the value of the background colour in hex (e.g. #000000) to the html output of field_heading.

<div style="background:[field_background_colour];">[field_heading]</div>

I tried using some html and replacement patterns in the rewrite of the field but it seems that gets stripped out by views. It seems to me that I need to use the field's template file to get what I want.

5
  • If this is a view title you are trying to style, where does the color field live? I would guess maybe the user profile or somewhere there are not multiple instances like node? Commented Jan 27, 2019 at 2:02
  • I agree inline styles are the best route in this use case all things considered (been there). Commented Jan 27, 2019 at 2:03
  • Is it the actual view title you are trying to style, or the title of each node being shown in the view? Commented Jan 27, 2019 at 2:03
  • The the heading and the colour field are both on the node. I am using a view with a fields to display them in a rotating hero banner Commented Jan 27, 2019 at 15:50
  • If the token [field_background_colour] is not working in your view, it could just be a formatting issue for that field. Inspect the element and how it is actually being printed in the DOM. Commented Jan 27, 2019 at 17:58

6 Answers 6

4
+100

In this use case, I believe inline styles are the way to go. There are methods to write a CSS file in your module or theme, for example, but since users can select, and update at any time, any color code, all situations would be very difficult or messy to manage. Inline styles are not ideal in the grand scope of things, but with multiple users, and multiple hex values reaching the millions, sometimes requirements make our choices for us. And plus, we just want to get it done.


Below assumes the view shows nodes, both fields are on the content type, and the title being styled is the node title, not the views title. This is best achieved setting the view to display content, and utilizing template files for your chosen display mode such as node--content-type--teaser.tpl.php.

node--content-type--rotating-hero.tpl.php:

<section>
  <h1 
    title="<?php print render($title); ?>" 
    alt="<?php print render($title); ?>"
    <?php if (isset($content['field_background_colour'])) : ?>
      style="color: #<?php print $content['field_background_colour']['#items'][0]['value']; ?>;"
    <?php endif; ?>
  >
    <?php print render($title); ?>
  </h1>
</section>

Here, each .views-row will contain an individual node display, and you can focus your javascript and CSS on those for the slider.

*multiple h1 tags on the same page need to be wrapped in a <section> tag, otherwise, use h2 tags.

*Templates are related to structure and usage. Views templates are for the structure and layout of content aggregation, node templates are the structure of individual entities. Wherever the field (or desired data) resides is the best place to theme template files.


Below assumes you need to style the views title itself...

will need more info about where the color field lives. If user profile, for example, you will need to load the user object to access the field value.

MYMODULE.module:

function MYMODULE_views_pre_render(&$view) {
  if ($view->name == 'view_name') {
    $view->build_info['title'] = "custom title";
  }
}

template.php:

function MYTHEME_views_pre_render(&$variables) {
  if (&$variables['view']->name == 'view_name') {
    &$variables['view']->build_info['title'] = "custom title";
  }
}
3
  • The background colour and heading are both on the node itself. All of the nodes are displayed in a rotating hero banner using fields display in views Commented Jan 27, 2019 at 15:44
  • It is possible to theme views type template files, however, I still recommend theming the node type template files. It will be more versatile and compatible for the future. I also think people spend a lot more time theming node templates than views templates, so will be easier to find help. You could even create a view mode named rotating hero and gain a lot of control over the display. Just set the view to display content instead of fields. Commented Jan 27, 2019 at 17:06
  • node—content-type—rotating-hero.tpl.php Commented Jan 27, 2019 at 17:07
1

Aren't you actually just trying to style one of the fields according to the value of the other field?

Inline CSS isn't the best way to go because of a number of reasons, mainly, it can't be easily overriden so it breaks the cascade, and maintenance is a nightmare.

There is a way to style your views rows based on field values: You add a class to your Heading field Style settings that is based on the bg-color field value. Using classes to mark up content and then style the classes with CSS is the way to go.

You need to add the CSS rules applied to the classes to your (sub)theme. Some themes provide the interface to add your custom CSS, if not you can use the CSS Editor or a similar module.

Here are the steps:

  1. Position the bg-color field above the Heading field (good if it's Hidden). If you need it visible in some other order then add a second bg-color field just for this purpose and position it above the Heading field
  2. Edit the Heading field > Uncollapse Style settings > Customize field and label wrapper HTML (or Customize field HTML if you don't need the wrapper) > Create a CSS class and enter the first part of your class (heading) (class names can't start with numbers so that's why)
  3. Uncollapse Rewrite results (don't enable it, you just need to look up the token), uncollapse Replacement patterns, copy the bg-color field token and paste it in the above CSS class field (you end up with something like heading-[field_bg_color]).
  4. Save the View and check your HTML output, you will see a class based on the color field on your Heading, something like class="views-field views-field-title heading-008000". The hash sign has been stripped automatically as it can break CSS.
  5. Add the CSS to your (sub)theme or the CSS Editor, for all the colors you have in your content:
.heading-008000 {
  background-color: #008000;
}

With Sass you can use a list to store all your colors and create the rules automatically.

If this is just a way to allow content editors to choose some preset styles try looking into Paragraphs and Bricks (D8).

4
  • The challenge is that the user defines the colour using the colour field module, so it can literally be any colour they choose. I cannot define every colour in css so I need to do this via the field template. Commented Jan 23, 2019 at 23:51
  • Branding nightmare :| I hope it's a legitimate case though. Yes, you'll need to go through views templates, probably with a preprocess to have the color value available in heading field template.
    – prkos
    Commented Jan 24, 2019 at 0:02
  • Indeed it is. Is there any way of using the replacement patterns in views directly in the templates? Commented Jan 24, 2019 at 0:22
  • I'm really not the expert, but maybe if you use the token CSS the way I described, or in some similar way you'd get the color field value into the Heading field object, then maybe you could manipulate it in views-view-fields.tpl.php for the Heading field (more specific title, you have suggestions within Views). Usually templates are used to output variables, not to store logic, logic is usually kept in modules or in template.php in your theme.
    – prkos
    Commented Jan 24, 2019 at 3:42
1

You can simply use template_preprocess_views_view_fields to rewrite content of the field, and wrap it inside another div with the markup.

like the following:

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function YourTheme_preprocess_views_view_fields(&$vars) {
  $view = $vars['view'];
  foreach ($view->field as $id => $field) {
    if ($id == 'field_background_colour') {
      $content = $vars['fields']['field_heading']->content;
      $background_colour = trim(strip_tags($vars['fields']['field_background_colour']->content));
      $vars['fields']['field_heading']->content = '<div style="background:' . $background_colour . '">' . $content . '</div>';
    }
  }
}

Result: enter image description here

0

You can use twig file and wrap your div code around {{output}}

    <div style="background-color: #{{ view.field.field_color.original_value }}">
    {{ output -}}
    </div>

Twig File: views-view-field--{page or block machine name}--{field name}.html.twig

Example: views-view-field--frontpage--field-color.html.twig

Note: You can access any field value from any views-view-field--{field name} by using {{ view.field.{field name}.original_value }}

4
  • Thanks for the answer but this question is for Drupal 7 and is tagged as such. Do you know how to do this in 7? Commented Jan 26, 2019 at 19:02
  • you can do on views-view-field--field-color.tpl.php and add as print $ view['field'][field_color']['original_value']
    – O-nur
    Commented Jan 26, 2019 at 19:39
  • Wouldn't I need this to be done in the field-heading.tpl? Commented Jan 26, 2019 at 19:53
  • Unfortunately, I don't have Drupal 7 installed. You need to test and see. My first suggestion was from Drupal 8 guidelines. Latter is from Drupal 7 guidelines.
    – O-nur
    Commented Jan 26, 2019 at 22:33
0

It's very simple, i added a working example, no need for template, first add colour_field:[field_background_colour], hide from display, then add field:[field_heading], in field settings do choose rewrite results (toggle checkbox), add this in input box:

<div class="background:#[field_background_colour]">[field_heading]</div>

or

<div class="background-color:#[field_background_colour]">[field_heading]</div>

[field_background_colour] field must be before of [field_heading] in your list of fields in view settings.

Supouse that [field_background_colour-value] is #000000, HTML output will be:

<div style="background:#000000">[field_heading-value]</div>

or

<div style="background-color:#000000">[field_heading-value]</div>

please see my WORKING sample settings, HTML output and CSS:

enter image description here

enter image description here

HTML

enter image description here

css

enter image description here

4
  • This would require pre-defining colours and with using the colour field module, the colour can be anything the user wants. Commented Jan 27, 2019 at 15:49
  • no, it does not require pre-defining colours, because you are using them as background, i publish my example, just to demostrate that this method works, indeed my example do require pre-defining colours, yours not. please try my solution.
    – pinueve
    Commented Jan 27, 2019 at 16:50
  • 1
    How does the <div class="background-color:# get converted to <div style="background-color:# Commented Jan 27, 2019 at 20:28
  • yes, my mistake, what i posted i did not tryed with color field module, then i play arround trying to make it work, cleaning tags, ... indeed, it needs a function with this module, my posted answers works, not with this module, it may be helpfull in some other cases.
    – pinueve
    Commented Jan 28, 2019 at 5:55
0
  1. Use the views_html_tags module to add tag in available HTML tags list.
  2. Add nid (Node ID) to view fields, put it on the top and hide it.
  3. Add class "node-[nid]" to field_heading.
  4. Add field 'field_background_color' to view fields and place it between 'nid' and 'field_heading' fields. Don't hide it.
  5. Rewrite it's output to: .node-[nid] { background-color: [field_background_color]; }

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.