Breadcrumbs

June 6, 2024 3:55 PM

Hi guys,

Anybody worked to do breadcrumbs. I am trying to do it but sometimes worked and sometimes not.If someone can give us a tip of creating will be perfect.


Environment

Answers

June 11, 2024 9:17 PM

You'll have better luck getting a helpful response from the community if you show some of your thought process and what you've already tried or explored 👍👍👍.

June 12, 2024 6:37 AM

Hi Sean,

Sorry about that, you are right. I am trying to find proper way to do the breadcrumbs but it is not really working

my code of repository is

public async Task<List<Breadcrumbs>> GetBreadcrumbsAsync(bool includeDefaultBreadcrumb = true, string homeUrl = "/", bool includeHome = true)
{
    var breadcrumbNodes = await GetNodeToBreadcrumbAndParent();
    var breadcrumbs = new List<Breadcrumbs>();

    foreach (var breadcrumb in breadcrumbNodes)
    {
        breadcrumbs.Add(new Breadcrumbs
        {
            LinkText = breadcrumb.LinkText,
            LinkUrl = breadcrumb.LinkUrl,
            IsCurrentPage = breadcrumb.IsCurrentPage
        });
    }

    if (includeDefaultBreadcrumb && includeHome)
    {
        breadcrumbs.Add(await GetDefaultBreadcrumbAsync(homeUrl));
    }

    breadcrumbs.Reverse();
    return breadcrumbs;
}

public Task<Breadcrumbs> GetDefaultBreadcrumbAsync(string homeUrl = "/")
{
    var defaultBreadcrumb = new Breadcrumbs
    {
        LinkText = "Home",
        LinkUrl = homeUrl,
        IsCurrentPage = false
    };
    return Task.FromResult(defaultBreadcrumb);
}

public Task<BreadcrumbJsonLD> BreadcrumbsToJsonLDAsync(IEnumerable<Breadcrumbs> breadcrumbs, bool excludeFirst = true)
{
    var currentPage = dataContextRetriever.Retrieve().WebPage;
    var channel = channelProvider.Get(currentPage.WebsiteChannelID);
    string baseUrl = channel.WebsiteChannelDomain;

    // Ensure the baseUrl starts with "https://"
    if (!baseUrl.StartsWith("https://"))
    {
        baseUrl = $"https://{baseUrl}";
    }

    // Ensure baseUrl ends without a trailing slash
    baseUrl = baseUrl.TrimEnd('/');

    var itemListElement = new List<ItemListElementJsonLD>();
    int position = 0;
    foreach (var breadcrumb in excludeFirst ? breadcrumbs.Skip(1) : breadcrumbs)
    {
        position++;
        string relativeUrl = breadcrumb.LinkUrl?.Replace("/", "") ?? string.Empty;

        // Ensure the relative URL does not start or end with a slash if it is empty
        relativeUrl = relativeUrl.TrimStart('/').TrimEnd('/');

        itemListElement.Add(new ItemListElementJsonLD(breadcrumb, position, baseUrl));
    }

    return Task.FromResult(new BreadcrumbJsonLD()
    {
        ItemListElement = itemListElement
    });
}



private async Task<List<Breadcrumbs>> GetNodeToBreadcrumbAndParent()
{
    var webpageItem = dataContextRetriever.Retrieve().WebPage;

    string languageName = preferredLanguageRetriever.Get();

    var nodes = new List<Breadcrumbs>();

    var builder = new ContentItemQueryBuilder()
        .ForContentType(webpageItem.ContentTypeName, queryParameters =>
        {
            queryParameters.ForWebsite(website.WebsiteChannelName);
            queryParameters.Where(where => where.WhereEquals(nameof(WebPageFields.WebPageItemID), webpageItem.WebPageItemID));
        })
        .InLanguage(webpageItem.LanguageName);

    string url1 = (await urlRetriever.Retrieve(webpageItem.WebPageItemID, webpageItem.LanguageName)).RelativePath;
    bool isCurrentPage = webpageItem.WebPageItemID == webpageItem.WebPageItemID;

    var webPageItemInfo = await GetWebpageInfoAsync(webpageItem.WebPageItemID);
    var displayname = await GetContentItemLanguageMetadataAsync(webPageItemInfo?.WebPageItemContentItemID ?? 0);
    int parentid = webPageItemInfo?.WebPageItemParentID ?? 0;

    var pages = await executor.GetMappedResult<IContentItemFieldsSource>(builder);

    foreach (var page in pages)
    {
        var node = new Breadcrumbs()
        {
            LinkText = displayname?.ContentItemLanguageMetadataDisplayName ?? string.Empty,
            LinkUrl = url1,
            IsCurrentPage = isCurrentPage,
        };
        nodes.Add(node);
    }
    return nodes;
}

public async Task<ContentItemLanguageMetadataInfo?> GetContentItemLanguageMetadataAsync(int webPageItemContentItemID)
{
    var query = ContentItemLanguageMetadataInfo.Provider.Get()
        .WhereEquals("ContentItemLanguageMetadataID", webPageItemContentItemID);

    return await query.FirstOrDefaultAsync();
}

public async Task<WebPageItemInfo?> GetWebpageInfoAsync(int webpageItemID) => await WebPageItemInfo.Provider.Get()
        .WhereEquals("WebPageItemID", webpageItemID)
        .TopN(1)
        .FirstOrDefaultAsync();
}

but if the ContentItemLanguageMetadataID is different then it doesnt work

June 12, 2024 9:41 PM

ContentItemLanguageMetadataDisplayName is not meant for content presentation - it's meant to be used by marketers inside the Xperience administration for content identification and organization. If you want to present content to website visitors, create a custom content type field for that purpose.

This is why you can't access that field on the content item you retrieve using the ContentItemQueryBuilder APIs.

Instead, think of this as a great use case for Reusable field schemas. You would assign a reusable field schema with a "Page Title" field to all web page content types. Then, you can query on the schema without caring what the content type of the page is and always have access to the "Page Title" field to display in your breadcrumb.

To answer this question, you have to login first.