How do you render that?
Typically razor require a HtmlString to render content raw. Either output your IHtmlContent using @Html.Raw or convert it to a HtmlString
// Not tested
public static string ToHtmlString(this IHtmlContent content)
{
if (content is HtmlString htmlString)
{
return htmlString.Value;
}
using (var writer = new StringWriter())
{
content.WriteTo(writer, HtmlEncoder.Default);
return writer.ToString();
}
}
If you decide to use @Html.Raw to render the string you can still keep the On Page Editing capabilties by using the @Html.EditAttributes within the paragraph tag.
i.e.
<address @Html.EditAttributes(m => m.CurrentPage.PracticeAddress)>
@Html.Raw(Model.CurrentPage.PracticeAddress.ToHtmlString)
</address>
Another option although might be a little late would be to change your property type from string to XhtmlString with a really stripped down version of the TinyMCE Editor so only allowing the Link plugin and nothing else (might also make it easier to use for your Editors)
I would echo Minesh's sentiment here that you should ideally use the TinyMCE editor here. I have multiple defininitions for TinyMCE that I have created as editor descriptors which inherit the XHtmlStringEditorDescriptor which helps with readability of the code.
[EditorDescriptorRegistration(TargetType = typeof(XhtmlString), EditorDescriptorBehavior = EditorDescriptorBehavior.OverrideDefault, UIHint = RichTextEditors.BasicEditor)]
public class BasicRichTextXhtmlStringEditorDescriptor : XhtmlStringEditorDescriptor
{
public BasicRichTextXhtmlStringEditorDescriptor(ServiceAccessor<TinyMceConfiguration> tinyMceConfiguration) : base(tinyMceConfiguration)
{
}
public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
{
base.ModifyMetadata(metadata, attributes);
if (!metadata.EditorConfiguration.ContainsKey("settings"))
{
return;
}
if (metadata.EditorConfiguration["settings"] is TinyMceSettings settings)
{
settings.BlockFormats("Paragraph=p;")
.Toolbar("formatselect | bold italic underline | superscript subscript",
"epi-personalized-content | removeformat | undo redo searchreplace | fullscreen help")
.DisableMenubar();
}
}
}
I then decorate the individual XHtmlString property with a UI Hint ... not that in the following example I'm using a nullable context and I've added Validators that check for blocks and media that have been dragged into the RTE and raises an error if they are detected.
[Display(
Name = "Intro Text",
Description = "Optional rich text content to display below the subtitle.",
GroupName = GroupNames.Content,
Order = 30)]
[CultureSpecific]
[UIHint(RichTextEditors.BasicEditor)]
[NoMediaInRichText]
[NoBlocksInRichText]
public virtual XhtmlString? IntroText { get; set; }
If you did chose to then go down this route instead, it is possible to write a MigrationStep that loads and iterates through all the instances of your content type and then converts the old string value to the new XHtmlString value. I would add that this would require the new XHtmlString property to be a new property and the old String property to be marked with [ScaffoldColumn(false)] to hide it from the CMS editor. Once you're live you can then remove the old property and the migration step.
On one of the page where there is a a href tag within a <p> tag, it doesn't render a href tag as a tag but as plain text:
How do I fix this issue where the a href tag renders inside the p tag as well as follows