How to Provide Breadcrumbs for Page with dynamic Parameters?

admin

Administrator
Staff member
I found a Grails framework for generating Breadcrumbs <a href="https://adityakalia.wordpress.com/2011/01/10/breadcrumbs-framework-for-grails/" rel="nofollow">here</a>. It does generate breadcrumbs based on a static definition in a breadcrumbs.xml file where it defines the hierarchies of the crumbs:

Code:
     &lt;map&gt;
        &lt;nav id="homeCrumb" matchController="samplePages" matchAction="homeBreadCrumbPage"&gt;
            &lt;!-- levels navigation --&gt;
            &lt;nav id="itemsLevel1Crumb" matchController="samplePages" matchAction="level1BreadCrumbPage"&gt;
                &lt;nav id="itemsLevel2Crumb" matchController="samplePages" matchAction="level2BreadCrumbPage"&gt;
                    &lt;nav id="itemsLevel3Crumb" matchController="samplePages" matchAction="level3BreadCrumbPage"&gt;
                        &lt;nav id="showItemCrumb" matchController="samplePages" matchAction="itemDetailsBreadCrumbPage"/&gt;
                    &lt;/nav&gt;
                &lt;/nav&gt;
            &lt;/nav&gt;
            &lt;nav id="simple1Crumb" matchController="samplePages" matchAction="simpleBreadCrumb"/&gt;
            &lt;nav id="simple2Crumb" matchController="samplePages" matchAction="simpleBreadCrumbWithAttr"/&gt;
            &lt;!-- levels navigation --&gt;
        &lt;/nav&gt;
    &lt;/map&gt;

This file is evaluated and printed by a taglib:

Code:
class BreadCrumbTagLib {

    static def log = LogFactory.getLog("grails.app.breadCrumbTag")

    def breadCrumb = { attrs , body -&gt;

            def manager = BreadCrumbManager.getInstance()
            def uri = request.getRequestURI() 
            def context = request.getContextPath() 

            def controller = params.controller
            def action = params.action

            def attrTitle =  attrs.title
            def attrLink = attrs.link

            // if controller and action are missing from params try to get them from request url
            if (!controller &amp;&amp; !action &amp;&amp; uri &amp;&amp; context &amp;&amp; uri.indexOf(context) != -1) {
                def uriParams = uri.substring(uri.indexOf(context) + (context.length() + 1), uri.length())
                def uriArray = uriParams.split('/')

                if (uriArray.size() &gt;= 2 ) {
                    controller = uriArray[0]
                    action = uriArray[1]                       
                }
            }

            def crumbs = manager.getBreadCrumbs(controller, action)

            if (crumbs) {
                out &lt;&lt; '&lt;div class="breadcrumb"&gt;&lt;ul&gt;'
                def size = crumbs.size()
                crumbs.eachWithIndex { crumb, index -&gt;
                    out &lt;&lt; '&lt;li&gt;'

                    // override title and link of breadcrumb on current page (i.e. last bread crumb in hierarchy)
                    // if name, link attributes are supplied
                    if (index == size - 1) {
                        if (attrTitle)
                            crumb.title = attrTitle
                        if (attrLink)
                            crumb.link = attrLink
                    }
                    // set title to undefined if not found, associated 
                    // renderer if present can overwrite it
                    if (!crumb.title)
                        crumb.title = "undefined"
                    if (crumb.title &amp;&amp; crumb.title.size() &gt; 40)
                        crumb.title = crumb.title.substring(0, 40) + "..."

                    if (crumb.viewController &amp;&amp; crumb.viewAction) {
                        def content = g.include(controller:crumb.viewController, action:crumb.viewAction, breadcrumb:crumb, params:params)
                        out &lt;&lt; content
                    } else if (crumb.viewTemplate) {
                        def content = g.include(view:crumb.viewTemplate, breadcrumb:crumb, params: params)
                        out &lt;&lt; content
                    } else if (crumb.linkToController &amp;&amp; crumb.linkToAction &amp;&amp; (size - 1 &gt; index)){
                        out &lt;&lt; "&lt;a href=\"${g.createLink (controller: crumb.linkToController, action: crumb.linkToAction)}\"&gt;${crumb.title}&lt;/a&gt;"
                    // if crumb has a link and its not the last vread crumb then show link else
                    // just show the text
                    } else if (crumb.link &amp;&amp; (size - 1 &gt; index)){
                        out &lt;&lt; "&lt;a href=\"${crumb.link}\"&gt;${crumb.title}&lt;/a&gt;"
                    } else {
                        out &lt;&lt; "${crumb.title}"
                    }
                    out &lt;&lt; "&lt;/li&gt;"
                    // do not print for last bread crumb
                    if (size - 1 &gt; index)
                        out &lt;&lt; "&lt;li&gt;&amp;raquo;&lt;/li&gt;"
                }
                out &lt;&lt; "&lt;/ul&gt;&lt;/div&gt;"
            }
    }
}

Problem: When I have a structure where I need some params which are not fix.

Example: I am in the third level of navigation lets say

Code:
A1 / A2 / A3

In my case
Code:
A2
should open a page like
Code:
user/show/1234
where 1234 is the id of the user to show. The problem is that I cannot add 1234 hard coded in the breadcrumbs.xml file because this id changes depending on which user you want to show.

<strong>How can I handle this when an intermediate breadcrumbs link needs dynamic parameters?</strong>