// 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 RenderRteMacros(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<string, object> macroAttributes.ConvertTo(x => (string)x, x => x)).ToString())); } finally { // restore UmbracoContext.Current.InPreviewMode = inPreviewMode; } return(sb.ToString()); }
public void Format_RTE_Data_For_Editor_With_No_Macros(string expected) { var content = expected; var result = MacroTagParser.FormatRichTextContentForPersistence(content); Assert.AreEqual(expected, result); }
/// <summary> /// Parses the macros inside the text, by creating child elements for each item. /// </summary> /// <param name="item">The item.</param> protected virtual void ParseMacros(Item item) { // do nothing if the macros have already been rendered if (item.Controls.Count > 0) { return; } string elementText = GetFieldContents(item); using (DisposableTimer.DebugDuration <ItemRenderer>("Parsing Macros")) { MacroTagParser.ParseMacros( elementText, //callback for when a text block is parsed textBlock => item.Controls.Add(new LiteralControl(textBlock)), //callback for when a macro is parsed: (macroAlias, attributes) => { var macroControl = new Macro { Alias = macroAlias }; foreach (var i in attributes.Where(i => macroControl.Attributes[i.Key] == null)) { macroControl.Attributes.Add(i.Key, i.Value); } item.Controls.Add(macroControl); }); } }
// 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. private string RenderRteMacros(string source, bool preview) { IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext(); using (umbracoContext.ForcedPreview(preview)) // force for macro rendering { var sb = new StringBuilder(); 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(_macroRenderer.RenderAsync( macroAlias, umbracoContext.PublishedRequest?.PublishedContent, // needs to be explicitly casted to Dictionary<string, object> macroAttributes.ConvertTo(x => (string)x, x => x) !).GetAwaiter().GetResult().Text)); return(sb.ToString()); } }
public void Format_RTE_Data_For_Persistence_No_Class() { var content = @"<html> <body> <h1>asdfasdf</h1> <div att1='asdf' att2='asdfasdfasdf' att3=""sdfsdfd""> <!-- <?UMBRACO_MACRO macroAlias=""myMacro"" param1=""test1"" param2=""test2"" /> --> asdfasdf asdfas <span>asdfasdfasdf</span> <p>asdfasdf</p> </div> <span>asdfdasf</span> <div> asdfsdf </div> </body> </html>"; var result = MacroTagParser.FormatRichTextContentForPersistence(content); Assert.AreEqual(@"<html> <body> <h1>asdfasdf</h1> <?UMBRACO_MACRO macroAlias=""myMacro"" param1=""test1"" param2=""test2"" /> <span>asdfdasf</span> <div> asdfsdf </div> </body> </html>".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); }
public void Format_RTE_Data_For_Editor_With_No_Macros() { var content = @"<p>hello world</p>"; var result = MacroTagParser.FormatRichTextContentForPersistence(content); Assert.AreEqual(@"<p>hello world</p>", content); }
public bool Init(int CurrentNodeId, string PropertyData, out object instance) { //we're going to send the string through the macro parser and create the output string. if (UmbracoContext.Current != null) { var sb = new StringBuilder(); var umbracoHelper = new UmbracoHelper(UmbracoContext.Current); MacroTagParser.ParseMacros( PropertyData, //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<string, object> macroAttributes.ConvertTo(x => (string)x, x => (object)x)).ToString())); instance = new HtmlString(sb.ToString()); } else { //we have no umbraco context, so best we can do is convert to html string instance = new HtmlString(PropertyData); } return(true); }
public void Format_RTE_Data_For_Persistence_Multiline_Parameters() { string content = @"<html> <body> <h1>asdfasdf</h1> <div class='umb-macro-holder mceNonEditable' att1='asdf' att2='asdfasdfasdf' att3=""sdfsdfd""> <!-- <?UMBRACO_MACRO macroAlias=""myMacro"" param1=""test1"" param2=""test2 dfdsfds"" /> --> asdfasdf asdfas <span>asdfasdfasdf</span> <p>asdfasdf</p> </div> <span>asdfdasf</span> <div> asdfsdf </div> </body> </html>"; string result = MacroTagParser.FormatRichTextContentForPersistence(content); Assert.AreEqual( @"<html> <body> <h1>asdfasdf</h1> <?UMBRACO_MACRO macroAlias=""myMacro"" param1=""test1"" param2=""test2 dfdsfds"" /> <span>asdfdasf</span> <div> asdfsdf </div> </body> </html>".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); }
public void Format_RTE_Data_For_Persistence() { var content = @"<html> <body> <h1>asdfasdf</h1> <div class='umb-macro-holder mceNonEditable' att1='asdf' att2='asdfasdfasdf' att3=""sdfsdfd""> <!-- <?UMBRACO_MACRO macroAlias=""myMacro"" param1=""test1"" param2=""test2"" /> --> asdfasdf asdfas <span>asdfasdfasdf</span> <p>asdfasdf</p> </div> <span>asdfdasf</span> <div> asdfsdf </div> </body> </html>"; var result = MacroTagParser.FormatRichTextContentForPersistence(content); Assert.AreEqual( @"<html> <body> <h1>asdfasdf</h1> <?UMBRACO_MACRO macroAlias=""myMacro"" param1=""test1"" param2=""test2"" /> <span>asdfdasf</span> <div> asdfsdf </div> </body> </html>".StripNewLines(), result.StripNewLines()); }
public void Format_RTE_Data_For_Editor_With_Params_When_Multiple_Macros() { var content = @"<p>asdfasdf</p> <p>asdfsadf</p> <?UMBRACO_MACRO test1=""value1"" test2=""value2"" macroAlias=""Map"" /> <p>asdfsadf</p> <?UMBRACO_MACRO test1=""value1"" macroAlias=""Map"" test2=""value2"" /> <p>asdfsadf</p> <?UMBRACO_MACRO macroAlias=""Map"" test1=""value1"" test2=""value2"" /> <p>asdfasdf</p>"; var result = MacroTagParser.FormatRichTextPersistedDataForEditor( content, new Dictionary <string, string> { { "test1", "value1" }, { "test2", "value2" } }); Assert.AreEqual( @"<p>asdfasdf</p> <p>asdfsadf</p> <div class=""umb-macro-holder mceNonEditable"" test1=""value1"" test2=""value2""> <!-- <?UMBRACO_MACRO test1=""value1"" test2=""value2"" macroAlias=""Map"" /> --> <ins>Macro alias: <strong>Map</strong></ins></div> <p>asdfsadf</p> <div class=""umb-macro-holder mceNonEditable"" test1=""value1"" test2=""value2""> <!-- <?UMBRACO_MACRO test1=""value1"" macroAlias=""Map"" test2=""value2"" /> --> <ins>Macro alias: <strong>Map</strong></ins></div> <p>asdfsadf</p> <div class=""umb-macro-holder mceNonEditable"" test1=""value1"" test2=""value2""> <!-- <?UMBRACO_MACRO macroAlias=""Map"" test1=""value1"" test2=""value2"" /> --> <ins>Macro alias: <strong>Map</strong></ins></div> <p>asdfasdf</p>".StripNewLines(), result.StripNewLines()); }
public void Format_RTE_Data_For_Editor() { var content = @"<p>asdfasdf</p> <p>asdfsadf</p> <?UMBRACO_MACRO macroAlias=""Map"" /> <p>asdfasdf</p>"; var result = MacroTagParser.FormatRichTextPersistedDataForEditor(content, new Dictionary <string, string>() { { "test1", "value1" }, { "test2", "value2" } }); // Assert.AreEqual(@"<p>asdfasdf</p> //<p>asdfsadf</p> //<div class=""umb-macro-holder Map mceNonEditable"" test1=""value1"" test2=""value2""> //<!-- <?UMBRACO_MACRO macroAlias=""Map"" /> --> //<ins>Macro alias: <strong>Map</strong></ins></div> //<p>asdfasdf</p>".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); Assert.AreEqual(@"<p>asdfasdf</p> <p>asdfsadf</p> <div class=""umb-macro-holder mceNonEditable"" test1=""value1"" test2=""value2""> <!-- <?UMBRACO_MACRO macroAlias=""Map"" /> --> <ins>Macro alias: <strong>Map</strong></ins></div> <p>asdfasdf</p>".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); }
/// <summary> /// Format the data for persistence /// </summary> /// <param name="editorValue"></param> /// <param name="currentValue"></param> /// <returns></returns> public override object ConvertEditorToDb(Core.Models.Editors.ContentPropertyData editorValue, object currentValue) { if (editorValue.Value == null) { return(null); } var parsed = MacroTagParser.FormatRichTextContentForPersistence(editorValue.Value.ToString()); return(parsed); }
/// <summary> /// Format the data for the editor /// </summary> /// <param name="property"></param> /// <param name="propertyType"></param> /// <param name="dataTypeService"></param> /// <returns></returns> public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { if (property.Value == null) { return(null); } var parsed = MacroTagParser.FormatRichTextPersistedDataForEditor(property.Value.ToString(), new Dictionary <string, string>()); return(parsed); }
/// <summary> /// Format the data for the editor /// </summary> /// <param name="property"></param> /// <param name="propertyType"></param> /// <param name="dataTypeService"></param> /// <returns></returns> public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { if (property.Value == null) { return(null); } var propertyValueWithMediaResolved = TemplateUtilities.ResolveMediaFromTextString(property.Value.ToString()); var parsed = MacroTagParser.FormatRichTextPersistedDataForEditor(propertyValueWithMediaResolved, new Dictionary <string, string>()); return(parsed); }
/// <summary> /// Parses out media UDIs from an HTML string based on embedded macro parameter values. /// </summary> /// <param name="text">HTML string</param> /// <returns></returns> public IEnumerable <UmbracoEntityReference> FindUmbracoEntityReferencesFromEmbeddedMacros(string text) { // There may be more than one macro with the same alias on the page so using a tuple var foundMacros = new List <Tuple <string?, Dictionary <string, string> > >(); // This legacy ParseMacros() already finds the macros within a Rich Text Editor using regexes // It seems to lowercase the macro parameter alias - so making the dictionary case insensitive MacroTagParser.ParseMacros(text, textblock => { }, (macroAlias, macroAttributes) => foundMacros.Add(new Tuple <string?, Dictionary <string, string> >(macroAlias, new Dictionary <string, string>(macroAttributes, StringComparer.OrdinalIgnoreCase)))); foreach (var umbracoEntityReference in GetUmbracoEntityReferencesFromMacros(foundMacros)) { yield return(umbracoEntityReference); } }
public void Format_RTE_Data_For_Persistence_Custom_Single_Entry() { string content = @"<div class=""umb-macro-holder mceNonEditable umb-macro-mce_1""><!-- <?UMBRACO_MACRO macroAlias=""Test"" content=""1089"" textArea=""asdfasdf"" title="""" bool=""0"" number="""" contentType="""" multiContentType="""" multiProperties="""" properties="""" tabs="""" multiTabs="""" /> --><ins> <div class=""facts-box""> <div class=""fatcs-box-header""> <h3>null</h3> </div> <div class=""fatcs-box-body"">1089</div> </div> </ins></div>"; string result = MacroTagParser.FormatRichTextContentForPersistence(content); Assert.AreEqual(@"<?UMBRACO_MACRO macroAlias=""Test"" content=""1089"" textArea=""asdfasdf"" title="""" bool=""0"" number="""" contentType="""" multiContentType="""" multiProperties="""" properties="""" tabs="""" multiTabs="""" />", result); }
/// <summary> /// Return IHtmlString so devs doesn't need to decode html /// </summary> /// <param name="value"></param> /// <returns></returns> public override Attempt <object> ConvertPropertyValue(object value) { //we're going to send the string through the macro parser and create the output string. var sb = new StringBuilder(); var umbracoHelper = new UmbracoHelper(UmbracoContext.Current); MacroTagParser.ParseMacros( value.ToString(), //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<string, object> macroAttributes.ConvertTo(x => (string)x, x => (object)x)).ToString())); return(new Attempt <object>(true, new HtmlString(sb.ToString()))); }
/// <summary> /// Parses the macros inside the text, by creating child elements for each item. /// </summary> /// <param name="item">The item.</param> protected virtual void ParseMacros(Item item) { // do nothing if the macros have already been rendered if (item.Controls.Count > 0) { return; } var elementText = GetFieldContents(item); //Don't parse macros if there's a content item assigned since the content value // converters take care of that, just add the already parsed text if (item.ContentItem != null) { item.Controls.Add(new LiteralControl(elementText)); } else { using (DisposableTimer.DebugDuration <ItemRenderer>("Parsing Macros")) { MacroTagParser.ParseMacros( elementText, //callback for when a text block is parsed textBlock => item.Controls.Add(new LiteralControl(textBlock)), //callback for when a macro is parsed: (macroAlias, attributes) => { var macroControl = new Macro { Alias = macroAlias }; foreach (var i in attributes.Where(i => macroControl.Attributes[i.Key] == null)) { macroControl.Attributes.Add(i.Key, i.Value); } item.Controls.Add(macroControl); }); } } }
public void Format_RTE_Data_For_Editor_With_Non_AlphaNumeric_Char_In_Alias() { string content = @"<p>asdfasdf</p> <p>asdfsadf</p> <?UMBRACO_MACRO macroAlias=""My.Map.isCool eh[boy!]"" /> <p>asdfasdf</p>"; string result = MacroTagParser.FormatRichTextPersistedDataForEditor(content, new Dictionary <string, string>() { { "test1", "value1" }, { "test2", "value2" } }); Assert.AreEqual( @"<p>asdfasdf</p> <p>asdfsadf</p> <div class=""umb-macro-holder mceNonEditable"" test1=""value1"" test2=""value2""> <!-- <?UMBRACO_MACRO macroAlias=""My.Map.isCool eh[boy!]"" /> --> <ins>Macro alias: <strong>My.Map.isCool eh[boy!]</strong></ins></div> <p>asdfasdf</p>".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); }
public void Format_RTE_Data_For_Editor_With_Params_Closing_Tag_And_Content() { string content = @"<p>asdfasdf</p> <p>asdfsadf</p> <?UMBRACO_MACRO macroAlias=""Map"" test1=""value1"" test2=""value2"" ><img src='blah.jpg'/></?UMBRACO_MACRO> <p>asdfasdf</p>"; string result = MacroTagParser.FormatRichTextPersistedDataForEditor(content, new Dictionary <string, string>() { { "test1", "value1" }, { "test2", "value2" } }); Assert.AreEqual( @"<p>asdfasdf</p> <p>asdfsadf</p> <div class=""umb-macro-holder mceNonEditable"" test1=""value1"" test2=""value2""> <!-- <?UMBRACO_MACRO macroAlias=""Map"" test1=""value1"" test2=""value2"" /> --> <ins>Macro alias: <strong>Map</strong></ins></div> <p>asdfasdf</p>".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); }
public void Format_RTE_Data_For_Editor_With_Multiple_Macros() { var content = @"<p>asdfasdf</p> <?UMBRACO_MACRO macroAlias=""Breadcrumb"" /> <p>asdfsadf</p> <p> </p> <?UMBRACO_MACRO macroAlias=""login"" /> <p> </p>"; var result = MacroTagParser.FormatRichTextPersistedDataForEditor(content, new Dictionary <string, string>()); Assert.AreEqual(@"<p>asdfasdf</p> <div class=""umb-macro-holder mceNonEditable""> <!-- <?UMBRACO_MACRO macroAlias=""Breadcrumb"" /> --> <ins>Macro alias: <strong>Breadcrumb</strong></ins></div> <p>asdfsadf</p> <p> </p> <div class=""umb-macro-holder mceNonEditable""> <!-- <?UMBRACO_MACRO macroAlias=""login"" /> --> <ins>Macro alias: <strong>login</strong></ins></div> <p> </p>".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); }
// 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. string RenderMacros(string source, bool preview) { var umbracoContext = _umbracoContextAccessor.UmbracoContext; using (umbracoContext.ForcedPreview(preview)) // force for macro rendering { var sb = new StringBuilder(); var umbracoHelper = new UmbracoHelper(umbracoContext, _services); 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<string, object> macroAttributes.ConvertTo(x => (string)x, x => x)).ToString())); return(sb.ToString()); } }
public void Format_RTE_Data_For_Editor_With_Multiline_Parameters() { string content = @"<p>asdfasdf</p> <p>asdfsadf</p> <?UMBRACO_MACRO macroAlias=""Map"" test1=""value1"" test2=""value2 test"" /> <p>asdfasdf</p>"; string result = MacroTagParser.FormatRichTextPersistedDataForEditor(content, new Dictionary <string, string>() { { "test1", "value1" }, { "test2", "value2\r\ntest" } }); Assert.AreEqual( @"<p>asdfasdf</p> <p>asdfsadf</p> <div class=""umb-macro-holder mceNonEditable"" test1=""value1"" test2=""value2 test""> <!-- <?UMBRACO_MACRO macroAlias=""Map"" test1=""value1"" test2=""value2 test"" /> --> <ins>Macro alias: <strong>Map</strong></ins></div> <p>asdfasdf</p>".NoCrLf(), result.NoCrLf()); }