Path Selector for Widget

Is it possible to get a path from a GUID using the WebPageSelectorComponent that allows any page type including folders?

[WebPageSelectorComponent(
  Label = "Articles folder",
  ExplanationText = "Select the folder containing articles",
  Order = 1,
  MaximumPages = 1)]
public IEnumerable<WebPageRelatedItem> Path { get; set; }


Environment

0

Answers

It's possible. In the widget properties, we have a property like so that gives the user the option to select from All (no path or individual selection), Select (select specific items), Path (select a page to use their children).

    [RequiredValidationRule]
    [RadioGroupComponent(
        Order = 1,
        Label = "Selection Mode",
        Options = "all;All\r\nselect;Select\r\npath;Path",
        Inline = true)]
    public string SelectionMode { get; set; } = "all";

Then we have 2 more properties that allow you to select content item(s) or a path. Note the visibility rules based on the SelectionMode value.

    [RequiredValidationRule]
    [VisibleIfEqualTo(nameof(SelectionMode), "select")]
    [ContentItemSelectorComponent(Person.CONTENT_TYPE_NAME, Order = 2, Label = "People", MinimumItems = 1)]
    public IEnumerable<ContentItemReference> SelectedPeople { get; set; } = [];

    [RequiredValidationRule]
    [VisibleIfEqualTo(nameof(SelectionMode), "path")]
    [ContentItemSelectorComponent(Page.CONTENT_TYPE_NAME, Order = 3, Label = "Path to people", MinimumItems = 1, MaximumItems = 1)]
    public IEnumerable<ContentItemReference> Path { get; set; } = [];

Lastly, in the ViewComponent, we have a pretty simple switch statement to check the SelectionMode value and return the proper set of data:

switch (properties.SelectionMode)
{
    case "path":

        var selectedPath = properties.Path.FirstOrDefault();

        if (selectedPath is null)
        {
            return [];
        }

        // get the webpage the user has selected and verify it exists
        var pathPage = await webPageRepo.GetWebPage([Page.CONTENT_TYPE_NAME], properties.Path.FirstOrDefault().Identifier, cancellationToken: HttpContext.RequestAborted);

        if (pathPage is null || !pathPage.Exists)
        {
            return [];
        }

        return await personRepo.GetPeopleAsync(pathPage.WebPageItemTreePath, properties.TopN, cancellationToken: HttpContext.RequestAborted);

    case "select":

        var selectedGuids = properties.SelectedPeople.Select(x => x.Identifier);
        return await personRepo.GetPeopleByGuidsAsync(selectedGuids, cancellationToken: HttpContext.RequestAborted);

    case "all":

        return await personRepo.GetPeopleAsync(XperienceConstants.RootTreePath, cancellationToken: HttpContext.RequestAborted);

    default:
        return [];
}

It's possible, just have to look at what you currently have available to you to use!

1

I don't know if that really answers what i was looking for. I have this now and it works for content i created

//widget property
 [WebPageSelectorComponent(
     Label = "Articles folder",
     ExplanationText = "Select the folder containing articles",
     Order = 1,
     MaximumPages = 1)]
 public IEnumerable<WebPageRelatedItem> Path { get; set; }     

 //in my repository
 public async Task<string?> GetTreePathFromWebPageRelatedItem(WebPageRelatedItem relatedItem, CancellationToken cancellationToken = default)
 {
     var builder = new ContentItemQueryBuilder()
         .ForContentTypes(parameters =>
         {
             parameters.ForWebsite(WebsiteChannelContext.WebsiteChannelName);
         })
         .Parameters(q => q
             .Where(w => w.WhereEquals(
                 nameof(IWebPageContentQueryDataContainer.WebPageItemGUID),
                 relatedItem.WebPageGuid))
             .TopN(1));

     var results = await contentQueryExecutor.GetMappedWebPageResult<WebPageFields>(
         builder,
         new ContentQueryExecutionOptions { ForPreview = false },
         cancellationToken);

     return results.FirstOrDefault()?.WebPageItemTreePath;
 }

But what i am also trying to include in the content is the default folder that

this part here doesn't seem to include that and returns null if it is what i have selected.

.ForContentTypes(parameters =>
         {
             parameters.ForWebsite(WebsiteChannelContext.WebsiteChannelName);
         })
0

To response this discussion, you have to login first.