11

Probably coming at this from too much of a Drupal 6 view point but...

How do I theme an image in a given image style when that image lives in a module folder? This is driving me batty and I know I'm just missing something simple.

Here is some example code showing what I'm trying to do:

$file_uri = 'public://sites/all/modules/my_module/logo.jpg';
$data['logo'] = theme('image_style', array('style_name' => 'medium', 'path' => $file_uri));

Even if I use file_build_uri(), I end up with a path to a file that doesn't exist. If I move the image to the files directory and change the $file_uri to 'public://logo.jpg', it works just fine.

Do I need to copy the image to the files directory as part of the module code? If so, isn't this ridiculous?

What am I missing? Is there documentation on how to do something like this? I've spent over an hour mining the Drupal documentation and came up completely dry.

  • public://sites/all/modules/my_module/logo.jpg effectively translates to sites/default/files/sites/all/modules/my_module/logo.jpg - which is why the above doesn't work. Guess the question I have is, how do I avoid copying the file just to run it through theme_image_style? – PrairieHippo Apr 22 '13 at 16:32
4

Unfortunately that's by design. From the theme_image_style() docs' description of the acceptable parameters:

path: The path of the image file relative to the Drupal files directory. This function does not work with images outside the files directory nor with remotely hosted images. This should be in a format such as 'images/image.jpg', or using a stream wrapper such as 'public://images/image.jpg'.

Emphasis mine.

It seems the image style system only works in the context of the public files directory (maybe private too, I'm not sure).

I ran into a similar situation recently and ended up having to code it myself (although I borrowed a lot from the core image module).

  • Thanks - really wish it didn't work this way but I suppose I can reason out why the developers chose this approach. – PrairieHippo Apr 22 '13 at 22:43
9

I just came across this and had to write the code to handle this.

This effectively clones theme_image_style() to create image derivatives during execution of the page request. Generation bypasses the security issues that would otherwise normally trigger a 404, but that also means a slower page the first time the page is visited.

I am only using the public file schema, but I would expect this to fail with the private file schema based styles.

    /**
     * Implements hook_theme().
     */
    function MODULE_theme() {
      return array(
        'remote_image_style' => array(
          'variables' => array(
            'style_name' => NULL,
            'path' => NULL,
            'width' => NULL,
            'height' => NULL,
            'alt' => '',
            'title' => NULL,
            'attributes' => array(),
          ),
        ),
      );
    }

    /**
     * Returns HTML for an image using a specific image style.
     *
     * Clones theme_image_style() with the additional step of forcing the creation
     * of the derivative to bypass any 404 issues.
     */
    function theme_remote_image_style($variables) {
      // Determine the dimensions of the styled image.
      $dimensions = array(
        'width' => $variables['width'],
        'height' => $variables['height'],
      );
      image_style_transform_dimensions($variables['style_name'], $dimensions);

      $variables['width'] = $dimensions['width'];
      $variables['height'] = $dimensions['height'];

      $image_style_dest_path = image_style_path($variables['style_name'], $variables['path']);
      if (!file_exists($image_style_dest_path)) {
        $style = image_style_load($variables['style_name']);
        image_style_create_derivative($style, $variables['path'], $image_style_dest_path);
      }
      $variables['path'] = file_create_url($image_style_dest_path);
      return theme('image', $variables);
    }
2

theme_image_style() accepts a URI using PHP's stream wrappers and not real paths.

input:// is a PHP's stream wrapper, whereas public://, private:// and temporary:// are Drupal's stream wrappers for representing the sites/default/files, private and temporary folders.

If you definitely need to use an image style with an image found in a module, you might want to check the system_stream_wrapper module which adds the module://, theme://, profile:// and library:// stream wrappers.

Notice: It may be irrelevant to the current question but since it was mentioned in other posts, I would like to also point to the remote_stream_wrapper module which adds support for any URL using http://, https://, or feed://. As mentioned though, these stream wrappers are read-only and cannot perform any writing operations but I believe it could be used with image_style_url() and related functions like theme_image_style().

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.