How to make breadcrumb navigation to match Content Taxonomy?

Peter Zalman
Tera Contributor

Breadcrumb navigation on Employee Center Portal is confusing and actually decreases usability. Is there a way to make all content appear in a consistent taxonomy so that breadcrumb navigation matches the mega menu?

Use Case As-Is

  1. Open Topic Page from Mega menu
  2. The breadcrumb reflects the content taxonomy 
  3. Click on the catalog item
  4. The breadcrumb navigation changes to different taxonomy - a technical structure of catalogs 

Use Case To-Be

  1. Open Topic Page from Mega menu
  2. The breadcrumb reflects the content taxonomy
  3. Click on the catalog item
  4. The breadcrumb navigation remains consistent, adds the final child item 

 

find_real_file.png

find_real_file.png

1 ACCEPTED SOLUTION

Vanderlei
Mega Sage

Hello @Peter Zalman, how are you?

 

I am implementing an employee center and I faced the same problem.

I needed to create a custom widget to have this functionality using a function that ServiceNow itself uses to generate the breadcrumb of the taxonomies.(function present in the topics page)

 

There are some business rules for the operation of this widget, they are:

  • Does not work if two topics are using the same item
  • Does not work using content items
  • If it doesn't find the breadcrumb, it will just be Home > Catalog Item Name.

 

How to implement:

  1. Install the attached widget.
  2. Go to Service Portal > Pages > esc_sc_cat_item
  3. Click on the instance where the HRM Back Button ( is on the instance and not on the widget name)
  4. Go to the Section Widget and change the widget to the breadcrumb taxonomy

 

Now where the back button widget will be replaced by the custom breadcrumb to show the taxonomy path to the catalog item.

 

Vanderlei_0-1681918191471.png

Vanderlei_1-1681918514490.png

Vanderlei_2-1681918533802.png

 

If my answer helped you, please mark my answer as helpful.

 

Vanderlei Catione Junior | LinkedIn

Senior ServicePortal Developer / TechLead at Nuvolax

 

View solution in original post

10 REPLIES 10

@Rob Keeton and @Mark Roethof 

Feel free to look at my widget and implement it in your instance.y

Any tips or feedback are most welcome!

Community Alums
Not applicable

Great widget @Vanderlei ! I tested it in my PDI, but I didn't get it to work for catalog items mapped to multiple topics. It displayed the breadcrumbs from the first topic that it was tagged to. The topic in the taxonomy topic-field on catalog item, that breadcrumb was displayed. 
Have you seen this as well? Any thoughts on how to fix it? 

Unfortunately this is a problem.
This widget look to the taxonomy field on the catalog item,

I will try to upgrade this widget and then I share here ok?

I updated the server script to the following code to at least filter it down to one taxonomy (based on portal) and on top to (as an option) receive an additional topic_id parameter to override the behaviour of going for the first match:

(function() {
    function getSPParam(name) {
        var param = $sp.getParameter(name);
        if (param) param = (param + "").trim();
        return param;
    }

    data.breadcrumbs = [];
    var topicId = (input && input.topic_id) || options.topic_id || $sp.getParameter("topic_id");
    if (topicId) topicId = topicId + "";

    function getRootTaxonomies(portalGR) {
        var taxonomies = [];
        var grM2mSpPortalTaxonomy = new GlideRecord('m2m_sp_portal_taxonomy');
        grM2mSpPortalTaxonomy.addEncodedQuery("sp_portal=" + portalGR.sys_id + "^active=true^taxonomyISNOTEMPTY");
        grM2mSpPortalTaxonomy.orderBy('order');
        grM2mSpPortalTaxonomy.setLimit(10);
        grM2mSpPortalTaxonomy.query();
        while (grM2mSpPortalTaxonomy.next()) {
            taxonomies.push(grM2mSpPortalTaxonomy.taxonomy.sys_id + "");
        }
        if (taxonomies.length > 0) return taxonomies;
        return false;
    }

    function getContent(page, rootTaxonomies, topicId) {
        if (page, rootTaxonomies && rootTaxonomies.length > 0) {
            var query = false;
            var topicQuery = false;
            if (topicId) {
                var grTopic = new GlideRecord('topic');
                if (grTopic.get(topicId)) {
                    topicQuery = "topic=" + topicId;
                }
            }
            if (!topicQuery) {
                topicQuery = "topicISNOTEMPTY";
            }
            switch (page) {
                case "sc_cat_item":
                    var catItem = getSPParam("sys_id");
                    if (!gs.nil(catItem)) {
                        query = "catalog_item=" + catItem;
                    }
                    break;
                case "kb_article":
                    var kb = getSPParam("sys_id");
                    if (!gs.nil(kb)) {
                        query = "knowledge=" + kb;
                    }
                    break;
                default:
                    //ignore (for now?!)
            }

            if (query) {
                var grM2mConnectedContent = new GlideRecord('m2m_connected_content');
                grM2mConnectedContent.addEncodedQuery(query + "^" + topicQuery + "^topic.taxonomyIN" + rootTaxonomies.join(","));
                grM2mConnectedContent.orderBy('order');
                grM2mConnectedContent.setLimit(10);
                grM2mConnectedContent.query();
                if (grM2mConnectedContent.next()) {
                    return grM2mConnectedContent;
                }
            }
        }
        return false;
    }

    function getLabel(contentGR) {
        if (contentGR) {
			var label = false;
            if (contentGR.catalog_item) {
                label = contentGR.catalog_item.getDisplayValue('name');
            }
			if (contentGR.knowledge) {
				label = contentGR.knowledge.getDisplayValue('short_description');
			}
            if (label && !gs.nil(label)) {
                return {
                    "label": label + "",
                    "url": "#"
                };
            }
        }
        return false;
    }

    var page = getSPParam("id");
    var portalGr = $sp.getPortalRecord();
    var taxonomies = getRootTaxonomies(portalGr);

    if (topicId) {
        var grTopic = new GlideRecord('topic');
        if (!(taxonomies && grTopic.get(topicId) && grTopic.taxonomy && taxonomies.includes(grTopic.taxonomy.sys_id + ""))) {
            topicId = false;
        }
    }

    var content = getContent(page, taxonomies, topicId);
    if (content) {
        try {
            var breadcrumbs = new sn_ex_sp.TopicPageUtil().fetchBreadCrumbsForTopic(content.topic.sys_id + "");
            breadcrumbs.push(data.breadcrumbs.pop());
            if (!breadcrumbs[breadcrumbs.length - 1]) breadcrumbs.pop();
            var label = getLabel(content);
            if (label) breadcrumbs.push(label);
            data.breadcrumbs = breadcrumbs;
        } catch (e) {
            gs.error(e.getMessage());
            gs.addErrorMessage(gs.getMessage("Error occurred, please refer logs for information"));
        }
    }

})();

 

swostik
Tera Contributor

@Vanderlei can you suggest what I should do to have the HRM Back button instead of the breadcrumbs for sc_cat_item page for a specific portal. My requirement is to have the back button for a specific portal and breadcrumbs for all the remaining portals that uses the same page