0

I am trying to implement a custom banner with some text written on it.

  • I have created a custom content type called banner with 2 fields: an image field and a text field.
  • Then I process the image field through ImageCache actions in order to apply a watermark on a photo. (fine till now)

I want to use this image (the output of imagecache_actions) as a background image of a node, so that I can apply the text on top of it.

So now node is something like the following.

<div class="node" >
    <img src="" /> 
    <div class=text> blabla </div> 
</div>

I want to change it to the following.

<div class="node" style="background: //use processed field by imagecache actions">
    <div class=text> blabla </div>
</div>

Seen from a different perspective, if I could dynamically overlay some text on top of the image, then that would also do the trick!

Can you suggest any idea?

4 Answers 4

3

I would create some dynamic CSS on the fly and add it to the head of the document.

$styled_image_path = image_style_url('style_name', $image_path);

$css = '
.node {
  background-image: url(' . $styled_image_path . ');
}
';

drupal_add_css($css, array('type' => 'inline'));

You can add this to a hook_preprocess_node() to check for a specific node before adding to the page.

2
  • you are right and thank you. I did exactly that (see my detailed answer below). The trick to add the css class in the $classes is cleaner than what I did, also, but it works fine, ok! Jun 5, 2013 at 13:34
  • Note that this will only work when you have only one node page (i.e. a listing of teasers would display them with the same background)
    – Pere
    Sep 9, 2014 at 10:57
0

I don't know the "proper" way to do it now, but the problem was seen by W3C.

There is a draft of CSS Variables processed right now. If they'll kick in, you will be able to write static CSS files like that:

background-image: url(var(node-image));

Then in your theme code just output:

<style>
  :root {
    node-image: <?php echo $image_path;?>
  }
</style>

Warning: this technology is experimental now, at the date of posting.

2
  • ok, but is it fine to blend CSS with logic? although I get the point and thank you for informing Jun 5, 2013 at 13:36
  • @VagelisKostopoulos As far as I understand, it was designed to allow keeping declarations like "here is a background" in static CSS files, and put only things that really change into the html document itself. It's way better in terms of separation than outputting whole style="background: ..." inline. And a tiny bit better than dynamically created inline styles in head - I mean, one need to do it anyway, but this way minimizes information that's outside static world. If one wants to make styles depend on content, there will always be some point these spheres needs to touch.
    – Mołot
    Jun 5, 2013 at 13:43
0

I managed to do it. Some general knowledge: When uploading an image for an image field, then we can access our image through

/sites/all/themes/MYTHEME/img/MYPIC.jpg 

(let's assume that in my active theme's directory we have created a folder named "img" and put our images inside it)

Then, ImageCache Actions takes the image from the url and performs it's magic on that image. So comes the question: Where to access the styled-by-ImageCache-Actions image? By using Firebug on an end-result image we see that it's path resembles the following:

/sites/default/files/styles/public/files/images/MYPIC.jpg?itok=FEqqXOKA

Here is what I did:

  • In my active theme's directory I opened my template.php (if it doesn't exist we have to create it and write: <?php on the top - and it's good practice to not close the php tag in the end)
  • I paste this code with explanations (notes: my theme is called: "awesome", the custom image field in my content type has a machine name: "field_banner_photo" :

    // preprocess function is used to prepare variables for node.tpl.php
    function awesome_preprocess_node(&$variables) {
    
      // we check if our node has a field_banner_photo filled with an image. This
      // will immediately exlude content types without this field
      if (!empty($variables['node']->field_banner_photo['und'][0]['uri'])) {
    
        // we store the image path of our field_banner_photo into $org_img_url
        $org_img_url = $variables['node']->field_banner_photo['und'][0]['uri'];
    
        // we create $imgcache_url which will be used in node--banner.tpl.php
        // using function image_style_url, the path to the altered (processed by
        // ImageCache Actions) is exposed and stored into $imgcache_url 
        $variables['imgcache_url'] = image_style_url("banner", $org_img_url);
      }
    } 
    
  • I create a node--banner.tpl.php in my active theme to specifically target my custom content type with the machine name: 'banner'. I fill it with the contents of /modules/node/node.tpl.php
  • In the place of

    <div id="node-<?php print $node->nid; ?>" class="<?php print $classes; ?>
    clearfix"<?php print $attributes; ?>>
    

    I put

    <div style="background:url('<?php print $imgcache_url; ?>') left top no-repeat;" 
    id="node-<?php print $node->nid; ?>" class="<?php print $classes; ?> 
    banner clearfix"<?php print $attributes; ?>>
    
  • Then I go to manage display for my custom content type and hide the field_banner_photo. So I achieve to just use the image provided - after ImageCache Actions does it's magic on it - applied as a background on the node!

And that's it! Thank you Drupal and ImageCache Actions for these amazing possibilities we have, almost out of the box!

0

If you use Field Group and Display Suite, check Field Group Background Image module. In your content type Manage Display page:

Create a div (background image) field group to wrap the whole node, and then select the image field you want to use. It allows specifying an image style too.

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.