From 6f00df4c85326a87286e22e3eb6e8b03d455bb1b Mon Sep 17 00:00:00 2001 From: Elijah Date: Tue, 18 Jan 2011 06:14:06 -1000 Subject: [PATCH] Updated Razor To Use System.Web.Complication.BuildManager --- .../DynamicNodeContext.cs | 24 +++ umbraco.MacroEngines.Juno/IMacroContext.cs | 8 + .../ParameterDictionary.cs | 35 ++++ umbraco.MacroEngines.Juno/RazorEngine.cs | 184 +++++------------- .../umbraco.MacroEngines.csproj | 11 +- 5 files changed, 125 insertions(+), 137 deletions(-) create mode 100644 umbraco.MacroEngines.Juno/DynamicNodeContext.cs create mode 100644 umbraco.MacroEngines.Juno/IMacroContext.cs create mode 100644 umbraco.MacroEngines.Juno/ParameterDictionary.cs diff --git a/umbraco.MacroEngines.Juno/DynamicNodeContext.cs b/umbraco.MacroEngines.Juno/DynamicNodeContext.cs new file mode 100644 index 0000000000..e06a00e413 --- /dev/null +++ b/umbraco.MacroEngines.Juno/DynamicNodeContext.cs @@ -0,0 +1,24 @@ +using umbraco.cms.businesslogic.macro; +using umbraco.interfaces; + +namespace umbraco.MacroEngines { + + public abstract class DynamicNodeContext : IMacroContext { + + private MacroModel _macro; + private DynamicNode _dynamicNode; + private ParameterDictionary _parameters; + + public dynamic Parameters { get { return _parameters; } } + public MacroModel Macro { get { return _macro; } } + public DynamicNode Current { get { return _dynamicNode; } } + + public void SetMembers(MacroModel macro, INode node) { + _macro = macro; + _dynamicNode = new DynamicNode(node); + _parameters = new ParameterDictionary(macro.Properties); + } + + } + +} diff --git a/umbraco.MacroEngines.Juno/IMacroContext.cs b/umbraco.MacroEngines.Juno/IMacroContext.cs new file mode 100644 index 0000000000..458b31fdb1 --- /dev/null +++ b/umbraco.MacroEngines.Juno/IMacroContext.cs @@ -0,0 +1,8 @@ +using umbraco.cms.businesslogic.macro; +using umbraco.interfaces; + +namespace umbraco.MacroEngines { + public interface IMacroContext { + void SetMembers(MacroModel macro, INode node); + } +} diff --git a/umbraco.MacroEngines.Juno/ParameterDictionary.cs b/umbraco.MacroEngines.Juno/ParameterDictionary.cs new file mode 100644 index 0000000000..46618e85aa --- /dev/null +++ b/umbraco.MacroEngines.Juno/ParameterDictionary.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using umbraco.cms.businesslogic.macro; + +namespace umbraco.MacroEngines { + + public class ParameterDictionary : DynamicObject { + + private readonly IEnumerable _parameters; + + public ParameterDictionary(IEnumerable parameters) { + if (parameters == null) + throw new ArgumentNullException("parameters"); + _parameters = parameters; + } + + public override IEnumerable GetDynamicMemberNames() { + return _parameters.Select(p => p.Key); + } + + public override bool TryGetMember(GetMemberBinder binder, out object result) { + var model = _parameters.FirstOrDefault(p => p.Key == binder.Name); + if (model == null) + { + result = string.Empty; + return true; + } + result = model.Value; + return true; + } + + } +} diff --git a/umbraco.MacroEngines.Juno/RazorEngine.cs b/umbraco.MacroEngines.Juno/RazorEngine.cs index a298af799b..9d4bd371aa 100644 --- a/umbraco.MacroEngines.Juno/RazorEngine.cs +++ b/umbraco.MacroEngines.Juno/RazorEngine.cs @@ -1,161 +1,83 @@ using System; -using System.CodeDom.Compiler; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Web; -using RazorEngine; -using RazorEngine.Templating; +using System.Web.Compilation; +using System.Web.WebPages; using umbraco.cms.businesslogic.macro; using umbraco.interfaces; using umbraco.IO; -using RE = RazorEngine; namespace umbraco.MacroEngines { - public class RazorEngine : IMacroEngine + public abstract class RazorEngine : IMacroEngine { #region IMacroEngine Members - public string Name - { - get { return "Razor Engine"; } - } + public abstract string Name { get; } - public List SupportedExtensions - { - get - { - var exts = new List {"razor"}; - return exts; - } - } + public abstract List SupportedExtensions { get; } - public Dictionary SupportedProperties - { + public Dictionary SupportedProperties { get { throw new NotImplementedException(); } } - public bool Validate(string code, INode currentPage, out string errorMessage) - { - try - { - string parsedResult; - if (!GetResult(null, code, currentPage, out parsedResult)) { - errorMessage = parsedResult; - return false; - } - - } - catch (Exception ee) - { - errorMessage = ee.ToString(); - return false; - } - - // clear razor compilation cache (a hack - by setting the template base type back/forward as there isn't a clear cache method) - Razor.SetTemplateBaseType(typeof (HtmlTemplateBase<>)); - Razor.SetTemplateBaseType(typeof (UmbracoTemplateBase<>)); - - + public bool Validate(string code, INode currentPage, out string errorMessage) { errorMessage = String.Empty; return true; } - public string Execute(MacroModel macro, INode currentPage) - { - string template = !String.IsNullOrEmpty(macro.ScriptCode) - ? macro.ScriptCode - : loadScript(IOHelper.MapPath(SystemDirectories.Python + "/" + macro.ScriptName)); - string parsedResult; - GetResult(macro.CacheIdentifier, template, currentPage, out parsedResult); + public string ExecuteRazor(MacroModel macro, INode currentPage) { + var context = HttpContext.Current; + var isDebugMode = GlobalSettings.DebugMode && HttpContext.Current.Request.QueryString["umbDebug"] != null; + var sw = new Stopwatch(); + if (isDebugMode) + sw.Start(); - // if it's a file we'll monitor changes to ensure that any updates to the file clears the cache - if (String.IsNullOrEmpty(macro.ScriptCode)) { - FileMonitor.Listen(SystemDirectories.Python + "/" + macro.ScriptName, action => RazorEngine.ClearRazorCompilationCache()); + var fileLocation = SystemDirectories.Python + "/" + macro.ScriptName; + //Returns The Compiled System.Type + var razorType = BuildManager.GetCompiledType(fileLocation); + //Instantiates The Razor Script + var razorObj = Activator.CreateInstance(razorType); + var razorWebPage = razorObj as WebPageBase; + if (razorWebPage == null) + throw new InvalidCastException("Razor Template Must Implement System.Web.WebPages.WebPageBase"); + //inject http context - for request response + var httpContext = new HttpContextWrapper(context); + razorWebPage.Context = httpContext; + //inject macro and parameters + if (razorObj is IMacroContext) { + var razorMacro = (IMacroContext)razorObj; + razorMacro.SetMembers(macro, currentPage); } - return parsedResult; + //output template + var output = new StringWriter(); + if (isDebugMode) + output.Write(string.Format(@"
", macro.Alias)); + razorWebPage.ExecutePageHierarchy(new WebPageContext(httpContext, razorWebPage, null), output); + if (isDebugMode) + { + sw.Stop(); + output.Write(string.Format("Taken {0}ms", sw.ElapsedMilliseconds)); + output.Write("
"); + } + return output.ToString(); } + public string Execute(MacroModel macro, INode currentPage) { + try { + return ExecuteRazor(macro, currentPage); + } catch (Exception exception) { + HttpContext.Current.Trace.Write("Macro", string.Format("Error loading Razor Script (file: {0}) {1}", macro.Name, exception.Message)); + var loading = string.Format("
Error loading Razor Script (file: {0})
", macro.ScriptName); + if (GlobalSettings.DebugMode) + loading = loading + exception.Message; + loading = loading + "
"; + return loading; + } + } #endregion - - /// - /// This clears all compiled razor scripts, thus ensures that changes made to files or scripts causes a recompilation - /// - public static void ClearRazorCompilationCache() - { - Razor.SetTemplateBaseType(typeof(HtmlTemplateBase<>)); - Razor.SetTemplateBaseType(typeof(UmbracoTemplateBase<>)); - } - - private bool GetResult(string cacheIdentifier, string template, INode currentPage, out string result) - { - try - { - Razor.SetTemplateBaseType(typeof (UmbracoTemplateBase<>)); - result = Razor.Parse(template, new DynamicNode(currentPage), cacheIdentifier); - return true; - } - catch (TemplateException ee) - { - string error = ee.ToString(); - if (ee.Errors.Count > 0) - { - error += - "

Detailed errors:
    "; - foreach (CompilerError err in ee.Errors) - error += string.Format("
  • {0}
  • ", err); - error += "

"; - } - result = string.Format( - "

Razor Macro Engine

An TemplateException occured while parsing the following code:

{0}

Your Razor template:

{1}

Cache key:

{2}

", - error, - HttpContext.Current.Server.HtmlEncode(template), - friendlyCacheKey(cacheIdentifier)); - } - catch (Exception ee) - { - result = string.Format( - "

Razor Macro Engine

An unknown error occured while rendering the following code:

{0}

Your Razor template:

{1}

Cache key:

{2}

", - ee, - HttpContext.Current.Server.HtmlEncode(template), - friendlyCacheKey(cacheIdentifier)); - } - return false; - } - - private string friendlyCacheKey(string cacheKey) - { - if (!String.IsNullOrEmpty(cacheKey)) - return cacheKey; - - return "No caching defined"; - } - - private string loadScript(string scriptName) - { - if (File.Exists(scriptName)) - { - return File.ReadAllText(scriptName); - } - - return String.Empty; - } - } - - public abstract class UmbracoTemplateBase : TemplateBase - { - private object m_model; - - public override T Model - { - get { return (T) m_model; } - set { m_model = value; } - } - - public string ToUpperCase(string name) - { - return name.ToUpper(); - } } } \ No newline at end of file diff --git a/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj b/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj index 2de07b2d3b..a3339710b4 100644 --- a/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj +++ b/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj @@ -42,12 +42,6 @@ ..\foreign dlls\DLR 4.0\Microsoft.Scripting.dll - - ..\foreign dlls\RazorEngine.Core.dll - - - ..\foreign dlls\RazorEngine.Templates.dll - @@ -56,6 +50,8 @@ False ..\foreign dlls\System.Web.Razor.dll + + @@ -63,6 +59,9 @@ + + +