Get ContentItemDataCommonDataID from Pages
I'm trying to get out the Page builder widget data via code using
private readonly IInfoProvider<ContentItemCommonDataInfo> _commonDataInfoProvider
I need to get this on a page by page basis, so I need a way of getting out the ContentItemDataCommonDataID
for the current page.
I'm currently using
private readonly IWebPageDataContextRetriever _pageDataContextRetriever;
var currentPage = _pageDataContextRetriever.Retrieve().WebPage;
but this doesn't give access to the ContentItemDataCommonDataID
field.
Looking in the database this value appears to be stored against the table for the specific content type as well but I need to be able to get this for any content type.
Is there another API I need to be using to get this value?
Environment
- Xperience by Kentico version: 29.3.1
- .NET version: [8]
- Deployment environment: Azure
Answers
Hi Sean
Sorry I probably should have been more specific. This is for an in page nav widget. The way we're building this widget means we need access to the PageBuilderWidget json from the
ContentItemCommonDataPageBuilderWidgets
field.
I need to get this field for the current page we're viewing the widget on.
Hope this clarifies things :)
If you are in the context of a widget or section, you can use the ComponentViewModel<T>.Page property and use its WebPageItemID
to retrieve the web page using a ContentItemQueryBuilder()
.
(Using ComponentViewModel<T>.Page
means you don't need to inject IWebPageDataContextRetriever
).
Then execute the query and limit yourself to the fields you need.
var b = new ContentItemQueryBuilder()
.ForContentTypes(q => q.ForWebsite([page.WebPageItemID]))
.Parameters(q => q.Columns("...")); // limit columns as an optimization
var contentItem = (await Executor.GetMappedResult<IContentItemFieldsSource>(b).FirstOrDefault();
Finally, use the content item's fields to get the correct common data record.
var commonData = (await commonDataInfoProvider
.Get()
.WhereEquals(
nameof(ContentItemCommonDataInfo.ContentItemCommonDataContentItemID),
contentItem.SystemFields.ContentItemID)
.WhereEquals(
nameof(ContentItemCommonDataInfo.ContentItemCommonDataContentLanguageID),
contentItem.SystemFields.ContentItemCommonDataContentLanguageID)
.GetEnumerableTypedResultAsync())
.FirstOrDefault();
Is your sidebar navigation dynamically built from the Widgets rendered on the page?
How will that work with personalization? Personalization will pick the variant of a Widget based on the contact details and the priority of variants of the widget but without replicating that logic, your sidebar navigation could display links that don't match the displayed content.
This almost seems to me to be an ok place to render something client side based on what is actually in the DOM (using vanilla JS, AlpineJS, or jQuery). If the navigation is outside of the main content flow you won't need to worry about cumulative layout shift from client-side rendering.
To answer this question, you have to login first.