Navigation
You are here: Home Things we build Code snippets Making Plone's dropdown menu work with your Bootstrap template

Making Plone's dropdown menu work with your Bootstrap template

Posted by Karel Calitz |
Bootstrap's navigation bar is a very good way of using the same navigation for both desktop and mobile devices. Using Plone's navigation structure for this requires some simple XSL transforms in your Diazo rules.

View our implementation of the solution here.

Please note that we are using the WebCouturier Dropdown Menu, as it gives us the right starting structure.

The problem

The structure that we get from the menu doesn't have the same classes or toggles to ensure that the menu triggers as it should. To change this, we need to identify specific tags and change them accordingly.

You can see more about the structure that is needed here.

The solution

There are two parts to this solution. We will identify the item that needs to change in the main rules file, and then run an external rules file for each of these items. You could probably consolidate this into one rules file, but I find that this keeps it nice and tidy.

Step 1

In the main rules.xml, add this:

<replace css:theme-children="#portal-globalnav">
    <xsl:for-each css:select="#portal-globalnav > li">
        <xi:include href="navigation-rules.xml"/>
    </xsl:for-each>
</replace>

Here we identify that the change needs to happen for each li within the main nav ul.

You will also need to add

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xi="http://www.w3.org/2001/XInclude"

in your main <rules> tag.

Step 2

Create a second rules file called navigation-rules.xml (as we have referenced that in the main rules.xml file.

<?xml version="1.0" encoding="UTF-8"?>

<xsl:if test="*"
    xmlns="http://namespaces.plone.org/diazo"
    xmlns:css="http://namespaces.plone.org/diazo/css"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xi="http://www.w3.org/2001/XInclude"
>

    <xsl:if test="not(ul)">
        <li><xsl:attribute name="class">
            <xsl:if test="contains(@class,'selected')">
                active
            </xsl:if>
            </xsl:attribute>
            <xsl:copy-of select="a[node()]"/>
        </li>
    </xsl:if>

    <xsl:if test="ul">
        <li class="dropdown">
            <a class="dropdown-toggle" data-toggle="dropdown" href="#">
                <xsl:copy-of select="a/node()"/>
                <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
                <xsl:copy-of select="ul/node()"/>
            </ul>
        </li>
    </xsl:if>

</xsl:if>

This file will run an action for each li within the #portal-globalnav ul, identifying whether it is an li or ul (which is the submenu) and applying tags accordingly.

We have only tested this on single level dropdowns, but feel free to try it on deeper navigation, and let us know what kind of results you get.

Find out how Juizi can help your business