2

I have one image style on my site that I need to add a cache breaker to.

Ideally I just want to add . '#' . time() to the end of the src URL.

For instance everywhere the large style is shown the src url is currently something like:

/sites/default/files/styles/large/public/image.jpg?itok=kdkdFf

With cachebreaker:

/sites/default/files/styles/large/public/image.jpg?itok=kdkdFf#1398670388

How do I go about doing this? hook_node_alter?

More info:

I set up a test image editor at http://blakedesign.co.nz/editor/ via Chrome uploading an image and then editing it works fine the modified image shows up in the preview.

On Firefox or IE it actually does work but the old unedited image gets redisplayed from memory.

This can be circumvented if a unique cachebreaker is appended to the source url every time the image is viewed.

  • itok=kdkdFf is regenerated per request already, isn't it? What more you need? If you delete cached images, itok will work as cache breaker. If you will not, breaking user's cache will not help anyway. So, why do you think there is any benefit in adding #1398670388 ? – Mołot Apr 28 '14 at 8:24
  • Nope it isn't generated per request. It stays the same after you change the image via the image editor. Adding #1398670388 to the end will break the cache as the source url will be different. Which is what I need. – blakedesign Apr 28 '14 at 8:57
4
  1. Use template_preprocess_field() to set a flag with drupal_static() when a particular style is being used. This function needs to sit in your themes template.php:

    function MYTHEME_preprocess_field(&$variables) {
      // Check field type is an image.
      if($variables['element']['#field_type'] == 'image') {
        // Loop over each image.
        foreach($variables['items'] as $k => $item) {
          // Check the image style is the one we want to append a timestamp to.
          if($variables['element'][$k]['#image_style'] == 'timestamp') {
            // Set a flag to say to modify this URL.
            $append_ts = &drupal_static('append_ts', TRUE);
            $append_ts = TRUE;
          }
        }
      }
    }
    
  2. Then we can use hook_file_url_alter() to modify the URL if the flag is set. This function can live in your themes template.php or a custom module.

    function MYMODULE_OR_MYTHEME_file_url_alter(&$uri) {
      // Fetch our flag we set in bartik_preprocess_field.
      $append_ts = &drupal_static('append_ts', FALSE);
      // Fetch an array of URI's that this function has already processed.
      $processed_uris = &drupal_static(__FUNCTION__, array());
      // If the flag is true and we've not already processed this URI...
      if ($append_ts && !in_array($uri, $processed_uris)) {
        // Add this URI to our processed list.
        $processed_uris[] = $uri;
        // Set flag to false so we only edit this URL.
        $append_ts = FALSE;
        // And finally create the new URL with a timestamp.
        $uri = file_create_url($uri) . '?t=' . time();
      }
    }
    

The use of the flag in this instance is necessary as we can't check what style the image is using in hook_file_url_alter(), but it is possible in template_preprocess_field().


To append a timestamp to the image on the edit node page

  1. Use hook_theme_registry_alter() to add a preprocess function to the image_widget:

    function MYMODULE_theme_registry_alter(&$theme_registry) {
      $theme_registry['image_widget']['preprocess functions'][] = 'image_widget_preproccess';
    }
    
  2. In the preprocess load the field instance config settings, and then check them to see which image style is being used. If the correct one then make changes to the markup to add a timestamp:

    function image_widget_preproccess(&$element) {
    
      $entity_type = $element['element']['#entity_type'];
      $field_name = $element['element']['#field_name'];
      $bundle_name = $element['element']['#bundle'];
    
      $field_instance_info = field_info_instance($entity_type, $field_name, $bundle_name);
    
      if($field_instance_info['display']['default']['settings']['image_style'] == 'timestamp' && isset($element['element']['preview']['#markup'])) {
        $element['element']['preview']['#markup'] = str_replace('?itok', '?t='.time().'&itok', $element['element']['preview']['#markup']);
      }
    
    }
    
  • This works perfectly for node view. Is there a way to change the preview image while in the node create form that is set as the timestamp style too. Like the one here:blakedesign.co.nz/editor After a user uploads an image or changes it via the pixlr image editor. – blakedesign Apr 28 '14 at 11:08
  • I've updated my answer with info on how to append a timestamp to the node edit page. – Felix Eve Apr 28 '14 at 13:20
  • This works great if the image is altered a new one shows up on IE and FF now but comes up with the error: Notice: Undefined index: preview in image_widget_preproccess() I put the preprocess function in the bartik template.php. Was that the right place? – blakedesign Apr 28 '14 at 22:10
  • I've updated the image_widget_preproccess function to check that $element['element']['preview']['#markup'] is defined before we update it. I think it should work putting the function in template.php, but personally I would rather put it in a custom module. – Felix Eve Apr 29 '14 at 7:59
  • Oh sweet. I just disabled notice messages for anonymous users. This is much better. – blakedesign May 9 '14 at 1:45

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.