delivery-sdk-net
delivery-sdk-net copied to clipboard
Proposal: New way of rendering rich-text
Theme:
- Improve rich-text rendering for .NET
Goals:
- improve and unify the link & asset resolution (#258 - resolution of all data-* attributes, #243 - other attributes of , #193 - asset URLs)
- promote ASP.NET display templates to a best practice
- strengthen the object model (
IRichTextContentwas an early attempt to achieve that but it's far from complete) - separate responsibilities and clean up the code (e.g. bug #257 - resolving rich-text into different types, #231 - mixing rendering and resolution approaches)
All related issues: https://github.com/Kentico/kontent-delivery-sdk-net/labels/rich-text
Supported scenarios:
- ASP.NET Display Templates
- Flattening of rich-text for search indexing purposes, etc.
- Provide ways to adjust content before rendering
Current solution:
- We offer two types of rich-text resolution:
- string-based - involves multiple types of resolvers for links, inline items, etc.
IRichTextContent-based - an object-like approach that combines hierarchical approach (for inline content items and assets) and string-based HTML rendering (for links)
Proposed solution:
- Let the
IRichTextContentbe the default type for rich-text elements and provide an additional layer for flattening it to a string.
Detailed proposition:
- Make the logic of
RichTextContentConverterpart of theModelProvider - Adjust the logic of
RichTextContentConverterto treat links as objects (=do not apply string-based resolution) => links, assets, inline content items will be treated the same - as objects - Provide resolution methods for all three type of objects
ContentLinkResolver,ContentAssetResolver,InlineContentItemResolverpublic string ResolveToString(T model)-> ability to flatten the object to stringpublic T Resolve(T model)-> ability to adjust model's properties
- Enrich the existing models for Links and Asset with a collection for supplying additional attributes (such as class or target), also add properties for some of the most common attributes (such as URL)
- Move all string-based resolution from the ModelProvider to a separate class (e.g. HtmlResolver)
- Remove the
--structuredmodeloption from the code generator and leave it true by default
Example code:
var articleResponse = await deliveryClient.GetItemAsync<Article>("on-roasts");
Article article = articleResponse.Item;
IRichTextContent richText = article.Body;
// Contains links, assets, strongly typed inline content items...already processed by `T Resolve(T model)`
// Ready to be passed to ASP.NET MVC Display Templates
IEnumerable<IRichTextBlock> blocks = richText.Blocks;
HtmlResolver resolver = new HtmlResolver(new XYZLinkResolver(), new ABCAssetResolver()...); // Or build via DI
string flattenedHtml = resolver.ToString(blocks, articleResponse.LinkedItems);
It looks like this new approach might resolve this as the IContentLinkUrlResolver moves from ModelProvider to HtmlResolver,
But currently, because the IContentLinkUrlResolver is instantiated via DI in the ModelProvider, which is in turn used by the DeliveryClient, Its currently impossible to have a IDeliveryClient instance injected within a custom IContentLinkUrlResolver implementation (it creates a circular dependency), eg;
public class CustomContentLinkUrlResolver : IContentLinkUrlResolver
{
public CustomContentLinkUrlResolver(IDeliveryClient client)
{
}
}
which in our case we want, (and I would think is a pretty general requirement?) to query Kontent's subpages hierarchy and build the url for a particular content item passed to the Url Resolver.
Thanks for pointing this out, we will take this into consideration.