Get all pages of a particular Pagetype

Vote:
 

Hi,

I would like to get all the pages of a particular Page type under a parent node. So far I use this code:

 PageReference careersExplorerParent = new PageReference(GoConstruct.Properties.Settings.Default.CP_Profiles_ParentId);

    PageDataCollection profiles = DataFactory.Instance.GetChildren(careersExplorerParent);

    results = profiles.Where(child => child.PageTypeName == "CareerExplorerCareerProfilePage" && child.IsVisibleOnSite() && child.StopPublish > DateTime.Now && child.IsDeleted == false);

But it only bringing back the first child node pages. I would also like to bring back pages under the child - for example Grand Child.:

Top Node:
       |_
         CareerExplorerCareerProfilePage Page type (Child page)

           |_                    
              CareerExplorerCareerProfilePage Page type (Grand Parent)

I hope this makes sense,

Jon

#150230
Jun 14, 2016 13:09
Vote:
 
var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
var contentModelUsage = ServiceLocator.Current.GetInstance<IContentModelUsage>();
// loading a block type
var contentType = contentTypeRepository.Load<CareerExplorerCareerProfilePage>();
// getting the list of block type usages, each usage object has properties ContentLink, LanguageBranch and Name
var usages = contentModelUsage.ListContentOfContentType(contentType);
// TODO: filter it by ancestors to find all below node
// TODO: cache if necessary for performance. Call to ListContentOfContentType is not cached by Episerver...
// TODO: use classes below Episerver.Filters to filter on access rights, publish status etc
Hope that helps!
#150232
Edited, Jun 14, 2016 13:25
David - Apr 14, 2020 21:14
Hi Daniel,

I'm using Episerver 7.5 and have followed your code snippet in order to complete what I was looking to do. I was able to make it work flawlessly, but unfortunately, the IContentModelUsage gives EVERY content references; unpublished or published. I was able to go around that, but found it really weird that in order to make it work, I had to inject a ContentStore instead of the contract IContentModelUsage. The ContentStore has an additional property named "onlyPublished" which allowed me to filter and receive only the published ContentReference.

Do you know any better way to do this? Like you said, there is a way of using "Episerver.Filters", but can't find anything related under the contract possible usages of IContentModelUsage. And since my client's web site doesn't reside inside DXC, it doesn't have Episerver Find.

Thanks for your help!
David
Vote:
 

Other alternatives:

create a recursive method, something like:

        protected static void GetDescendantsOfType<T>(PageData page, ICollection<T> descendants) where T : class
        {
            var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
            var children = contentRepository.GetChildren<PageData>(page.ContentLink);
            foreach (var child in children)
            {
                if (child is T)
                {
                    descendants.Add(child as T);
                }
                GetDescendantsOfType(child, descendants);
            }
        }

or use ContentRepository's GetDescendents and then filter by type etc:

var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
var descendants = contentRepository.GetDescendents(page.ContentLink);
#150239
Jun 14, 2016 16:19
Vote:
 

I would recommend Daniels approach or to use FindPagesWithCriterion: https://github.com/alfnilsson/ascend2015/blob/master/Business/_StandardPageRepository/4%20FindPagesWithCriteria.cs

using getchildren or getdescendants requires the application to read the entire data structure which can be quite performance heavy.

Have a look at my blog post about good practices reading content from Epi https://talk.alfnilsson.se/2015/11/25/code-best-practices-and-performance-optimization-the-summary/

speciallt when considering cache and locks

#150274
Jun 15, 2016 12:02
* 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.