Updated Razor To Use System.Web.Complication.BuildManager
This commit is contained in:
24
umbraco.MacroEngines.Juno/DynamicNodeContext.cs
Normal file
24
umbraco.MacroEngines.Juno/DynamicNodeContext.cs
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
8
umbraco.MacroEngines.Juno/IMacroContext.cs
Normal file
8
umbraco.MacroEngines.Juno/IMacroContext.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using umbraco.cms.businesslogic.macro;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace umbraco.MacroEngines {
|
||||
public interface IMacroContext {
|
||||
void SetMembers(MacroModel macro, INode node);
|
||||
}
|
||||
}
|
||||
35
umbraco.MacroEngines.Juno/ParameterDictionary.cs
Normal file
35
umbraco.MacroEngines.Juno/ParameterDictionary.cs
Normal file
@@ -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<MacroPropertyModel> _parameters;
|
||||
|
||||
public ParameterDictionary(IEnumerable<MacroPropertyModel> parameters) {
|
||||
if (parameters == null)
|
||||
throw new ArgumentNullException("parameters");
|
||||
_parameters = parameters;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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<string> SupportedExtensions
|
||||
{
|
||||
get
|
||||
{
|
||||
var exts = new List<string> {"razor"};
|
||||
return exts;
|
||||
}
|
||||
}
|
||||
public abstract List<string> SupportedExtensions { get; }
|
||||
|
||||
public Dictionary<string, IMacroGuiRendering> SupportedProperties
|
||||
{
|
||||
public Dictionary<string, IMacroGuiRendering> 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(@"<div title=""Macro Tag: '{0}'"" style=""border: 1px solid #009;""><div style=""border: 1px solid #CCC;"">", macro.Alias));
|
||||
razorWebPage.ExecutePageHierarchy(new WebPageContext(httpContext, razorWebPage, null), output);
|
||||
if (isDebugMode)
|
||||
{
|
||||
sw.Stop();
|
||||
output.Write(string.Format("<strong>Taken {0}ms<strong>", sw.ElapsedMilliseconds));
|
||||
output.Write("</div>");
|
||||
}
|
||||
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("<div>Error loading Razor Script (file: {0})</br/>", macro.ScriptName);
|
||||
if (GlobalSettings.DebugMode)
|
||||
loading = loading + exception.Message;
|
||||
loading = loading + "</div>";
|
||||
return loading;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// This clears all compiled razor scripts, thus ensures that changes made to files or scripts causes a recompilation
|
||||
/// </summary>
|
||||
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 +=
|
||||
"</p><strong>Detailed errors:</strong><br/><ul style=\"list-style-type: disc; margin: 1em 0;\">";
|
||||
foreach (CompilerError err in ee.Errors)
|
||||
error += string.Format("<li style=\"display: list-item;\">{0}</li>", err);
|
||||
error += "</ul><p>";
|
||||
}
|
||||
result = string.Format(
|
||||
"<div class=\"error\"><h3>Razor Macro Engine</h3><p><em>An TemplateException occured while parsing the following code:</em></p><p>{0}</p><h4 style=\"font-weight: bold; margin: 0.5em 0 0.3em 0;\">Your Razor template:</h4><code>{1}</code><h4 style=\"font-weight: bold; margin: 0.5em 0 0.3em 0;\">Cache key:</h4><p>{2}</p></div>",
|
||||
error,
|
||||
HttpContext.Current.Server.HtmlEncode(template),
|
||||
friendlyCacheKey(cacheIdentifier));
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
result = string.Format(
|
||||
"<div class=\"error\"><h3>Razor Macro Engine</h3><em>An unknown error occured while rendering the following code:</em><br /><p>{0}</p><h4 style=\"font-weight: bold; margin: 0.5em 0 0.3em 0;\">Your Razor template:</h4><code>{1}</code><h4 style=\"font-weight: bold; margin: 0.5em 0 0.3em 0;\">Cache key:</h4><p>{2}</p></div>",
|
||||
ee,
|
||||
HttpContext.Current.Server.HtmlEncode(template),
|
||||
friendlyCacheKey(cacheIdentifier));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private string friendlyCacheKey(string cacheKey)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(cacheKey))
|
||||
return cacheKey;
|
||||
|
||||
return "<em>No caching defined</em>";
|
||||
}
|
||||
|
||||
private string loadScript(string scriptName)
|
||||
{
|
||||
if (File.Exists(scriptName))
|
||||
{
|
||||
return File.ReadAllText(scriptName);
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class UmbracoTemplateBase<T> : TemplateBase<T>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,12 +42,6 @@
|
||||
<Reference Include="Microsoft.Scripting">
|
||||
<HintPath>..\foreign dlls\DLR 4.0\Microsoft.Scripting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RazorEngine.Core">
|
||||
<HintPath>..\foreign dlls\RazorEngine.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RazorEngine.Templates">
|
||||
<HintPath>..\foreign dlls\RazorEngine.Templates.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
@@ -56,6 +50,8 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\foreign dlls\System.Web.Razor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||
<Reference Include="System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Xml" />
|
||||
@@ -63,6 +59,9 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="DLRScriptingEngine.cs" />
|
||||
<Compile Include="DynamicNode.cs" />
|
||||
<Compile Include="DynamicNodeContext.cs" />
|
||||
<Compile Include="IMacroContext.cs" />
|
||||
<Compile Include="ParameterDictionary.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="RazorEngine.cs" />
|
||||
<Compile Include="Scripting\MacroScript.cs" />
|
||||
|
||||
Reference in New Issue
Block a user