You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi,
I've recently been looking at using blazor to render Markdown content as part of a blog.
Using the ChildContent which contains the markdown syntax and at the same time render any sub components inside the markdown.
It turns out this is possible (and pretty awesome)
But the code is a little sketchy in certain places
The question I've got is, is there a better way to do this in so far as the RenderTreeBuilder Array?
Such as a function call which sets rather than Adds a frame.
That way I could just ChildContent(destbuilder);
Then override the frames I want with a set function to turn them from markdown syntax into html.
I came across this but it didn't seem of much help #12415
Perhaps there's a different / better way I should be doing this, or perhaps some API method I'm not familiar with.
Markdown.cs
usingMarkdig;usingGanss.XSS;usingMicrosoft.AspNetCore.Components;usingMicrosoft.AspNetCore.Components.Rendering;usingMicrosoft.AspNetCore.Components.RenderTree;namespaceBlogFace.Components.Markdown{/// <summary> Blazor component for rendering markdown using Markdig. </summary>publicclassMarkdown:ComponentBase{/// <summary> The Markdig pipeline. </summary>/// <value> The Markdig pipeline. </value>[Parameter]publicMarkdownPipelineMdPipeLine{get;set;}/// <summary> The child content. </summary>/// <value> The child content. </value>[Parameter]publicRenderFragmentChildContent{get;set;}/// <summary> Service used to sanitize the html. </summary>/// <value> The HTML sanitizer. </value>[Inject]publicIHtmlSanitizerHtmlSanitizer{get;set;}/// <summary> On initial Setup </summary>protectedoverridevoidOnInitialized(){base.OnInitialized();if(MdPipeLine==null){MdPipeLine=newMarkdownPipelineBuilder().UseAdvancedExtensions().Build();}}/// <summary> Convert markdown string to html. </summary>/// <param name="value"> The string value to render. </param>/// <returns> The string converted to html. </returns>protectedstringConvertMarkdownToString(stringvalue){if(!string.IsNullOrWhiteSpace(value)){// Convert markdown string to HTMLvarhtml=Markdig.Markdown.ToHtml(value,MdPipeLine);// Sanitize HTML before renderingvarsanitizedHtml=HtmlSanitizer.Sanitize(html);// Return sanitized HTMLreturnsanitizedHtml;}return"";}/// <summary> Builds the render tree. </summary>/// <param name="destbuilder"> The destbuilder. </param>[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage","BL0006:Do not use RenderTree types",Justification="<Pending>")]protectedoverridevoidBuildRenderTree(RenderTreeBuilderdestbuilder){base.BuildRenderTree(destbuilder);// We use this to extract the text from the ChildContent so we can pass it to Markdigvarsrcbuilder=newRenderTreeBuilder();ChildContent(srcbuilder);// Get the Framesvarframes=srcbuilder.GetFrames();varframearr=frames.Array;varframecount=frames.Count;// Loop over the frames rendered from ChildContentfor(inti=0;i<framecount;i++){varframe=framearr[i];// Assume Markup is Markdown syntax and render it via Markdigif(frame.FrameType==RenderTreeFrameType.Markup){varsrc_content=frame.MarkupContent;destbuilder.AddMarkupContent(i,ConvertMarkdownToString(src_content));}else{// Add other sub componentsvardestframes=destbuilder.GetFrames();// This part is kind of sketchy but it works// Is there a better way to do this?// make sure the array counter is incremented internally.destbuilder.AddMarkupContent(i,"");// move the reference over from the ChildContentdestframes.Array[i]=framearr[i];}}}}}
An Example of usage below
Note TestComponent1 can be anything
it's just an example of embedding a blazor component in the middle of the markdown text.
Works fine with code blocks too.
Example1.razor
<Markdown>
# Test Header1
## Test Header2
This is some more content, hello world
<TestComponent1>
</TestComponent1>
# Test Header3
## Test Header4
This is some more content, hello world
</Markdown>
The text was updated successfully, but these errors were encountered:
One suggestion would be an api function on the RenderTreeBuilder to Add in a existing RenderTreeFrame from a different collection, alongside all the other Add function calls.
Thanks for contacting us. RenderTreeBuilder APIs are not meant to be consumed by public. You can use these APIs at your own risk, but we don't plan to add new features / APIs to those based on external asks for this area.
I think part of the question was if there will be a supported api some place else at some point to do this sort of thing? (or the equivalent) even if it's not within RenderTreeBuilder
ghost
locked as resolved and limited conversation to collaborators
Nov 3, 2021
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Hi,
I've recently been looking at using blazor to render Markdown content as part of a blog.
Using the ChildContent which contains the markdown syntax and at the same time render any sub components inside the markdown.
It turns out this is possible (and pretty awesome)
But the code is a little sketchy in certain places
The question I've got is, is there a better way to do this in so far as the RenderTreeBuilder Array?
Such as a function call which sets rather than Adds a frame.
That way I could just
ChildContent(destbuilder);
Then override the frames I want with a set function to turn them from markdown syntax into html.
I came across this but it didn't seem of much help
#12415
Perhaps there's a different / better way I should be doing this, or perhaps some API method I'm not familiar with.
Markdown.cs
An Example of usage below
Note TestComponent1 can be anything
it's just an example of embedding a blazor component in the middle of the markdown text.
Works fine with code blocks too.
Example1.razor
The text was updated successfully, but these errors were encountered: