Force Sitecore to always render URLs using targetHostName

You might be surprised to find out that - when rendering absolute links - Sitecore will often look at the current context Request object to work out which hostname, port, scheme etc to use. This may be a little inconvenient if - for example - a production environment has separate internal URLs used to target individual Content Delivery applications; if you are using HTML caching, and an "internal" request is made, you may find these URLs are cached for the general public, at least until the next publish clears the HTML cache! Fortunately, it's fairly easy to customise Sitecore's LinkProvider and LinkBuilder classes to behave in a different manner. Below I've ensured that the context Request object is never used as the source for any of the ingredients necessary for a building a URL - instead, we pull what we need from the <sites> config. Note that I've not used this code "in the wild" yet, so use at your own risk! Also note that you may now need to define things like port number and scheme explicitly within the <sites> config element...

Step 1 - inherit your custom LinkProvider class from Sitecore's:

        namespace RedMoon.Example
        {
            public class LinkProvider : Sitecore.Links.LinkProvider
            {     
                protected override LinkBuilder CreateLinkBuilder(UrlOptions options)
                {
                    return new Providers.LinkBuilder(options);
                }
            }
        }
    

Step 2 - inherit your custom LinkBuilder class from Sitecore's (with custom code pulling information from config):

        namespace RedMoon.Example
        {
            public class LinkBuilder : Sitecore.Links.LinkProvider.LinkBuilder
            {
                public LinkBuilder(UrlOptions options) : base(options)
                {
                }

                protected override string GetServerUrlElement(SiteInfo siteInfo)
                {
                    if (siteInfo == null || !AlwaysIncludeServerUrl)
                    {
                        return string.Empty;
                    }

                    string hostName = GetTargetHostName(siteInfo);
                    if (string.IsNullOrEmpty(hostName))
                    {
                        return string.Empty;
                    }

                    string scheme = siteInfo.Scheme;
                    int port = siteInfo.Port;
           
                    string url = scheme + "://" + hostName;
                    if (port > 0 && port != 80)
                    {
                        return url + ":" + port;
                    }
                    else
                    {
                        return url;
                    }           
                }      
            }
        }
    

Step 3 - patch in your custom LinkProvider:

        <?xml version="1.0" ?>
        <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
            <sitecore>
                <linkmanager>
                    <providers>
                        <add name="sitecore">
                            <patch:attribute name="alwaysIncludeServerUrl">true</patch:attribute>
                            <patch:attribute name="type">RedMoon.Example.Providers.LinkProvider, Redmoon.Example</patch:attribute>
                        </add>
                     </providers>
                 </linkmanager>
            </sitecore>
        </configuration>

 

 


By James at 7 Dec 2015, 21:24 PM


Comments

Post a comment