Search code examples
c#asp.net-mvcepiserverepiserver-8

Getting all children of specific page type


I have the following tree in EPI CMS:

[Root]
.
.
--[Lobby] ID=1
  --Foo1
  --Foo2
  --Foo3
  --[ContainerOfSubFoo] ID=2
    --SubFoo1
    --SubFoo2
    --SubFoo3

I want when I edit Foo1, to have check boxes of all the SubFoo's.

What I have now is this:

private static List<SelectItem> GetSubFoos()
    {

        PageReference pRef = new PageReference(2); //(ID=2 is my container page - ContainerOfSubFoo)
        PageData root = DataFactory.Instance.GetPage(pRef);
        var pages = DataFactory.Instance.GetChildren<Models.Pages.SubFoo>(root.ContentLink);

        List<SelectItem> targetsList = new List<SelectItem>();

        foreach (var target in pages)
        {
            targetsList.Add(new SelectItem() { Value = target.ContentLink.ID.ToString(), Text = target.SubFooProperty });
        }

        return targetsList;
    }

This works fine but I don't want to use ID=2, I want the GetSubFoos to go "up" (to Lobby) then go "down" to the first ContainerOfSubFoo and get all the children of SubFooType

The GetSubFoo method is on the Foo class I can provide the code of the SelectionFactory if needed.

Another problem I see now is that the checkbox "V" does not save :/ (the string is saved with the values comma seperated but the checkboxes are all unchecked

this was solved by adding .ToString() for the ID


Solution

  • From within the selection factory, you can obtain the current content via a handy extension method EPiServer.Cms.Shell.Extensions.FindOwnerContent() on the ExtendedMetadata that is passed in by EPiServer:

    public virtual IEnumerable<ISelectItem> GetSelections(ExtendedMetadata metadata)
    {
        var selections = new List<SelectItem>();
        var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
    
        var ownerContent = metadata.FindOwnerContent();
    
        if (ownerContent is Foo)
        {
            var containerRoot = contentRepository.GetChildren<ContainerOfSubFoo>(ownerContent.ParentLink).FirstOrDefault();
            var pageOptions = contentRepository.GetChildren<SubFoo>(containerRoot.ContentLink);
            foreach (var target in pageOptions)
            {
                selections.Add(new SelectItem() { Value = target.ContentLink.ID.ToString(), Text = target.SubFooProperty });
            }
        }
    
        return selections;
    }
    

    You can then traverse the page tree to find what you need.