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 (
IRichTextContent
was 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
IRichTextContent
be the default type for rich-text elements and provide an additional layer for flattening it to a string.
Detailed proposition:
- Make the logic of
RichTextContentConverter
part of theModelProvider
- Adjust the logic of
RichTextContentConverter
to 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
,InlineContentItemResolver
-
public string ResolveToString(T model)
-> ability to flatten the object to string -
public 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
--structuredmodel
option 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.