OrchardCore icon indicating copy to clipboard operation
OrchardCore copied to clipboard

Expose ContentItem props - Data and Elements

Open MikeKry opened this issue 9 months ago • 7 comments

Is your feature request related to a problem? Please describe.

This feature request aims to provide easier custom implementations on project side without modifying core. Application can be in custom importers, typed fetching of elements on project side etc. Right now I have problems with creating custom implementations that work with elements.

Example on Elements property: I have a blog post type defined in CMS (so it is a dynamic content type). It has some fields that I want to fetch, but I do not want to register it in code. So I have concrete class, that inherits ContentPart and exposes some fields (dont want to use deserialize/reflection/..).

But there is a problem - when I use contentItem.Get<BlogProps>("BlogPost") in controller, it works okay. But when I call it at indexprovider level, it throws exception.

Exception is thrown because at IndexProvider, Elements array is already filled up. And it contains "BlogPost" entry with a different type (ContentPart) that can not be casted to my type (BlogProps). So what I can do now is to clear Elements array and it will work again. But I cannot do that from project level, so my only way to clear it, is to call self referencing merge - "contentItem.Merge(contentItem, replacesettings..);" because it contains this Elements.Clear().

Example on data property: I have created a custom importer that transforms CSV data from old solutions like Joomla and I am using contentManager to handle data operations. But that means I need to transform data to ContentItems.

Currently, there is no option to create and customize data of ContentItems from outside of OC libraries. Only possible way to initialize ContentItem with data that I need is:

var json = JsonConvert.SerializeObject(importModel);  // transforming custom object that has same structure as ContentItem into json

var model = JsonConvert.DeserializeObject\<ContentItem\>(json); // deserializing json into ContentItem as it is only way to create content item with data and elements filled.

This approach uses predefined JsonConvertor from OC that will transform data to form I need, but it is not very elegant.

Describe the solution you'd like

In my opinion, properties on ContentItem should be public, so it is possible to play with them as needed. It is well designed for usecase that currently OrchardCore needs, but for customization, it becomes very challenging when I do not want to customize core packages.

Basically it is about making ContentElement.Data and ContentElement.Elements public

Describe alternatives you've considered

Dont know any, feel free to suggest something else. I know many other people did their importers, so maybe there is other way.

For elements, solution might be also some parameter "UseCache" that allows to ignore fetching from elements.

Related also to https://github.com/OrchardCMS/OrchardCore/discussions/15530#discussioncomment-9480680

MikeKry avatar Apr 30 '24 08:04 MikeKry

And it contains "BlogPost" entry with a different type (ContentPart) that can not be casted to my type (BlogProps).

This was fixed recently, could you try the main branch?

sebastienros avatar May 30 '24 17:05 sebastienros

@sebastienros

Do you please know where is commit / PR that fixes that? I can not really use current main branch in given project, so I could try to look at it atleast.

But anyway, if this was fixed for indexproviders, it still does not cover custom importer scenario.

Is it a problem making these props public?

MikeKry avatar May 31 '24 20:05 MikeKry

https://github.com/OrchardCMS/OrchardCore/pull/15974

sebastienros avatar May 31 '24 20:05 sebastienros

It seems that this issue didn't really move for quite a while despite us asking the author for further feedback. Is this something you'd like to revisit any time soon or should we close? Please reply.

github-actions[bot] avatar Jun 16 '24 02:06 github-actions[bot]

@MikeKry please try the latest bits, then close if it's fixed

hishamco avatar Jun 16 '24 11:06 hishamco

@hishamco @sebastienros

This PR surely fixes given example that I provided for Elements property.

Anyway it is not what I wanted to point out. My main goal is to increase flexibility of content handling by making Elements and Data property publicly accessible. Another way might be keeping Data and Elements private, but provide constructors that can create content item and set custom data.

I want to create same logic as is here but from outside module (https://github.com/OrchardCMS/OrchardCore/blob/main/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/ContentItemConverter.cs). But instead of deserialization of json, I would just insert my JObject into Data property.

But I will try to revisit this on my side once more, maybe I will be able to utilize logic from ContentStep.cs

MikeKry avatar Jun 16 '24 15:06 MikeKry

btw. difference between our importer and https://github.com/OrchardCMS/OrchardCore/pull/14630 is that our importer simply creates objects/jsons from import data and then transforms them into content items and relies on content manager to validate fields. Which is way easier/less code than creating items field by field, part by part. So not sure, if it would not be possible solution also for content transfer module..

MikeKry avatar Jun 16 '24 16:06 MikeKry

It seems that this issue didn't really move for quite a while despite us asking the author for further feedback. Is this something you'd like to revisit any time soon or should we close? Please reply.

github-actions[bot] avatar Jul 03 '24 04:07 github-actions[bot]

Closing this issue because it didn't receive further feedback from the author for very long. If you think this is still relevant, feel free to reopen it with the requested details.

github-actions[bot] avatar Jul 10 '24 04:07 github-actions[bot]