Thursday, October 4, 2012

Edit Macros that are Cached in Umbraco

One of the really annoying problems in Umbraco is that is when editing Macro Scripting Files for Macros that are cached your changes will not appear until the cache expires and is rebuilt.  To get around this you have to go and turn off caching on the macro that you are working on and then remember to turn it back on when done.

A much nicer solution to this problem is simply to clear out the cached versions of the macro whenever its script file is saved.  In this way the new version of the macro will always be displayed when refreshing the page after any changes.  This code can be added to the App_Code directory of an umbraco install to do jus that.

ClearMacroCache.cs
using System.Web;
using umbraco.BusinessLogic;
using umbraco.IO;
using System.IO;
using System.Web.Hosting;
using ClientDependency.Core.Config;
using System.Text.RegularExpressions;
using System.Linq;
using umbraco.cms.businesslogic.macro;
using umbraco.cms.businesslogic.cache;

namespace JSP
{
    public class ClearMacroCache : ApplicationBase
    {
        public ClearMacroCache()
        {
            // Get the macro folder.
            var macroPath = HttpContext.Current.Server.MapPath(SystemDirectories.MacroScripts);

            // Watch for file changes ot any macros.
            HttpContext.Current.Application.Add("macroWatcher", new FileSystemWatcher(macroPath));
            var macroFsw = (FileSystemWatcher)HttpContext.Current.Application["macroWatcher"];
            macroFsw.EnableRaisingEvents = true;
            macroFsw.IncludeSubdirectories = true;

            // Trigger an event on any change.
            macroFsw.Changed += new FileSystemEventHandler(expireClientDependency);
            macroFsw.Created += new FileSystemEventHandler(expireClientDependency);
            macroFsw.Deleted += new FileSystemEventHandler(expireClientDependency);
        }

        /// <summary>
        /// This method is called each time a macro file is saved/updated and will clear out and cached versions 
        ///     of the macro to eliminate cacheing problems when developing macros.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void expireClientDependency(object sender, FileSystemEventArgs e)
        {
            // If this is a real macro file.
            Regex reg = new Regex(@"\d+_");
            if(!reg.Match(e.Name).Success)
            {
                var macro = Macro.GetAll().SingleOrDefault(i => i.ScriptingFile.ToLower() == e.Name.ToLower());

                if (macro != null)
                    Cache.ClearCacheByKeySearch("macroHtml_" + macro.Alias);
            }
        }
    }
}

No comments: