diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MacroContainerValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MacroContainerValueConverter.cs
new file mode 100644
index 0000000000..f08610350e
--- /dev/null
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MacroContainerValueConverter.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Text;
+using System.Web;
+using Umbraco.Core;
+using Umbraco.Core.Macros;
+using Umbraco.Core.Models.PublishedContent;
+using Umbraco.Core.PropertyEditors;
+
+namespace Umbraco.Web.PropertyEditors.ValueConverters
+{
+ ///
+ /// Ensures macro syntax is parsed for the macro container which will work when getting the field
+ /// values in any way (i.e. dynamically, using Field(), or IPublishedContent)
+ ///
+ [PropertyValueType(typeof (IHtmlString))]
+ [PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Request)]
+ public class MacroContainerValueConverter : PropertyValueConverterBase
+ {
+ public override bool IsConverter(PublishedPropertyType propertyType)
+ {
+ return Guid.Parse(Constants.PropertyEditors.MacroContainer).Equals(propertyType.PropertyEditorGuid);
+ }
+
+ // NOT thread-safe over a request because it modifies the
+ // global UmbracoContext.Current.InPreviewMode status. So it
+ // should never execute in // over the same UmbracoContext with
+ // different preview modes.
+ static string RenderMacros(string source, bool preview)
+ {
+ // save and set for macro rendering
+ var inPreviewMode = UmbracoContext.Current.InPreviewMode;
+ UmbracoContext.Current.InPreviewMode = preview;
+
+ var sb = new StringBuilder();
+
+ try
+ {
+ var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
+ MacroTagParser.ParseMacros(
+ source,
+ //callback for when text block is found
+ textBlock => sb.Append(textBlock),
+ //callback for when macro syntax is found
+ (macroAlias, macroAttributes) => sb.Append(umbracoHelper.RenderMacro(
+ macroAlias,
+ //needs to be explicitly casted to Dictionary
+ macroAttributes.ConvertTo(x => (string)x, x => x)).ToString()));
+ }
+ finally
+ {
+ // restore
+ UmbracoContext.Current.InPreviewMode = inPreviewMode;
+ }
+
+ return sb.ToString();
+ }
+
+ public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
+ {
+ if (source == null) return null;
+ var sourceString = source.ToString();
+
+ // ensure string is parsed for macros and macros are executed correctly
+ sourceString = RenderMacros(sourceString, preview);
+
+ return sourceString;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
index 2824f9a137..548d4357db 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
@@ -11,7 +11,7 @@ using Umbraco.Web.Templates;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
- ///
+ ///
/// A value converter for TinyMCE that will ensure any macro content is rendered properly even when
/// used dynamically.
///
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 797b353009..aba7c4d109 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -355,6 +355,7 @@
+