2

image_style_url() generates proper links, but sadly it's only a PHP function.

Let's assume I want to substitute file icon with preview image on hover:

(function($) { 
  Drupal.behaviors.ImagePreview = {
    attach: function (context, settings) {

      $('.form-managed-file', context).on('hover', function(){
        $(this).find('img').attr('src', $(this).find('a').attr('href'));
      });


    }
  };
})(jQuery);

Not the smartest code in the world, but simple, works and illustrates my example. Now, it will show image in the resolution user uploaded. But I need a thumbnail. It's a built in style so I don't need to test if it exists, but I do need valid security token and I need to respect all the Drupal file system settings, just like image_style_url() does. How can I achieve this with jQuery?

Note: In my case both input and output need to happen on jQuery side, as the image may not even be on the server when page is rendered.

  • 1
    I don't have time to write this in as an answer, so I'll just leave a comment - but could you use a menu callback and an AJAX request? Or is that out of the scope of your requirements? – Chapabu Sep 9 '13 at 13:48
  • @Chapabu if Drupal does not provide this functionality out of the box, I will have to do just that. But I hope there is built-in function and I simply cannot find it. Either way I think it's worth to have this figured out and posted for future visitors. – Mołot Sep 9 '13 at 13:50
  • 1
    There a pretty good answer here from MPD that should answer your question actually! If not, you should at least be able to modify it :-) – Chapabu Sep 9 '13 at 13:53
  • @Mołot Do you need a single style, or any style? I have another approach for single styles, too. – mpdonadio Sep 9 '13 at 13:54
  • @MPD specifically I need thumbnail style. Or any other one, but I can hard code it all right. – Mołot Sep 9 '13 at 13:55
4

For a single image style, I tack it on as a data attribute to the image. Then in my JS, I use that.

This is how I handle retina images, using src switching (edited to just show the relevant portions):

function MYTHEME_image_style($variables) {
  // ...

  if (in_array($variables['style_name'] . '_2x', array_keys(image_styles())) {
    $variables['data-retina'] = image_style_url($variables['style_name'] . '_2x', $path);
  }

  return theme('image', $variables);
}

/**
 * Implements theme_image().
 */
function MYTHEME_image($variables) {
  // ...

  if (isset($variables['data-retina'])) {
    $attributes['data-retina'] = file_create_url($variables['data-retina']);
  }

  return '<img' . drupal_attributes($attributes) . ' />';
}

This in the JS (again, lifted and edited):

$('img').each(function (i, img) {
  var $img = $(img);

  if ($img.data('retina')) {
    $img.data('src', img.src);
    img.src = $img.data('retina');
  }
});

The key is to generate the style URL on the server side, so that the URL includes the itok and that all hooks get fired to allow modules like CDN to work. You just need to figure out the proper place to do it from. In your case, I suspect you may need to do it from a theme_field.

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.