// 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()); } }
/// <summary> /// Renders the macro with the specified alias, passing in the specified parameters. /// </summary> private async Task <IHtmlEncodedString> RenderMacroAsync(IPublishedContent content, string alias, IDictionary <string, object>?parameters) { if (content == null) { throw new ArgumentNullException(nameof(content)); } // TODO: We are doing at ToLower here because for some insane reason the UpdateMacroModel method looks for a lower case match. the whole macro concept needs to be rewritten. // NOTE: the value could have HTML encoded values, so we need to deal with that var macroProps = parameters?.ToDictionary( x => x.Key.ToLowerInvariant(), i => i.Value is string?WebUtility.HtmlDecode(i.Value.ToString()) : i.Value); var html = (await _macroRenderer.RenderAsync(alias, content, macroProps)).Text; return(new HtmlEncodedString(html !)); }