1

We have one caching issues on live site. Actually we keep JS/CSS files in sitecore media library so after every prod deployment when we publish updates JS file we have to press Ctrl+F5 to load latest JS file updates. This is fine for Developers but not for visitors and we can't instruct every visitors to press Ctrl+F5.

<script src="/-/media/common/js/productlisting.js"></script>

To mitigate this issue we are planning to add time-stamp as a query string in src attribute in <script> element as described in below URL

https://css-tricks.com/can-we-prevent-css-caching/

and this looks like need modification in sitecore media pipelines. Any idea how can we do this.

OR

Any other suggestion much appreciated

Thanks

UPDATE 07/17/2017

Below Patch works for me

<mediaProvider>
        <patch:attribute name="type">MyProject.Pipelines.CacheBustingMediaProvider, MyProject</patch:attribute>
</mediaProvider>

I see very strange behavior see screenshot. While debugging I found code between line no. 16 and 34 is not getting executed. You can see when I tried to set debug at line no. 14 it throw exception. finally debug point come to line no. 12 and then directly goes to line no. 36 and goes out. Any idea on this.

enter image description here

1

1 Answer 1

1

If you're looking to continue storing these files in the media library (there are pros and cons to this approach), you'll need to subclass Sitecore.Resources.Media.MediaProvider, override GetMediaUrl(MediaItem item, MediaUrlOptions options), and patch it into your configuration.

The default Media Provider is set in Sitecore.config with <mediaProvider type="Sitecore.Resources.Media.MediaProvider, Sitecore.Kernel" />. You'll want to use a config file to patch this value to your custom MediaProvider class.

In GetMediaUrl(), you have access to the MediaItem object, you have access to the Extension field which you could use to determine if the item is JS/CSS. You'll also need to pull the updated date from the statistics of the Sitecore item.

Finally, you'll want to get the URL that the default MediaProvider returns, and modify that. The following is the basic jist of what I'm suggesting.

public class CacheBustingMediaProvider : Sitecore.Resources.Media.MediaProvider {
    public override string GetMediaUrl(MediaItem item, MediaUrlOptions options)
    {
        var requiredExtensions = new[] {"js", "css"};

        var baseURL = base.GetMediaUrl(item, options);

        if (requiredExtensions.Contains(item.Extension))
        {
            var rawItem = item.Database.GetItem(item.ID);
            var itemTimestamp = (rawItem.Statistics.Updated.Ticks - 621355968000000000) / 10000000;
            var urlComponents = baseURL.Split('?');

            Sitecore.Collections.SafeDictionary<string> queryString;

            if (urlComponents.Length > 1)
            {
                queryString = Sitecore.Web.WebUtil.ParseQueryString(urlComponents[1]);
            }
            else
            {
                queryString = new Sitecore.Collections.SafeDictionary<string>();
            }

            queryString["t"] = itemTimestamp.ToString();

            var finalQueryString = Sitecore.Web.WebUtil.BuildQueryString(queryString, true);

            return urlComponents[0] + "?" + finalQueryString;
        }

        return baseURL;
    }
}

There's another few examples of using a MediaProvider here: https://allthingssitecore.com/2014/03/26/integrating-a-cdn-into-your-sitecore-solution/

12
  • Except; don't use timestamp. Use the revision field; it's a guid that is generated whenever the item updates.
    – Mark Cassidy
    Commented Jul 17, 2017 at 17:21
  • 1
    @MarkCassidy I could see it both ways. I personally think it would be better to use the timestamp to make it easier to debug, since you could easily determine what version you're getting. Commented Jul 17, 2017 at 17:23
  • Sure I will try this. Does below patch will work <sitecore> <mediaLibrary> <mediaProvider type="Myporject.Pipelines.CacheBustingMediaProvider, Myporject" patch:after="Sitecore.Resources.Media.MediaProvider, Sitecore.Kernel"> </mediaProvider> </mediaLibrary> </sitecore>
    – Sukhjeevan
    Commented Jul 17, 2017 at 20:51
  • @Sukhi I believe you want patch:instead, not patch:after Commented Jul 17, 2017 at 22:18
  • Can you please check my update in Post
    – Sukhjeevan
    Commented Jul 18, 2017 at 3:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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