This is a little P.O.C. I worked out a while ago that allowed for the creation of a custom a preview site where a user could tack on a date & time via the QueryString to see what the content would look like on that date. Only requirments were 1. it had to be friendly to people who do not care about and will never log into Sitecore and 2. the link could then be easily shared. 

What’s involved? We’ll create a the code and configs for a HttpRequestProcessor and a GetRendererProcessor as well as a quick helper for us to get the work done!

1: Create a new preview site and add a custom attribute we can use to determine if the pipeline should be run, I called mine isPreviewSite to our SiteDefinition.config. 

<site name=”mypreviewsite” patch:before=”site[@name=’website’]”

                  …

                  isPreviewSite=”true” />

2: Create a helper since this logic will be referenced in multiple places. Our helper PreviewItemResolverHelper simply checks the date and tries to resolve the correct version of an item.

public class PreviewItemResolverHelper

    {

        public Item ResolvePreviewItem(string itemPath)

        {

            var item = Context.Database.GetItem(itemPath, Sitecore.Context.Language);

            var queryStringDate = WebUtil.GetQueryString(“date”);

            if (item != null && !string.IsNullOrWhiteSpace(queryStringDate))

            {

                var previewDate = DateUtil.IsoDateToDateTime(queryStringDate);

                return item.Publishing.GetValidVersion(previewDate, false);

            }

            return item;

        }

    }

So here here are the fun bits!

3: Create a custom HttpRequestProcessor and add it to the httpRequestBegin pipeline. Here we verify that the site is a preview site via the isPreviewSite attribute and also check that the expected QueryString parameter has been supplied. Code and config below:

public class PreviewItemResolver : HttpRequestProcessor

    {

        public override void Process(HttpRequestArgs args)

        {

            Assert.ArgumentNotNull(args, “args”);

            if (System.Convert.ToBoolean(Context.Site.SiteInfo.Properties[“isPreviewSite”] ?? “false”) && 

                !MainUtil.GetBool(Sitecore.Context.Items[“preview::ItemResolved”], false))

            {

                var previewItemResolverHelper = new PreviewItemResolverHelper();

                Sitecore.Context.Item = previewItemResolverHelper.ResolvePreviewItem(args.Url.ItemPath);

                Sitecore.Context.Items[“preview::ItemResolved”] = true;

            }

        }

    }
 <httpRequestBegin>

                <processor type=”Project.Pipelines.HttpRequest.PreviewItemResolver, Melaleuca.Foundation.SitecoreExtensions”

                           patch:after=”*[@type=’Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel’]” />

</httpRequestBegin>

4: Create a custom GetRendererProcessor and added it to the mvc.getRenderer pipeline. As with the PreviewItemResolver we verify that the site is a preview site via the isPreviewSite attribute and also check that the expected QueryString parameter has been supplied. This could be centralized but I chose to leave it here in case the conditions for executing the PreviewItemResolver & GetPreviewItemRenderer might be different. Code and config below:

public class GetPreviewItemRenderer : GetRendererProcessor

    {

        public override void Process(GetRendererArgs args)

        {

            Assert.ArgumentNotNull(args, “args”);

            if (System.Convert.ToBoolean(Context.Site.SiteInfo.Properties[“isPreviewSite”] ?? “false”))

            {

                var previewItemResolverHelper = new PreviewItemResolverHelper();

                args.Rendering.Item = previewItemResolverHelper.ResolvePreviewItem(args.Rendering.Item.Paths.Path);

            }

        }

    }
<mvc.getRenderer>

                <processor type=”Project.Pipelines.GetRenderer.GetPreviewItemRenderer, Melaleuca.Foundation.SitecoreExtensions”      patch:instead=”processor[@type=’Sitecore.Mvc.Pipelines.Response.GetRenderer.GetItemRenderer, Sitecore.Mvc’]” />

</mvc.getRenderer>

5: Build, deploy and test!

I chose to use the form yyyyMMddTHHMMSS (time is optional) for my QueryString date. It just made life a lot easier. You could use any format and handle it in the PreviewItemResolverHelper.


Now we have link we can pass around that lets us look into the future (or past)!

http://mypreviewsite/someurl?date=20200929

http://mypreviewsite/someurl?date=20200929T050000