diff --git a/foreign dlls/RazorEngine.Core.dll b/foreign dlls/RazorEngine.Core.dll
new file mode 100644
index 0000000000..9c2b080619
Binary files /dev/null and b/foreign dlls/RazorEngine.Core.dll differ
diff --git a/foreign dlls/RazorEngine.Templates.dll b/foreign dlls/RazorEngine.Templates.dll
new file mode 100644
index 0000000000..2bf91af8ad
Binary files /dev/null and b/foreign dlls/RazorEngine.Templates.dll differ
diff --git a/umbraco.MacroEngines.Juno/Razor/RazorCompiler.cs b/umbraco.MacroEngines.Juno/Razor/RazorCompiler.cs
index b02472db4b..bd139a781e 100644
--- a/umbraco.MacroEngines.Juno/Razor/RazorCompiler.cs
+++ b/umbraco.MacroEngines.Juno/Razor/RazorCompiler.cs
@@ -1,6 +1,10 @@
using System.CodeDom;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
-namespace umbraco.MacroEngines.Razor {
+namespace umbraco.MacroEngines.Razor
+{
using System;
using System.CodeDom.Compiler;
using System.IO;
@@ -13,9 +17,11 @@ namespace umbraco.MacroEngines.Razor {
///
/// Compiles razor templates.
///
- internal class RazorCompiler {
+ internal class RazorCompiler
+ {
#region Fields
private readonly IRazorProvider provider;
+ private Type templateBaseType;
#endregion
#region Constructor
@@ -23,7 +29,8 @@ namespace umbraco.MacroEngines.Razor {
/// Initialises a new instance of .
///
/// The provider used to compile templates.
- public RazorCompiler(IRazorProvider provider) {
+ public RazorCompiler(IRazorProvider provider)
+ {
if (provider == null)
throw new ArgumentNullException("provider");
@@ -38,7 +45,8 @@ namespace umbraco.MacroEngines.Razor {
/// The class name of the dynamic type.
/// The template to compile.
/// [Optional] The mode type.
- private CompilerResults Compile(string className, string template, Type modelType = null) {
+ private CompilerResults Compile(string className, string template, Type modelType = null)
+ {
var languageService = provider.CreateLanguageService();
var codeDom = provider.CreateCodeDomProvider();
var host = new RazorEngineHost(languageService);
@@ -56,9 +64,11 @@ namespace umbraco.MacroEngines.Razor {
? typeof(TemplateBaseDynamic)
: typeof(TemplateBase<>).MakeGenericType(modelType));
+ templateBaseType = baseType;
generator.GeneratedClass.BaseTypes.Add(baseType);
- using (var reader = new StreamReader(new MemoryStream(Encoding.ASCII.GetBytes(template)))) {
+ using (var reader = new StreamReader(new MemoryStream(Encoding.ASCII.GetBytes(template))))
+ {
parser.Parse(reader, generator);
}
@@ -66,25 +76,20 @@ namespace umbraco.MacroEngines.Razor {
generator.GeneratedExecuteMethod.Statements.Insert(0, new CodeExpressionStatement(statement));
var builder = new StringBuilder();
- using (var writer = new StringWriter(builder)) {
+ using (var writer = new StringWriter(builder))
+ {
codeDom.GenerateCodeFromCompileUnit(generator.GeneratedCode, writer, new CodeGeneratorOptions());
}
- var @params = new CompilerParameters();
-// @params.ReferencedAssemblies.Add("System");
-// @params.ReferencedAssemblies.Add("System.Web");
- foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
- {
- if (!assembly.IsDynamic)
- @params.ReferencedAssemblies.Add(assembly.Location);
- }
+ var parameters = new CompilerParameters();
+ AddReferences(parameters);
- @params.GenerateInMemory = true;
- @params.IncludeDebugInformation = false;
- @params.GenerateExecutable = false;
- @params.CompilerOptions = "/target:library /optimize";
+ parameters.GenerateInMemory = true;
+ parameters.IncludeDebugInformation = false;
+ parameters.GenerateExecutable = false;
+ parameters.CompilerOptions = "/target:library /optimize";
- var result = codeDom.CompileAssemblyFromSource(@params, new[] { builder.ToString() });
+ var result = codeDom.CompileAssemblyFromSource(parameters, new[] { builder.ToString() });
return result;
}
@@ -94,7 +99,8 @@ namespace umbraco.MacroEngines.Razor {
/// The template to compile.
/// [Optional] The model type.
/// An instance of .
- public ITemplate CreateTemplate(string template, Type modelType = null) {
+ public ITemplate CreateTemplate(string template, Type modelType = null)
+ {
string className = Regex.Replace(Guid.NewGuid().ToString("N"), @"[^A-Za-z]*", "");
var result = Compile(className, template, modelType);
@@ -107,5 +113,92 @@ namespace umbraco.MacroEngines.Razor {
return instance;
}
#endregion
+
+ ///
+ /// Adds any required references to the compiler parameters.
+ ///
+ /// The compiler parameters.
+ private void AddReferences(CompilerParameters parameters)
+ {
+ var list = new List();
+ IEnumerable coreRefs = GetCoreReferences();
+ foreach (string location in coreRefs)
+ {
+ list.Add(location.ToLowerInvariant());
+ }
+
+ IEnumerable baseRefs = GetBaseTypeReferencedAssemblies();
+ foreach (string location in baseRefs)
+ {
+ list.Add(location.ToLowerInvariant());
+ }
+
+ foreach (string location in list)
+ System.Diagnostics.Debug.Print(location);
+ IEnumerable distinctList = list.Distinct(new AssemblyVersionComparer());
+ parameters.ReferencedAssemblies.AddRange(distinctList.ToArray());
+ }
+
+ ///
+ /// Gets the locations of assemblies referenced by a custom base template type.
+ ///
+ /// An enumerable of reference assembly locations.
+ private IEnumerable GetBaseTypeReferencedAssemblies()
+ {
+ if (templateBaseType == null)
+ return new string[0];
+
+ return templateBaseType.Assembly
+ .GetReferencedAssemblies()
+ .Select(n => Assembly.ReflectionOnlyLoad(n.FullName).Location);
+ }
+
+
+ ///
+ /// Gets the locations of all core referenced assemblies.
+ ///
+ /// An enumerable of reference assembly locations.
+ private static IEnumerable GetCoreReferences()
+ {
+ var refs = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic).Select(a => a.Location);
+
+ return refs.Concat(typeof(RazorCompiler)
+ .Assembly
+ .GetReferencedAssemblies().Select(n => Assembly.ReflectionOnlyLoad(n.FullName).Location));
+ }
+
}
+
+ public class AssemblyVersionComparer : IEqualityComparer
+ {
+ bool IEqualityComparer.Equals(string x, string y)
+ {
+ x = findAssemblyName(x);
+ y = findAssemblyName(y);
+ return (x.Contains(y) || y.Contains(x));
+ }
+
+ int IEqualityComparer.GetHashCode(string obj)
+ {
+ // 1) find the assembly name without version number and path (xxx.yyy.dll)
+ obj = findAssemblyName(obj);
+ // 2) send det som hashcode
+ if (Object.ReferenceEquals(obj, null))
+ return 0;
+ return obj.GetHashCode();
+ }
+
+ private string findAssemblyName(string fullAssemblyPath)
+ {
+
+ Regex r = new Regex(@"\\([^\\]*.dll)");
+ Match m = r.Match(fullAssemblyPath);
+ if (m.Groups.Count > 0)
+ {
+ fullAssemblyPath = m.Groups[0].Value;
+ }
+ return fullAssemblyPath;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/umbraco.MacroEngines.Juno/RazorEngine.cs b/umbraco.MacroEngines.Juno/RazorEngine.cs
index cb735d7626..55e14a22cb 100644
--- a/umbraco.MacroEngines.Juno/RazorEngine.cs
+++ b/umbraco.MacroEngines.Juno/RazorEngine.cs
@@ -1,10 +1,15 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Security.Cryptography;
+using System.Text;
using System.Web;
+using RazorEngine;
+using RazorEngine.Templating;
using umbraco.cms.businesslogic.macro;
using umbraco.interfaces;
using umbraco.IO;
+using RE = RazorEngine;
namespace umbraco.MacroEngines
{
@@ -40,25 +45,46 @@ namespace umbraco.MacroEngines
string template = !String.IsNullOrEmpty(macro.ScriptCode) ? macro.ScriptCode : loadScript(IOHelper.MapPath(SystemDirectories.Python + "/" + macro.ScriptName));
try
{
- //TODO: Add caching support
- // if (CacheTemplate)
- // result = Razor.Parse(template, new DynamicNode(currentPage), this.ID + "_razorTemplate");
- // else
- // {
- result = Razor.Razor.Parse(template, new DynamicNode(currentPage));
+ Razor.SetTemplateBaseType(typeof(UmbracoTemplateBase<>));
+ result = Razor.Parse(template, new DynamicNode(currentPage), macro.CacheIdenitifier);
+
+ }
+ catch (TemplateException ee)
+ {
+ string error = ee.ToString();
+ if (ee.Errors.Count > 0)
+ {
+ error += "
Detailed errors:
";
+ foreach (var err in ee.Errors)
+ error += string.Format("- {0}
", err.ToString());
+ 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(macro.CacheIdenitifier));
}
- // }
catch (Exception ee)
{
result = string.Format(
- "Razor Macro Engine
An error occured while rendering the following code:{0}
{1} ",
+ "Razor Macro Engine
An unknown error occured while rendering the following code:{0}
Your Razor template:
{1}Cache key:
{2}
",
ee.ToString(),
- HttpContext.Current.Server.HtmlEncode(template));
+ HttpContext.Current.Server.HtmlEncode(template),
+ friendlyCacheKey(macro.CacheIdenitifier));
}
return result;
}
+ private string friendlyCacheKey(string cacheKey)
+ {
+ if (!String.IsNullOrEmpty(cacheKey))
+ return cacheKey;
+ else
+ return "No caching defined";
+ }
+
private string loadScript(string scriptName)
{
if (File.Exists(scriptName))
@@ -68,5 +94,28 @@ namespace umbraco.MacroEngines
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();
+ }
}
}
diff --git a/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj b/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj
index 55c7024c08..2de07b2d3b 100644
--- a/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj
+++ b/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj
@@ -42,17 +42,22 @@
..\foreign dlls\DLR 4.0\Microsoft.Scripting.dll
+
+ ..\foreign dlls\RazorEngine.Core.dll
+
+
+ ..\foreign dlls\RazorEngine.Templates.dll
+
+
False
..\foreign dlls\System.Web.Razor.dll
-
-
@@ -60,14 +65,6 @@
-
-
-
-
-
-
-
-
diff --git a/umbraco/cms/businesslogic/macro/Macro.cs b/umbraco/cms/businesslogic/macro/Macro.cs
index 44031b1f96..f93d0039b6 100644
--- a/umbraco/cms/businesslogic/macro/Macro.cs
+++ b/umbraco/cms/businesslogic/macro/Macro.cs
@@ -1,5 +1,7 @@
using System;
using System.Data;
+using System.Security.Cryptography;
+using System.Text;
using System.Xml;
using System.Runtime.CompilerServices;
@@ -503,6 +505,49 @@ namespace umbraco.cms.businesslogic.macro
}
}
+ public static MacroTypes FindMacroType(string xslt, string scriptFile, string scriptType, string scriptAssembly)
+ {
+ if (!string.IsNullOrEmpty(xslt))
+ return MacroTypes.XSLT;
+ else
+ {
+ if (!string.IsNullOrEmpty(scriptFile))
+ return MacroTypes.Script;
+ else
+ {
+ if (!string.IsNullOrEmpty(scriptType) && scriptType.ToLower().IndexOf(".ascx") > -1)
+ {
+ return MacroTypes.UserControl;
+ }
+ else if (!string.IsNullOrEmpty(scriptType) && !string.IsNullOrEmpty(scriptAssembly))
+ return MacroTypes.CustomControl;
+ }
+ }
+
+ return MacroTypes.Unknown;
+ }
+
+ public static string GenerateCacheKeyFromCode(string input)
+ {
+ if (String.IsNullOrEmpty(input))
+ throw new ArgumentNullException("input", "An MD5 hash cannot be generated when 'input' parameter is null!");
+
+ // step 1, calculate MD5 hash from input
+ MD5 md5 = System.Security.Cryptography.MD5.Create();
+ byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
+ byte[] hash = md5.ComputeHash(inputBytes);
+
+ // step 2, convert byte array to hex string
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < hash.Length; i++)
+ {
+ sb.Append(hash[i].ToString("X2"));
+ }
+ return sb.ToString();
+ }
+
+
+
//Macro events
//Delegates
diff --git a/umbraco/cms/businesslogic/macro/MacroModel.cs b/umbraco/cms/businesslogic/macro/MacroModel.cs
index 5a5d3cb47e..9f45072a7c 100644
--- a/umbraco/cms/businesslogic/macro/MacroModel.cs
+++ b/umbraco/cms/businesslogic/macro/MacroModel.cs
@@ -12,16 +12,20 @@ namespace umbraco.cms.businesslogic.macro
{
public string Name { get; set; }
public string Alias { get; set; }
+ public string MacroControlIdentifier { get; set; }
+ public MacroTypes MacroType { get; set; }
public string TypeAssembly { get; set; }
public string TypeName { get; set; }
public string Xslt { get; set; }
public string ScriptName { get; set; }
public string ScriptCode { get; set; }
+ public string ScriptLanguage { get; set; }
public int CacheDuration { get; set; }
public bool CacheByPage { get; set; }
public bool CacheByMember { get; set; }
+ public string CacheIdenitifier { get; set; }
public List Properties { get; set; }
@@ -43,6 +47,8 @@ namespace umbraco.cms.businesslogic.macro
CacheByMember = cacheByMember;
Properties = new List();
+
+ MacroType = Macro.FindMacroType(Xslt, ScriptName, TypeName, TypeAssembly);
}
}
@@ -63,4 +69,16 @@ namespace umbraco.cms.businesslogic.macro
Value = value;
}
}
+
+ public enum MacroTypes
+ {
+ XSLT = 1,
+ CustomControl = 2,
+ UserControl = 3,
+ Unknown = 4,
+ Python = 5,
+ Script = 6
+ }
+
+
}
diff --git a/umbraco/presentation/config/Dashboard.config b/umbraco/presentation/config/Dashboard.config
index fcb784a54e..5d59760924 100644
--- a/umbraco/presentation/config/Dashboard.config
+++ b/umbraco/presentation/config/Dashboard.config
@@ -54,7 +54,7 @@
/usercontrols/propertyTest.ascx
-
+
/umbraco/dashboard/startupdashboardintro.ascx
@@ -88,4 +88,24 @@
+
+
+ content
+
+
+ /usercontrols/blog/CommentModeration.ascx
+
+
+
+
+ default
+ content
+
+
+ /usercontrols/dashboards/ContactForm_logs.ascx
+
+
+ /usercontrols/dashboards/EmailAFriendForm_logs.ascx
+
+
\ No newline at end of file
diff --git a/umbraco/presentation/config/UrlRewriting.config b/umbraco/presentation/config/UrlRewriting.config
index 58fb55ea48..020f541879 100644
--- a/umbraco/presentation/config/UrlRewriting.config
+++ b/umbraco/presentation/config/UrlRewriting.config
@@ -29,5 +29,6 @@
Any bugs or problems with the rewriter, contact Anders/Duckie
-->
+
\ No newline at end of file
diff --git a/umbraco/presentation/config/metablogConfig.config b/umbraco/presentation/config/metablogConfig.config
index 06fafc8306..585ebd0bf5 100644
--- a/umbraco/presentation/config/metablogConfig.config
+++ b/umbraco/presentation/config/metablogConfig.config
@@ -5,11 +5,12 @@
0
1080
False
- FAQItem
+ umbBlog
- answer
+
+
diff --git a/umbraco/presentation/config/restExtensions.config b/umbraco/presentation/config/restExtensions.config
index 991dde0bc7..88aa956085 100644
--- a/umbraco/presentation/config/restExtensions.config
+++ b/umbraco/presentation/config/restExtensions.config
@@ -10,4 +10,8 @@
-->
+
+
+
+
\ No newline at end of file
diff --git a/umbraco/presentation/config/xsltExtensions.config b/umbraco/presentation/config/xsltExtensions.config
index 44e4344593..e83c1dea04 100644
--- a/umbraco/presentation/config/xsltExtensions.config
+++ b/umbraco/presentation/config/xsltExtensions.config
@@ -2,5 +2,6 @@
-
+
+
\ No newline at end of file
diff --git a/umbraco/presentation/macro.cs b/umbraco/presentation/macro.cs
index 4b1fc37c29..7211c3633d 100644
--- a/umbraco/presentation/macro.cs
+++ b/umbraco/presentation/macro.cs
@@ -5,6 +5,7 @@ using System.Diagnostics;
using System.IO;
using System.Net;
using System.Reflection;
+using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
@@ -68,16 +69,6 @@ namespace umbraco
#region public properties
- public enum eMacroType
- {
- XSLT = 1,
- CustomControl = 2,
- UserControl = 3,
- Unknown = 4,
- Python = 5,
- Script = 6
- }
-
public int MacroID
{
set { macroID = value; }
@@ -233,24 +224,7 @@ namespace umbraco
macroCache.Insert(macroCacheIdentifier + id, this);
}
- if (!string.IsNullOrEmpty(XsltFile))
- macroType = (int)eMacroType.XSLT;
- else
- {
- if (!string.IsNullOrEmpty(ScriptFile))
- macroType = (int)eMacroType.Script;
- else
- {
- if (!string.IsNullOrEmpty(ScriptType) && ScriptType.ToLower().IndexOf(".ascx") > -1)
- {
- macroType = (int)eMacroType.UserControl;
- }
- else if (!string.IsNullOrEmpty(ScriptType) && !string.IsNullOrEmpty(ScriptAssembly))
- macroType = (int)eMacroType.CustomControl;
- }
- }
- if (macroType.ToString() == string.Empty)
- macroType = (int)eMacroType.Unknown;
+ macroType = (int)Macro.FindMacroType(XsltFile, ScriptFile, ScriptType, ScriptAssembly);
}
public override string ToString()
@@ -346,9 +320,11 @@ namespace umbraco
return false;
}
- private string getCacheGuid(Hashtable attributes, Hashtable pageElements, int pageId)
+ private string getCacheGuid(MacroModel model, Hashtable pageElements, int pageId)
{
- string tempGuid = string.Empty;
+ string tempGuid = !String.IsNullOrEmpty(model.ScriptCode)
+ ? Macro.GenerateCacheKeyFromCode(model.ScriptCode) + "-"
+ : model.Alias + "-";
if (CacheByPage)
{
@@ -362,11 +338,9 @@ namespace umbraco
else
tempGuid += "m";
}
-
- IDictionaryEnumerator id = attributes.GetEnumerator();
- while (id.MoveNext())
+ foreach (MacroPropertyModel prop in model.Properties)
{
- string attValue = helper.FindAttribute(pageElements, attributes, id.Key.ToString());
+ string attValue = prop.Value;
if (attValue.Length > 255)
tempGuid += attValue.Remove(255, attValue.Length - 255) + "-";
else
@@ -376,38 +350,45 @@ namespace umbraco
}
public Control renderMacro(Hashtable attributes, Hashtable pageElements, int pageId)
+ {
+ MacroModel m = ConvertToMacroModel(attributes);
+ return renderMacro(m, pageElements, pageId);
+ }
+
+ public Control renderMacro(MacroModel model, Hashtable pageElements, int pageId)
{
HttpContext.Current.Trace.Write("renderMacro",
string.Format("Rendering started (macro: {0}, type: {1}, cacheRate: {2})",
- Name, MacroType, RefreshRate));
+ Name, MacroType, model.CacheDuration));
StateHelper.SetContextValue(macrosAddedKey, StateHelper.GetContextValue(macrosAddedKey) + 1);
String macroHtml = null;
Control macroControl = null;
- string macroGuid = getCacheGuid(attributes, pageElements, pageId);
+ model.CacheIdenitifier = getCacheGuid(model, pageElements, pageId);
- if (RefreshRate > 0)
+ if (model.CacheDuration > 0)
{
- macroHtml = macroCache["macroHtml_" + macroGuid] as String;
+ macroHtml = macroCache["macroHtml_" + model.CacheIdenitifier] as String;
if (!String.IsNullOrEmpty(macroHtml))
{
- macroHtml = macroCache["macroHtml_" + macroGuid] as String;
- HttpContext.Current.Trace.Write("renderMacro", "Content loaded from cache ('" + macroGuid + "')...");
+ macroHtml = macroCache["macroHtml_" + model.CacheIdenitifier] as String;
+ HttpContext.Current.Trace.Write("renderMacro", "Content loaded from cache ('" + model.CacheIdenitifier + "')...");
}
}
if (String.IsNullOrEmpty(macroHtml))
{
- switch (MacroType)
+ int macroType = model.MacroType != MacroTypes.Unknown ? (int)model.MacroType : MacroType;
+ switch (macroType)
{
- case (int)eMacroType.UserControl:
+ case (int)MacroTypes.UserControl:
try
{
HttpContext.Current.Trace.Write("umbracoMacro", "Usercontrol added (" + scriptType + ")");
- macroControl = loadUserControl(ScriptType, attributes, pageElements);
+ macroControl = loadUserControl(ScriptType, model, pageElements);
break;
}
catch (Exception e)
@@ -417,12 +398,12 @@ namespace umbraco
macroControl = new LiteralControl("Error loading userControl '" + scriptType + "'");
break;
}
- case (int)eMacroType.CustomControl:
+ case (int)MacroTypes.CustomControl:
try
{
HttpContext.Current.Trace.Write("umbracoMacro", "Custom control added (" + scriptType + ")");
HttpContext.Current.Trace.Write("umbracoMacro", "ScriptAssembly (" + scriptAssembly + ")");
- macroControl = loadControl(scriptAssembly, ScriptType, attributes, pageElements);
+ macroControl = loadControl(scriptAssembly, ScriptType, model, pageElements);
break;
}
catch (Exception e)
@@ -436,15 +417,14 @@ namespace umbraco
scriptType + "'");
break;
}
- case (int)eMacroType.XSLT:
- macroControl = loadMacroXSLT(this, attributes, pageElements);
+ case (int)MacroTypes.XSLT:
+ macroControl = loadMacroXSLT(this, model, pageElements);
break;
- case (int)eMacroType.Script:
+ case (int)MacroTypes.Script:
try
{
HttpContext.Current.Trace.Write("umbracoMacro",
"MacroEngine script added (" + ScriptFile + ")");
- MacroModel model = ConvertToMacroModel(attributes);
macroControl = loadMacroDLR(model);
break;
}
@@ -482,10 +462,10 @@ namespace umbraco
}
// Add result to cache
- if (RefreshRate > 0)
+ if (model.CacheDuration > 0)
{
// do not add to cache if there's no member and it should cache by personalization
- if (!CacheByPersonalization || (CacheByPersonalization && Member.GetCurrentMember() != null))
+ if (!model.CacheByMember || (model.CacheByMember && Member.GetCurrentMember() != null))
{
if (macroControl != null)
{
@@ -494,10 +474,10 @@ namespace umbraco
var hw = new HtmlTextWriter(sw);
macroControl.RenderControl(hw);
- macroCache.Insert("macroHtml_" + macroGuid,
+ macroCache.Insert("macroHtml_" + model.CacheIdenitifier,
sw.ToString(),
null,
- DateTime.Now.AddSeconds(RefreshRate),
+ DateTime.Now.AddSeconds(model.CacheDuration),
TimeSpan.Zero,
CacheItemPriority.Low,
null);
@@ -599,13 +579,10 @@ namespace umbraco
return retval;
}
- public Control loadMacroXSLT(macro macro, Hashtable attributes, Hashtable pageElements)
+ public Control loadMacroXSLT(macro macro, MacroModel model, Hashtable pageElements)
{
if (XsltFile.Trim() != string.Empty)
{
- //get attributes in lowercase...
- attributes = keysToLowerCase(keysToLowerCase(attributes));
-
// Get main XML
XmlDocument umbracoXML = content.Instance.XmlContent;
@@ -615,20 +592,19 @@ namespace umbraco
foreach (DictionaryEntry macroDef in macro.properties)
{
- try
+ var prop = model.Properties.Find(m => m.Key == (string)macroDef.Key);
+ string propValue = prop != null
+ ? helper.parseAttribute(pageElements, prop.Value)
+ : helper.parseAttribute(pageElements, "");
+ if (!String.IsNullOrEmpty(propValue))
{
- if (helper.FindAttribute(pageElements, attributes, macroDef.Key.ToString()) != string.Empty)
+ if (propValue != string.Empty)
addMacroXmlNode(umbracoXML, macroXML, macroDef.Key.ToString(), macroDef.Value.ToString(),
- helper.FindAttribute(pageElements, attributes, macroDef.Key.ToString()));
+ propValue);
else
addMacroXmlNode(umbracoXML, macroXML, macroDef.Key.ToString(), macroDef.Value.ToString(),
string.Empty);
}
- catch (Exception e)
- {
- HttpContext.Current.Trace.Warn("umbracoMacro", "Could not write XML node (" + macroDef.Key + ")",
- e);
- }
}
if (HttpContext.Current.Request.QueryString["umbDebug"] != null && GlobalSettings.DebugMode)
@@ -1072,79 +1048,25 @@ namespace umbraco
return string.Empty;
}
- ///
- /// Executes a python script.
- ///
- /// The instance of the macro (this). No idea why passed.
- /// Relayed attributes to determine the values of the passed properties.
- /// The current page.
- /// Returns a LiteralControl stuffed with the StandardOutput of the script execution.
- public Control loadMacroPython(macro macro, Hashtable attributes, Hashtable pageElements)
- {
- var ret = new LiteralControl();
- try
- {
- // Adding some global accessible variables to the enviroment.
- // Currently no cleanup after execution is done.
- var args = new Hashtable();
- HttpContext.Current.Session.Add("pageElements", pageElements);
- HttpContext.Current.Session.Add("macro", this);
- HttpContext.Current.Session.Add("args", args);
-
- foreach (DictionaryEntry macroDef in macro.properties)
- {
- try
- {
- args.Add(macroDef.Key.ToString(),
- helper.FindAttribute(pageElements, attributes, macroDef.Key.ToString()));
- }
- catch (Exception e)
- {
- HttpContext.Current.Trace.Warn("umbracoMacro",
- "Could not add global variable (" + macroDef.Key +
- ") to python enviroment", e);
- }
- }
-
- if (string.IsNullOrEmpty(macro.ScriptFile))
- {
- ret.Text = string.Empty;
- }
- else
- {
- // Execute the script and set the text of our LiteralControl with the returned
- // result of our script.
- string path = IOHelper.MapPath(SystemDirectories.Python + "/" + macro.scriptFile);
- object res = python.executeFile(path);
- ret.Text = res.ToString();
- }
- }
- catch (Exception ex)
- {
- // Let's collect as much info we can get and display it glaring red
- ret.Text = "";
- Exception ie = ex;
- while (ie != null)
- {
- ret.Text += "
" + ie.Message + "
";
- ret.Text += ie.StackTrace + "
";
-
- ie = ie.InnerException;
- }
- ret.Text += "
";
- }
- return ret;
- }
-
-
public Control loadMacroDLR(MacroModel macro)
{
+ TraceInfo("umbracoMacro", "Loading IMacroEngine script");
var ret = new LiteralControl();
+ if (macro.ScriptCode != String.Empty)
+ {
+ IMacroEngine engine = MacroEngineFactory.GetByExtension(macro.ScriptLanguage);
+ ret.Text = engine.Execute(
+ macro,
+ Node.GetCurrent());
- string path = IOHelper.MapPath(SystemDirectories.Python + "/" + macro.ScriptName);
- IMacroEngine engine = MacroEngineFactory.GetByFilename(path);
- ret.Text = engine.Execute(macro, Node.GetCurrent());
-
+ }
+ else
+ {
+ string path = IOHelper.MapPath(SystemDirectories.Python + "/" + macro.ScriptName);
+ IMacroEngine engine = MacroEngineFactory.GetByFilename(path);
+ ret.Text = engine.Execute(macro, Node.GetCurrent());
+ }
+ TraceInfo("umbracoMacro", "Loading IMacroEngine script [done]");
return ret;
}
@@ -1155,9 +1077,9 @@ namespace umbraco
/// Name of the control
///
///
- public Control loadControl(string fileName, string controlName, Hashtable attributes)
+ public Control loadControl(string fileName, string controlName, MacroModel model)
{
- return loadControl(fileName, controlName, attributes, null);
+ return loadControl(fileName, controlName, model, null);
}
///
@@ -1168,7 +1090,7 @@ namespace umbraco
///
///
///
- public Control loadControl(string fileName, string controlName, Hashtable attributes, Hashtable pageElements)
+ public Control loadControl(string fileName, string controlName, MacroModel model, Hashtable pageElements)
{
Type type;
Assembly asm;
@@ -1213,14 +1135,16 @@ namespace umbraco
{
if (HttpContext.Current != null)
HttpContext.Current.Trace.Warn("macro",
- string.Format("control property '{0} ({1})' didn't work",
- propertyAlias,
- helper.FindAttribute(attributes, propertyAlias)));
+ string.Format("control property '{0}' doesn't exist or aren't accessible (public)",
+ propertyAlias));
continue;
}
- object propValue = helper.FindAttribute(pageElements, attributes, propertyAlias);
+ MacroPropertyModel propModel = model.Properties.Find(m => m.Key == propertyAlias);
+ object propValue = propModel != null
+ ? helper.parseAttribute(pageElements, propModel.Value)
+ : helper.parseAttribute(pageElements, "");
// Special case for types of webControls.unit
if (prop.PropertyType == typeof(Unit))
propValue = Unit.Parse(propValue.ToString());
@@ -1255,13 +1179,6 @@ namespace umbraco
}
prop.SetValue(control, Convert.ChangeType(propValue, prop.PropertyType), null);
-
- if (HttpContext.Current != null)
- HttpContext.Current.Trace.Write("macro",
- string.Format("control property '{0} ({1})' worked",
- propertyAlias,
- helper.FindAttribute(pageElements, attributes,
- propertyAlias)));
}
return control;
}
@@ -1273,10 +1190,10 @@ namespace umbraco
/// The attributes.
/// The page elements.
///
- public Control loadUserControl(string fileName, Hashtable attributes, Hashtable pageElements)
+ public Control loadUserControl(string fileName, MacroModel model, Hashtable pageElements)
{
Debug.Assert(!string.IsNullOrEmpty(fileName), "fileName cannot be empty");
- Debug.Assert(attributes != null, "attributes cannot be null");
+ Debug.Assert(model.Properties != null, "attributes cannot be null");
Debug.Assert(pageElements != null, "pageElements cannot be null");
try
{
@@ -1291,8 +1208,8 @@ namespace umbraco
if (slashIndex < 0)
slashIndex = 0;
- if (attributes["controlID"] != null)
- oControl.ID = attributes["controlID"].ToString();
+ if (!String.IsNullOrEmpty(model.MacroControlIdentifier))
+ oControl.ID = model.MacroControlIdentifier;
else
oControl.ID =
string.Format("{0}_{1}", fileName.Substring(slashIndex, fileName.IndexOf(".ascx") - slashIndex),
@@ -1318,10 +1235,12 @@ namespace umbraco
continue;
}
- object propValue =
- helper.FindAttribute(pageElements, attributes, propertyAlias).Replace("&", "&").Replace(
- """, "\"").Replace("<", "<").Replace(">", ">");
- if (string.IsNullOrEmpty(propValue as string))
+ MacroPropertyModel propModel = model.Properties.Find(m => m.Key == propertyAlias);
+ object propValue = propModel != null
+ ? helper.parseAttribute(pageElements, propModel.Value)
+ : helper.parseAttribute(pageElements, "");
+
+ if (propValue != null)
continue;
// Special case for types of webControls.unit
@@ -1592,6 +1511,7 @@ namespace umbraco
xslt = xslt.Replace("{1}", namespaceList.ToString());
return xslt;
}
+
}
public class MacroCacheContent
diff --git a/umbraco/presentation/umbraco/templateControls/Macro.cs b/umbraco/presentation/umbraco/templateControls/Macro.cs
index 52bdff446c..107bb3ac61 100644
--- a/umbraco/presentation/umbraco/templateControls/Macro.cs
+++ b/umbraco/presentation/umbraco/templateControls/Macro.cs
@@ -102,27 +102,48 @@ namespace umbraco.presentation.templateControls
if (!MacroAttributes.ContainsKey("macroalias") && !MacroAttributes.ContainsKey("macroAlias"))
MacroAttributes.Add("macroalias", Alias);
+ // set pageId to int.MinValue if no pageID was found,
+ // e.g. if the macro was rendered on a custom (non-Umbraco) page
+ int pageId = Context.Items["pageID"] == null ? int.MinValue : int.Parse(Context.Items["pageID"].ToString());
+
if (!String.IsNullOrEmpty(Language) && Text != "")
{
- //TODO: FOR JUNO RC: Move this into the Macro object to ensure caching etc
macro m = new macro();
+
MacroModel model = m.ConvertToMacroModel(MacroAttributes);
model.ScriptCode = Text;
- IMacroEngine engine = MacroEngineFactory.GetByExtension(Language);
+ model.ScriptLanguage = Language;
+ model.MacroType = MacroTypes.Script;
+ if (!String.IsNullOrEmpty(Attributes["Cache"]))
+ {
+ int cacheDuration = 0;
+ if (int.TryParse(Attributes["Cache"], out cacheDuration))
+ {
+ model.CacheDuration = cacheDuration;
+ }
+ else
+ {
+ System.Web.HttpContext.Current.Trace.Warn("Template",
+ "Cache attribute is in incorect format (should be an integer).");
+ }
+ }
+ Control c = m.renderMacro(model, (Hashtable)Context.Items["pageElements"], pageId);
+ if (c != null)
+ Controls.Add(c);
+ else
+ System.Web.HttpContext.Current.Trace.Warn("Template", "Result of inline macro scripting is null");
+
+ /*IMacroEngine engine = MacroEngineFactory.GetByExtension(Language);
string result = engine.Execute(
model,
Node.GetCurrent());
- Controls.Add(new LiteralControl(result));
+ Controls.Add(new LiteralControl(result));*/
}
else
{
macro tempMacro = null;
tempMacro = macro.ReturnFromAlias(Alias);
- // set pageId to int.MinValue if no pageID was found,
- // e.g. if the macro was rendered on a custom (non-Umbraco) page
- int pageId = Context.Items["pageID"] == null ? int.MinValue : int.Parse(Context.Items["pageID"].ToString());
-
if (tempMacro != null)
{