Text before macro
\n\n\n
\n
Text After Macro
" +} +``` + +The value holds JSON with: + +- Empty block information. +- The markup with the actual RTE value and the inline macro data. +- The macro consists off: + - The tag used as a placeholder where to render its output. + - An alias to find the correct render/update logic. + - Two parameters with values entered by the user. + +The first step in transforming the data is taking the JSON value and deserializing it into a `RichTextEditorValue`. This way you have a class to work with to store the updated data in. + +You can deserialize it yourself, or you can use the `RichTextPropertyEditorHelper` to do the job for you. It will also try to catch non-JSON values that have not been migrated to the new format. + +#### Usage of RichtextPropertyEditorHelper + +```csharp +RichTextPropertyEditorHelper.TryParseRichTextEditorValue(originalValue, _jsonSerializer, _logger, out var richTextEditorValue); +``` + +The next step is to get all (relevant) macro tags out of the markup. One way of doing this is through a regular expression. + +The sample regex does not take into account that the order of parameters, which might be different from tag to tag. One way of dealing with this is to not take out the parameters in the first match. Instead move each parameter to a separate regex that runs on the first match. + +#### Example regex + +```csharp +// this regex does not take into account that the parameters might be in a different order. +private static readonly Regex MacroTagRegex = new( + @"<\?UMBRACO_MACRO\s+macroAlias=['""](?Text before macro
\n\n
\n
Text After Macro
", + "blocks" : { + "contentData" : [ { + "contentTypeKey" : "190f8990-3720-4a00-bd48-4e10dde08a5b", + "udi" : null, + "key" : "958ab4b7-213c-4576-a4d7-30b31e3e5e83", + "values" : [ { + "editorAlias" : "Umbraco.TextBox", + "culture" : null, + "segment" : null, + "alias" : "title", + "value" : "CLICK HERE" + }, { + "editorAlias" : "Umbraco.TextBox", + "culture" : null, + "segment" : null, + "alias" : "youtubeVideoId", + "value" : "xvFZjo5PgG0" + } ] + } ], + "settingsData" : [ ], + "expose" : [ { + "contentKey" : "958ab4b7-213c-4576-a4d7-30b31e3e5e83", + "culture" : null, + "segment" : null + } ], + "Layout" : { + "Umbraco.RichText" : [ { + "contentUdi" : null, + "settingsUdi" : null, + "contentKey" : "958ab4b7-213c-4576-a4d7-30b31e3e5e83", + "settingsKey" : null + } ] + } + } +} +``` + +Note that: + +- The markup still contains a tag placeholder but this time with only the `data-content-key`. +- That key references an item inside the blocks `contentData` that holds the values of the properties and a reference to the Element Type set up earlier. +- The same key is added to the `expose` collection and the Rich text `layout` collection. +- This means that if you have multiple blocks in the same value, more `contentData` items will be added in the blocks collection. They will be referenced in the `expose and `Layout accordingly. + +The example below shows the full handling of an invariant macro to an invariant block. + +This migrator starts and ends with a raw (serialized) string. If you choose a different path, you might have to change the code to work with the supplied value types instead. + +{% code title="/MacroMigrator/CtaButtonMacroMigrator.cs" %} + +```csharp +using System.Text.RegularExpressions; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.Blocks; +using Umbraco.Cms.Core.PropertyEditors; +using Umbraco.Cms.Core.Serialization; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Strings; + +namespace MacrosThirteenToFifteen.MacroMigrator; + +public class CtaButtonMacroMigrator : IMacroMigrator +{ + private readonly IJsonSerializer _jsonSerializer; + private readonly ILogger| Migrate from Vendr to Umbraco Commerce | migrate-from-vendr-to-umbraco-commerce |
| Configure SQLite support | configure-sqlite-support.md |
| Add item to Cart | add-item.md |
| Update Cart | update-cart.md |
| Delete item from Cart | delete-item.md |
| Limit Order Line Quantity | limit-orderline-quantity.md |
| Use an alternative database for Umbraco Commerce tables | use-an-alternative-database-for-umbraco-commerce-tables.md |
| Migrate from Vendr to Umbraco Commerce | migrate-from-vendr-to-umbraco-commerce |
| Configure SQLite support | configure-sqlite-support.md |
| Creating a Custom Shopping Cart | custom-cart.md |
| Limit Order Line Quantity | limit-orderline-quantity.md |
| Use an alternative database for Umbraco Commerce tables | use-an-alternative-database-for-umbraco-commerce-tables.md |