Don't assume HtmlString when inserting default values in templates #18144
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Prerequisites
If there's an existing issue for this PR then this fixes #12805
Description
When inserting default values in templates, the client always adds them as
HtmlString
- for example@Model.Value("title", fallback: Fallback.ToDefaultValue, defaultValue: new HtmlString("Fallback for title"))
It ends up invoking
Value<T>()
method fromFriendlyPublishedContentExtensions
(source).This results in a
null
value being rendered for any property editor whose value convert does not yield anHtmlString
output - which, incidentally, none of the core property value converters seem to do.In other words: The default value is rendered as long as the property is not filled out. As soon as the property has a value, the output becomes empty (
null
).Given how the
FriendlyPublishedContentExtensions
work, the only way to make this "work" is by explicitly invoking the non-typed version ofValue()
(source) - in other words, rendering like this:@Model.Value("title", fallback: Fallback.ToDefaultValue, defaultValue: (object)"Fallback for title")
I say "work" because this is actually functionally different if you were to insert markup as default value; as-is, that would be rendered as markup. With this change, the HTML would be rendered as raw text. However, given the circumstance, I feel this is a fair trade-off to a somewhat CompletelyBroken™ feature.
Future considerations
The "insert value" feature is only useful for simple properties that yield simple values (strings, numbers) and the RTE. Any other properties (like media, content pickers, blocks etc.) will render the
ToString()
value of whatever object their value converters yield.For example, a media picker property rendered with
@Model.Value(alias)
yields a textual output along the lines of:Umbraco.Cms.Core.Models.MediaWithCrops`1[Umbraco.Cms.Web.Common.PublishedModels.Image]
We should really consider if we want to have this feature in the template builder. It's a friendly feature for simple properties... right up until the point when it becomes unfriendly for other properties.
Testing this PR