0

I am trying to change the header background image of my website based on the current node. I have added an image field to my content type, field_hero_image, and, in preprocess function mytheme_preprocess_page(&$variables), I get the image url and try to inject it in the page, as inline css:

function mytheme_preprocess_page(&$variables) {

    $node = $variables['node'];
    if ($node) {
           $path = file_create_url($node->field_hero_image->entity->getFileUri());
            $variables['page']['#attached']['css'] = array(
                'data' => '.header-wrapper { background:url(' . $path . ') center center no-repeat !important; background-size: cover;}',
                'type' => 'inline',
            );
    }
}

or

function mytheme_preprocess_page(&$variables) {

    $node = $variables['node'];
    if ($node) {
           $path = file_create_url($node->field_hero_image->entity->getFileUri());
           $variables['#attached']['library'][] = array(
            'data' => '.header-wrapper { background:url(' . $path . ') center center no-repeat !important; background-size: cover;}',
            'type' => 'inline',
        );
    }
}

None of this works.

Is there a way to inject css from the preprocess function? I know that I can get the path value, put it in $variables and use it in twig. But this doesn't seem a clean solution to me.

  • Looks like this is no possible yet, see Drupal Core Issue: Add support for inline JS/CSS with #attached – No Sssweat Feb 17 '17 at 13:59
  • You could create a view, and add hero image as a field. Then use CSS to make a BG, using the z-index property, ie: z-index: -10; – No Sssweat Feb 17 '17 at 14:02
  • 1
    Thank you! I think that this is a solution, besides adding inline css in page.htm.twig file, with image url coming from a variable. I was just looking for the "right way" to do the thing. – Oana Hulpoi Feb 17 '17 at 14:10
  • You can add inline CSS, you simply have to output it as a raw html_head tag. See drupal.org/docs/8/creating-custom-modules/… – Berdir Feb 18 '17 at 10:13
0

You can make a different templete and use, for example, a class and load the different img by css is one of many possible soluctions, I think that is the best practice

You can read more about Drupal 8 Temple in these threads:

https://www.drupal.org/docs/8/theming

https://www.drupal.org/docs/8/theming/twig

Example aplications

function YOURTHEMENAME_preprocess_node(&$variables) {
  if ($variables['node']) {
    $node = $variables['node'];
    switch ( $node->nid ) {
    case 'nid1':  // Replace nid1 etc with your nid
    case 'nid2':
      break;
    }
  }
}

Template/node/node--full--[nid]

    <div class="img--hero--image">
    </div>

Other solutions it is use a field in the content type and use this field to render in your background.

  • My question was related to your 'other solution'. I have already a field on that content type and the background image should be dynamic. I cannot use multiple node templates, as you wrote, as I don't have any predefined images for any node id. The image should come from the field value (user related content). – Oana Hulpoi Feb 17 '17 at 14:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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