World is now on Opti ID! Learn more

How to get all pages of certain page type?

Vote:
 

I want to get all pages with type of ArticlePage from a controller of a partial. 

Currently I have this code and pages is null?

[ChildActionOnly]
        public ActionResult Navigation()
        {
            var model = new NavigationPartialViewModel();

            var pageTypeId = ServiceLocator.Current.GetInstance<ContentTypeRepository>()
                .Load<ArticlePage>()
                .ID
                .ToString();


            var criterias = new PropertyCriteriaCollection
            {
                new PropertyCriteria()
                {
                    Condition = CompareCondition.Equal,
                    Name = "PageTypeID",
                    Type = PropertyDataType.PageType,
                    Value = pageTypeId,
                    Required = true
                }
            };

            var repository = ServiceLocator.Current.GetInstance<IPageCriteriaQueryService>();

            var pages = repository.FindPagesWithCriteria(
                PageReference.StartPage,
                criterias);

            return PartialView(model);
        }
#265608
Oct 25, 2021 11:36
Vote:
 

Try using FindAllPagesWithCriteria instead of FindPagesWithCriteria

FYI - FindPagesWithCriteria returns all matching pages that the current user has read access for, whereas FindAllPagesWithCriteria returns all pages regardless of permissions.

#265609
Oct 25, 2021 12:29
Vote:
 

Something like this?

var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
var contentModelUsage = ServiceLocator.Current.GetInstance<IContentModelUsage>();
var contentType = contentTypeRepository.Load<ArticlePage>();
var allArticlePages = contentModelUsage.ListContentOfContentType(contentType);
#265619
Oct 25, 2021 16:51
Vote:
 

IContentModelUsage is awesome, but might give you more than you want.

ListContentOfContentType will give you every version of the content, each version in every language. So, if a page has been publisedh 5 times, and therefore has 5 versions; then that page will be listed 5 times here.

To fix this you can remove duplicate entries and convert ContentLink to non-versioned.

Add the following extension method to your code. Then you have the following method available: contentModelUsage.ListContentWithoutVersionOfContentType(contentType);

using EPiServer.Core;
using EPiServer.DataAbstraction;
using System.Collections.Generic;
using System.Linq;

namespace EPiServer.Core;

public static class IContentModelUsageExtensions
{
    /// <summary>
    /// Lists all content of desired type, without versions.
    /// </summary>
    public static IEnumerable<ContentUsage> ListContentWithoutVersionOfContentType(this IContentModelUsage contentModelUsage, ContentType contentType)
        => contentModelUsage.ListContentOfContentType(contentType)
        .DistinctBy(_ => (_.ContentLink.ID, _.LanguageBranch))
        .Select(content => new ContentUsage
        {
            ContentLink = content.ContentLink.ToReferenceWithoutVersion(),
            LanguageBranch = content.LanguageBranch,
            Name = content.Name
        })
        .ToArray();
}

 

Thomas, do you aggree? 😊

#337689
Edited, Apr 02, 2025 15:57
Vote:
 

Yes, you are correct Tommy, but that's not the only case where IContentModelUsage could return more than you expect.

If you want usage of a block type, and that block type is used as a property on other content types – you will get both direct instances of the block type, and instances of content types that use the block type as a property (local block).

Under the hood, the SQL stored procedures netPageTypeGetUsage and netBlockTypeGetUsage are used. If you have specific needs, or deal with blocks that are used both as content types and local blocks, you could be better off writing your own stored procedure. IContentModelUsage could be confusing.

#337691
Edited, Apr 02, 2025 17:49
Vote:
 

Here are the helper methods I have used to get all pages and blocks of a certain content type:

        /// <summary>
        /// Returns the children with type <typeparamref name="T">T</typeparamref> of the <paramref name="rootLink">root</paramref> recursively.
        /// </summary>
        /// <typeparam name="T">A page type of type SitePageData</typeparam>
        /// <param name="rootLink">Root page to start looking</param>
        /// <param name="getPublishedPagesOnly"></param>
        /// <returns></returns>
        public static IEnumerable<T> GetAllChildrenOfType<T>(ContentReference rootLink, bool getPublishedPagesOnly)
            where T : PageData
        {
            var loader = ServiceLocator.Current.GetInstance<IContentLoader>();
            var publishedStateAssessor = ServiceLocator.Current.GetInstance<IPublishedStateAssessor>();

            bool Predicate(PageData x) =>
                getPublishedPagesOnly
                    ? publishedStateAssessor.IsPublished(x, PagePublishedStatus.Published)
                    : publishedStateAssessor.IsPublished(x, PublishedStateCondition.None);

            var children = loader.GetChildren<PageData>(rootLink).Where(Predicate);
            foreach (var child in children)
            {
                if (child is T childOfRequestedType && child.IsEPiServerPage())
                {
                    yield return childOfRequestedType;
                }
                foreach (var descendant in GetAllChildrenOfType<T>(child.ContentLink, getPublishedPagesOnly))
                {
                    yield return descendant;
                }
            }
        }
        public static List<T> GetAllBlocksOfType<T>(bool filterPublished = true) where T : IContentData
        {
            var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
            var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
            var contentModelUsage = ServiceLocator.Current.GetInstance<IContentModelUsage>();

            // get all usages of MyBlock, including versions
            var contentType = contentTypeRepository.Load<T>();
            var contentUsages = contentModelUsage.ListContentOfContentType(contentType);

            // get distinct content references without version
            var contentReferences = contentUsages
                .Select(x => x.ContentLink.ToReferenceWithoutVersion())
                .Distinct()
                .ToList();

            // fetch data from DB
            var instances = contentReferences
                .Select(contentReference => contentLoader.Get<IContent>(contentReference))
                .ToList();

            // remove unpublished
            if (filterPublished)
            {
                new FilterPublished().Filter(instances);
            }
            var result = instances.Cast<T>().ToList();

            return result;
        }
#339618
Jul 09, 2025 11:48
* 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.