Try our conversational search powered by Generative AI!

Filter pages by VisibleInMenu

Vote:
 

Using the Content Delivery API (latest version) I want to retrieve all children pages of the homepage that have the VisibleInMenu (Display in Navigation) property set to true.However I don't see the VisibleInMenu property in any content result I retrieve, and filtering on it gives no results. How can I do this?

#287989
Sep 23, 2022 14:56
Vote:
 

You will need to Implement you own IContentCoverterProvider (EPiServer.ContentApi.Core.Serialization) 

    public class PageContentConvertorProvider : IContentConverterProvider
    {
        private readonly PageContentConvertor _pageContentConvertor;

        /// <summary>
        /// Initializes a new instance of the <see cref="PageContentConvertorProvider"/> class.
        /// </summary>
        /// <param name="pageContentConvertor"></param>
        public PageContentConvertorProvider(PageContentConvertor pageContentConvertor)
        {
            _pageContentConvertor = pageContentConvertor;
        }

        public int SortOrder => 200;

        /// <summary>
        /// Resolve custom page convertor
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public IContentConverter Resolve(IContent content)
        {
            // further enhance this to allow different supported convertors
            return content is PageData ? _pageContentConvertor : null;
        }
    }

Register in your Service Collection 

        public static void AddContentDeliveryApiCustomization(this IServiceCollection services)
        {
            services.AddSingleton<PageContentConvertor>();

Create an Interface with a Convert Method

    /// <summary>
    /// Content api model property convertor
    /// </summary>
    public interface IContentApiModelConvertor
    {
        /// <summary>
        /// Convert content to api model
        /// </summary>
        /// <param name="content"></param>
        /// <param name="contentApiModel"></param>
        /// <param name="converterContext"></param>
        void Convert(IContent content, ContentApiModel contentApiModel, ConverterContext converterContext);
    }

Implement this Interface (Business logic not included to exclude non visible in menu, but should be easy enough to do) 

    /// <summary>
    /// Dashboard page content convertor
    /// </summary>
    public class DashboardPageApiModelConvertor : IContentApiModelConvertor
    {
        private readonly IContentLoader _contentLoader;
        private readonly IUrlResolver _urlResolver;

        /// <summary>
        /// Initializes a new instance of the <see cref="DashboardPageApiModelConvertor"/> class.
        /// </summary>
        /// <param name="contentLoader"></param>
        /// <param name="urlResolver"></param>
        public DashboardPageApiModelConvertor(IContentLoader contentLoader, IUrlResolver urlResolver)
        {
            _contentLoader = contentLoader;
            _urlResolver = urlResolver;
        }

        /// <summary>
        /// Convert content to api model
        /// </summary>
        /// <param name="content"></param>
        /// <param name="contentApiModel"></param>
        /// <param name="converterContext"></param>
        public void Convert(IContent content, ContentApiModel contentApiModel, ConverterContext converterContext)
        {
            if (content is not IDashboardPageContent pageContent)
            {
                return;

Register in Service Collection

            services.TryAddEnumerable(ServiceDescriptor.Scoped<IContentApiModelConvertor, DashboardPageApiModelConvertor>());

We have done this to include all Child pages of a particular landing page but you can extend it to just generic PageData 

#287990
Sep 23, 2022 15:34
Vote:
 

Very Rough but something like this 

        public void Convert(IContent content, ContentApiModel contentApiModel, ConverterContext converterContext)
        {
            if (content is not IDashboardPageContent pageContent)
            {
                return;
            }

            var root = GetDashboardRootContent(pageContent);

            if (root != null)
            {
                // add navigation
                var navigation = new List<NavigationItemDto>();
                var children = _contentLoader.GetChildren<IDashboardPageContent>(root.ContentLink);

                navigation.Add(CreateNavigationItem((IDashboardPageContent)root, content));
                navigation.AddRange(children.Select(x => CreateNavigationStructure(x, content)));

                contentApiModel.Properties.Add(ApiConstants.DashboardNavigationDto, navigation);
            }
        }
        private NavigationItemDto CreateNavigationItem(IDashboardPageContent pageContent, IContent currentContent)
        {
            if (pageContent is PageData pageData && pageData.VisibleInMenu)
            {
                return new NavigationItemDto
                {
                    Title = pageContent.Title ?? pageContent.Name,
                    Url = _urlResolver.GetUrl(pageContent.ContentLink),
                    IsSelected = pageContent.ContentLink == currentContent.ContentLink
                };
            }

        }

or 

        private NavigationItemDto CreateNavigationItem(IDashboardPageContent pageContent, IContent currentContent)
        {
            if (pageContent is PageData pageData)
            {
                return new NavigationItemDto
                {
                    Title = pageContent.Title ?? pageContent.Name,
                    Url = _urlResolver.GetUrl(pageContent.ContentLink),
                    IsSelected = pageContent.ContentLink == currentContent.ContentLink,
                    VisibleInMenu = pageData.VisibleInMenu
                };
            }

        }
#287991
Edited, Sep 23, 2022 15:42
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.