Insights

Sitecore and Cloudflare: Creating a Pipeline to Purge Cache on Publish

Master the process of building a Sitecore-Cloudflare pipeline to purge cache on publish for fast and efficient content updates.

Introduction

This post will guide you in creating a pipeline to purge your Cloudflare cache when publishing an item. With the pipeline, there is no need to manually purge the cache every time a change is authored.

Prerequisites

Please read my previous guide on purging the cache using C#.

Next, you will need to create a new project called Website.Foundation.Helpers. You can name it whatever you want.

Create a new pipeline

Create a new .config file inside your App_Config folder (e.g., App_Config/Include/Project) and place the following code inside. I named mine PurgeOnPublish.

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <publish>
        <processor patch:after="*[@type='Sitecore.Publishing.Pipelines.Publish.ProcessQueue, Sitecore.Kernel']" type="Website.Foundation.Helpers.Cloudflare.CloudflarePurge, Website.Foundation.Helpers"/>
      </publish>
    </pipelines>
  </sitecore>
</configuration>

Next, create the classes from my previous blog (just copy and paste them). Create CloudflareCacheHelper, CloudflareFileInfo, and CloudflareResponse

Create the class that the pipeline runs

You will notice in the config file we named it Cloudflare purge, so create a new file named CloudflarePurge.cs that extends PublishProcessor. The following code will purge the cache. Read the comments for more details.

public class CloudflarePurge : PublishProcessor
{

    //process is the function that gets called
    public override void Process(PublishContext context)
    {
        Assert.ArgumentNotNull(context, "context");

        if (context.Aborted)
            return;

        //new helper instance
        CloudflarePurgeHelper cfPurge = new CloudflarePurgeHelper();

        //Fetches list of processed items (Created/Updated/Deleted) 
        var processedItems = context.ProcessedPublishingCandidates.Keys.Select(x => context.PublishOptions.TargetDatabase.GetItem(x.ItemId)).Where(y => y != null);

        //Create a list of links to purge
        List<string> linksToPurge = new List<string>();

        //Loop through each item
        foreach(var item in processedItems)
        {
            //if the item has a layout, it means it is an actual webpage.
            //You can add more checks here to see if it is part of your content tree
            if (HasLayout(item))
            {
                //The following code is just to get the full link of the item
                var siteContext = ResolveSiteContext(item);

                var options = LinkManager.GetDefaultUrlOptions();
                options.AlwaysIncludeServerUrl = true;
                options.SiteResolving = true;

                if(siteContext != null)
                {
                    options.Site = siteContext;
                }

                string link = LinkManager.GetItemUrl(item, options);

                //add the link to the list
                linksToPurge.Add(link);

            }
            //if the item isn't an actual webpage, just skip it
        }

        //send links to the purge function you already created
        if(linksToPurge.Count > 0)
        {
            //you can use this bool for your own purposes, or just leave it alone
            bool success = cfPurge.Purge(linksToPurge);
        }
    }

    private bool HasLayout(Item item)
    {
            return item.Visualization.Layout != null;
    }

    private SiteContext ResolveSiteContext(Item item)
    {
        string siteName = null;
        // loop through all configured sites
        foreach (var site in Sitecore.Configuration.Factory.GetSiteInfoList())
        {
            // get this site's home page item
            var sitePath = (site.RootPath + site.StartItem).ToLower();
            var itemPath = item.Paths.FullPath.ToLower();

            if (!String.IsNullOrWhiteSpace(sitePath) && itemPath.Contains(sitePath))
            {
                siteName = site.Name;
                break;
            }
        }
        return siteName == null ? null : SiteContext.GetSite(siteName);
    }
}

Conclusion

Cloudflare is an amazing service that makes defending and speeding your website easy. However, it can be annoying to have to manually purge the page after the smallest change. Hopefully, this blog can help alleviate some of your frustrations and speed up your workflow. Thanks for reading!!



👋 Hey Sitecore Enthusiasts!

Sign up to our bi-weekly newsletter for a bite-sized curation of valuable insight from the Sitecore community.

What’s in it for you?

  • Stay up-to-date with the latest Sitecore news
  • New to Sitecore? Learn tips and tricks to help you navigate this powerful tool
  • Sitecore pro? Expand your skill set and discover troubleshooting tips
  • Browse open careers and opportunities
  • Get a chance to be featured in upcoming editions
  • Learn our secret handshake
  • And more!
Sitecore Snack a newsletter by Fishtank Consulting
 

Meet Gorman Law

Full Stack Developer

🏋️🎸🏈

Gorman is a Full Stack Developer and a University of Calgary alumni who has a background in Canada's financial industry. Outside of work, he likes to go rock climbing, try out new ice cream places, and watch sports.

Connect with Gorman