5

Is there a way to set Media.MediaLinkServerUrl value per sitecore site? basically I would like to use CDN for main website by specifying the cdn domain as MediaLinkServerUrl value but not for one of the other sites in multi-site setup.

Is this possible without writing any custom media link resolver logic?

3

Custom code is necessary to achieve this since you want to generate media urls in different ways based on the context site.

Override the MediaProvider and provide config nodes to determine which sites use CDN urls.

Add a sitecore config patch:

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <hooks>
      <hook type="Project.Web.Hooks.MediaProvider, Project.Web">
        <OriginPrefix>https://projectcdn.blob.core.windows.net/CDN/</OriginPrefix>
        <Sites>Site1|Site2</Sites>
      </hook>
    </hooks>
  </sitecore>
</configuration>

Create a class that inherits from MediaProvider and implements the GetMedia methods to do what you want:

public class MediaProvider : Sitecore.Resources.Media.MediaProvider, IHook
{
    // get the values from the inner config nodes
    public string OriginPrefix { get; set; }
    public string Sites { get; set; }

    public List<string> AllowedSites
    {
        get { return string.IsNullOrEmpty(Sites) ? new List<string>() : Sites.Split('|').Where(x => !string.IsNullOrEmpty(x)).ToList(); }
    }

    public void Initialize()
    {
        MediaManager.Provider = this;
    }

    public override string GetMediaUrl(MediaItem item)
    {
        return GetMediaUrl(base.GetMediaUrl(item), item);
    }

    public override string GetMediaUrl(MediaItem item, MediaUrlOptions options)
    {
        return GetMediaUrl(base.GetMediaUrl(item, options), item);
    }

    public string GetMediaPath(MediaItem mediaItem, string extension = "")
    {
        var str = MainUtil.EncodeName(mediaItem.Name);
        return mediaItem.MediaPath.TrimStart('/').Replace(mediaItem.DisplayName, str + "." + extension).ToLower();
    }

    public string GetMediaUrl(string mediaUrl, MediaItem item)
    {
        if ((Context.Database != null && Context.Database.Name == "core") || string.IsNullOrEmpty(OriginPrefix))
        {
            return mediaUrl;
        }

        if (mediaUrl.ToLower().Contains("-/media/"))
        {
            mediaUrl = OriginPrefix + mediaUrl.Substring(mediaUrl.LastIndexOf("-/media/", StringComparison.Ordinal) + 8, mediaUrl.Length - 8 - mediaUrl.LastIndexOf("-/media/", StringComparison.Ordinal)).ToLower();
        }

        if (mediaUrl.ToLower().Contains("?"))
        {
            mediaUrl = mediaUrl.Split('?')[0];
        }

        // cache busting
        mediaUrl = $"{mediaUrl}?rv={item.InnerItem.Statistics.Revision}";

        return mediaUrl;
    }
}

In this case I'm defining the cdn origin prefix in config as well and using that to construct the media url. The AllowedSites property can be used to determine whether to use the base or custom implementations based on the context site (this is not included in the example).

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.