From dc258400f11f2ea027076b8b73c8ca5039c16e1a Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 23 Sep 2013 13:49:24 +1000 Subject: [PATCH] Have the RTE insert macro stuff working, needs a few tweaks and needs to load content but its working. YOU NEED A FULL BRAND NEW DB RE-INSTALL FOR THIS. --- src/Umbraco.Core/Macros/MacroTagParser.cs | 86 ++++ src/Umbraco.Tests/Macros/MacroParserTests.cs | 60 +++ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + .../src/common/services/tinymce.service.js | 14 +- .../PropertyEditors/RichTextPropertyEditor.cs | 50 ++- src/umbraco.cms/ClassDiagram1.cd | 379 ------------------ src/umbraco.cms/umbraco.cms.csproj | 1 - .../IDataFieldWithButtons.cs | 12 + .../umbraco.interfaces.csproj | 1 + 9 files changed, 221 insertions(+), 383 deletions(-) create mode 100644 src/Umbraco.Tests/Macros/MacroParserTests.cs delete mode 100644 src/umbraco.cms/ClassDiagram1.cd create mode 100644 src/umbraco.interfaces/IDataFieldWithButtons.cs diff --git a/src/Umbraco.Core/Macros/MacroTagParser.cs b/src/Umbraco.Core/Macros/MacroTagParser.cs index ad4b180528..0b0949c978 100644 --- a/src/Umbraco.Core/Macros/MacroTagParser.cs +++ b/src/Umbraco.Core/Macros/MacroTagParser.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using System.Text.RegularExpressions; namespace Umbraco.Core.Macros { @@ -9,6 +10,91 @@ namespace Umbraco.Core.Macros /// internal class MacroTagParser { + private static readonly Regex MacroRteContent = new Regex(@"(
.*? + /// This could be some macro content + /// {/div} + /// + /// + internal static string FormatRichTextPersistedDataForEditor(string persistedContent, IDictionary htmlAttributes) + { + return MacroPersistedFormat.Replace(persistedContent, match => + { + if (match.Groups.Count >= 2) + { + //
+ var sb = new StringBuilder("
"); + sb.Append(""); + sb.Append("Macro alias: "); + sb.Append(""); + sb.Append(match.Groups[1].Value); + sb.Append("
"); + return sb.ToString(); + } + //replace with nothing if we couldn't find the syntax for whatever reason + return ""; + }); + } + + /// + /// This formats the string content posted from a rich text editor that contains macro contents to be persisted. + /// + /// + /// + /// + /// This is required because when editors are using the rte, the html that is contained in the editor might actually be displaying + /// the entire macro content, when the data is submitted the editor will clear most of this data out but we'll still need to parse it properly + /// and ensure the correct sytnax is persisted to the db. + /// + /// When a macro is inserted into the rte editor, the html will be: + /// + /// {div class='umb-macro-holder'} + /// + /// This could be some macro content + /// {/div} + /// + /// What this method will do is remove the {div} and parse out the commented special macro syntax: {?UMBRACO_MACRO macroAlias=\"myMacro\" /} + /// since this is exactly how we need to persist it to the db. + /// + /// + internal static string FormatRichTextContentForPersistence(string rteContent) + { + return MacroRteContent.Replace(rteContent, match => + { + if (match.Groups.Count >= 3) + { + //get the 3rd group which is the macro syntax + return match.Groups[2].Value; + } + //replace with nothing if we couldn't find the syntax for whatever reason + return ""; + }); + } + /// /// This will accept a text block and seach/parse it for macro markup. /// When either a text block or a a macro is found, it will call the callback method. diff --git a/src/Umbraco.Tests/Macros/MacroParserTests.cs b/src/Umbraco.Tests/Macros/MacroParserTests.cs new file mode 100644 index 0000000000..5204729626 --- /dev/null +++ b/src/Umbraco.Tests/Macros/MacroParserTests.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using NUnit.Framework; +using Umbraco.Core.Macros; + +namespace Umbraco.Tests.Macros +{ + [TestFixture] + public class MacroParserTests + { + [Test] + public void Format_RTE_Data_For_Editor() + { + var content = @"

asdfasdf

+

asdfsadf

+ +

asdfasdf

"; + var result = MacroTagParser.FormatRichTextPersistedDataForEditor(content, new Dictionary(){{"test1", "value1"},{"test2", "value2"}}); + + Assert.AreEqual(@"

asdfasdf

+

asdfsadf

+
+ +Macro alias: Map
+

asdfasdf

", result); + } + + [Test] + public void Format_RTE_Data_For_Persistence() + { + var content = @" + +

asdfasdf

+
+ +asdfasdf +asdfas +asdfasdfasdf +

asdfasdf

+
+asdfdasf +
+asdfsdf +
+ +"; + var result = MacroTagParser.FormatRichTextContentForPersistence(content); + + Assert.AreEqual(@" + +

asdfasdf

+ +asdfdasf +
+asdfsdf +
+ +", result); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index f302a431fd..38f3f87c8c 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -238,6 +238,7 @@ + diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 6c27e5c5ca..580fa89a7b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -294,9 +294,19 @@ function tinyMceService(dialogService, $log, imageHelper, assetsService, $timeou template: "views/common/dialogs/insertmacro.html", scope: $scope, callback: function(data) { - + + //put the macro syntax in comments, we will parse this out on the server side to be used + //for persisting. + var macroSyntaxComment = ""; + editor.insertContent( - editor.dom.createHTML('div', { 'class': 'umb-macro-holder' }, 'Macro alias: ' + data.macroAlias + '')); + editor.dom.createHTML('div', + { + 'class': 'umb-macro-holder', + // indicates whether or not this should kick off the ajax request to load in the macro contents. + 'data-load-content': false + }, + macroSyntaxComment + 'Macro alias: ' + data.macroAlias + '')); } }); diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs index 551f08f972..736d7444d4 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs @@ -1,4 +1,6 @@ -using Umbraco.Core; +using System.Collections.Generic; +using Umbraco.Core; +using Umbraco.Core.Macros; using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors @@ -6,5 +8,51 @@ namespace Umbraco.Web.PropertyEditors [PropertyEditor(Constants.PropertyEditors.TinyMCEv3Alias, "Rich Text Editor", "rte")] public class RichTextPropertyEditor : PropertyEditor { + /// + /// Create a custom value editor + /// + /// + protected override PropertyValueEditor CreateValueEditor() + { + return new RichTextPropertyValueEditor(base.CreateValueEditor()); + } + + /// + /// A custom value editor to ensure that macro syntax is parsed when being persisted and formatted correctly for display in the editor + /// + internal class RichTextPropertyValueEditor : PropertyValueEditorWrapper + { + public RichTextPropertyValueEditor(PropertyValueEditor wrapped) + : base(wrapped) + { + } + + /// + /// Format the data for the editor + /// + /// + /// + public override object FormatDataForEditor(object dbValue) + { + var parsed = MacroTagParser.FormatRichTextPersistedDataForEditor(dbValue.ToString(), new Dictionary()); + + return parsed; + } + + /// + /// Format the data for persistence + /// + /// + /// + /// + public override object FormatDataForPersistence(Core.Models.Editors.ContentPropertyData editorValue, object currentValue) + { + var parsed = MacroTagParser.FormatRichTextContentForPersistence(editorValue.Value.ToString()); + + return parsed; + } + } } + + } \ No newline at end of file diff --git a/src/umbraco.cms/ClassDiagram1.cd b/src/umbraco.cms/ClassDiagram1.cd deleted file mode 100644 index 60abc85680..0000000000 --- a/src/umbraco.cms/ClassDiagram1.cd +++ /dev/null @@ -1,379 +0,0 @@ - - - - - - - businesslogic\CMSNode.cs - iAIDQAAAEIwCEBIFAABEYQAARAwAKBgNAAgBGAAAUAI= - - - - - - - - - - - - businesslogic\Content.cs - IAAAABABAAgAZAAAAAAQAYEBBAgAEAgEAAAQAASADAA= - - - - - - - - businesslogic\ContentType.cs - AAAAAAAIAAIAAAAAACAAAQAABhgAAkAIAgAQAAQQCBA= - - - - - - - - - - businesslogic\ContentType.cs - - - - - businesslogic\ContentType.cs - - - - - - - - - businesslogic\datatype\DataType.cs - AAAAAAAAAAICEEAAAAAAAAAAIAAAAAAAAgAAACAAAAA= - - - - - - - - businesslogic\media\Media.cs - AAAAAAAAAAAAEEAAAAAEAQAABAAAAAAAAAQAAAAAAAA= - - - - - - - - businesslogic\media\MediaType.cs - AAAAAAAAAAAAEEAAAAAAAQAAAgAAAAAAAgAAAAAAAAA= - - - - - - - - businesslogic\member\Member.cs - AWgCAFAAQCAAEEEAAIAAQYQgBAAgAQguAgICCAFAAAA= - - - - - - - - businesslogic\member\MemberGroup.cs - AAAAAAAAAAAAEEAAAAAAAAAAAAAAAAAAAgAAAAAAAAg= - - - - - - - - businesslogic\member\MemberType.cs - AAACAAABAAAAEEAAEAAAAQAAAgAAAAAQAiAAAAAAAAA= - - - - - - - - businesslogic\web\Document.cs - AAAEEOAAA8CIEECBOEAECYgABgAAAAgMAAEACiAAQJA= - - - - - - - - businesslogic\web\DocumentType.cs - AABQACAAAAAAEEAAAgECAQAACgAAAAAEAgAAAAAAAAA= - - - - - - - - businesslogic\relation\Relation.cs - AAACAAAUEAAAEIAAAABAYAAAABECAAAAgIABAAAAAAA= - - - - - - - - businesslogic\relation\RelationType.cs - EAICYAAAAAIAAAAAAABAAAwAAgAAAAAAAAAAAAAQAAA= - - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - Actions\defaultActions.cs - AAAAAAAAAIIAAAIAAAAAAAQAQAAAAAAAgAAAAAEAAAA= - - - - - - - businesslogic\Property\Property.cs - CAACAAAABAAAEACAAABAAQAAAAAAAAAEAEAiAAAAAAA= - - - - - - - - businesslogic\propertytype\propertytype.cs - AAEDNAAAAAIgEQCEACRACQQAAAAAAAAAAgAAAAQQAAE= - - - - - - - - - - - - - - - - - - - - Actions\Action.cs - AAAAAAAAAAAAAAQAAAAAAAAAAgAAAAAAAAAACAAAAAA= - - - - - - - - - - - \ No newline at end of file diff --git a/src/umbraco.cms/umbraco.cms.csproj b/src/umbraco.cms/umbraco.cms.csproj index 9c79259f1f..19fa159ac4 100644 --- a/src/umbraco.cms/umbraco.cms.csproj +++ b/src/umbraco.cms/umbraco.cms.csproj @@ -429,7 +429,6 @@ - diff --git a/src/umbraco.interfaces/IDataFieldWithButtons.cs b/src/umbraco.interfaces/IDataFieldWithButtons.cs new file mode 100644 index 0000000000..eabb6ca4a4 --- /dev/null +++ b/src/umbraco.interfaces/IDataFieldWithButtons.cs @@ -0,0 +1,12 @@ +using System; + +namespace umbraco.interfaces +{ + /// + /// Summary description for IDataFieldWithButtons. + /// + public interface IDataFieldWithButtons : IDataEditor + { + object[] MenuIcons {get;} + } +} diff --git a/src/umbraco.interfaces/umbraco.interfaces.csproj b/src/umbraco.interfaces/umbraco.interfaces.csproj index 3f2e2f3b19..0f617173bd 100644 --- a/src/umbraco.interfaces/umbraco.interfaces.csproj +++ b/src/umbraco.interfaces/umbraco.interfaces.csproj @@ -124,6 +124,7 @@ +