Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save bgarrant/0683b7b69691853fce1fc3767250142b to your computer and use it in GitHub Desktop.
Save bgarrant/0683b7b69691853fce1fc3767250142b to your computer and use it in GitHub Desktop.
Multi-level Bootstrap 4 Navbar With Craft 3 (No Plugins)

Multi-level Bootstrap 4 Navbar With Craft 3 (No Plugins)

You want to setup a Bootstrap 4 Navbar and use native functions in Craft 3 to manage the navigation menu.

This was built for Bootstrap v4.0 and Craft CMS 3.0.0-RC9

Step 1: Install Craft 3

Go to https://github.com/craftcms/docs/blob/v3/en/installation.md and install Craft 3.

Step 2: Download and Install latest Bootstrap 4 build

Currently v4.0 which you can get at https://getbootstrap.com.

Step 3: Build Navigation in Craft 3 using a Structure 2 Level Section

Setup your 2 level Structure section for navigation in Craft 3. Call the section Navigation so the handle is navigation.

Setup four fields as follows:

Name: Link to a Site Asset

  • Handle: siteAssetLink
  • Instructions: Use this link type to link to any uploaded Asset on your site (PDFs, documents, images, etc.)
  • Field Type: Assets
  • Sources: All
  • Limit: 1

Name: Link to a Site Page

  • Handle: sitePageLink
  • Instructions: Use this link type to link to any other Page or Entry on your site
  • Field Type: Entries
  • Sources: All
  • Limit: 1
  • Selection Label: Add a Page

Name: Offsite Link

  • Handle: offsiteLink
  • Instructions: Use this link type to link to any URL outside of your website. Enter the full URL you would like to link * to including the http://
  • Field Type: URL

Name: Open In New Window

  • Handle: openInNewWindow
  • Instructions: Toggle this switch to Open this Link in a new browser tab or window
  • Field Type: Lightswitch
  • Default Value: off

Setup three Entry Types as follows in your Navigation Structure section:

Name: Internal Site Link

  • Handle: internalSiteLink
  • Show the Title Field: checked
  • Title Field Label: Title
  • Fields: Link to a Site Page

Name: Internal Asset Link

  • Handle: internalAssetLink
  • Show the Title Field: checked
  • Title Field Label: Title
  • Fields: Link to a Site Asset, Open in New Window

Name: Offsite Link

  • Handle: offsiteLink
  • Show the Title Field: checked
  • Title Field Label: Title
  • Fields: Offsite Link, Open in New Window

Step 4: Code it out

Setup your template code as follows:

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="{{ siteUrl }}">{{ siteName }}</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarNavDropdown">

    {% set navigation = craft.entries.section('navigation') %}

    <ul class="navbar-nav mr-auto">
      {% nav node in navigation.level(1).all() %}
      {% if node.hasDescendants() %}

      <li class="nav-item dropdown">
        {% if node.type == 'internalSiteLink' %}
          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown{{ node.id }}" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ node.title }}</a>
        {% elseif node.type == 'internalAssetLink' %}
          {% set asset = node.siteAssetLink.one() %}
          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown{{ node.id }}" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ node.title }}</a>
        {% elseif node.type == 'offsiteLink' %}
          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown{{ node.id }}" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ node.title }}</a>
        {% endif %}
        <div class="dropdown-menu" aria-labelledby="navbarDropdown{{ node.id }}">
          {% set nodeSubs = node.getChildren() %}
          {% for nodeSub in nodeSubs.all() %}
            {% if nodeSub.type == 'internalSiteLink' %}
              <a class="dropdown-item" href="{{ nodeSub.sitePageLink[0].url }}">{{ nodeSub.title }}</a>
            {% elseif nodeSub.type == 'internalAssetLink' %}
              {% set asset = nodeSub.siteAssetLink.one() %}
              <a class="dropdown-item" href="{{ asset.url }}" {% if nodeSub.openInNewWindow %} target="_blank" {% endif %}>{{ nodeSub.title }}</a>
            {% elseif nodeSub.type == 'offsiteLink' %}
              <a class="dropdown-item" href="{{ nodeSub.offsiteLink }}" {% if nodeSub.openInNewWindow %} target="_blank" {% endif %}>{{ nodeSub.title }}</a>
            {% endif %}
          {% endfor %}
        </div>
      </li>

      {% else %}

      <li class="nav-item">
        {% if node.type == 'internalSiteLink' %}
          <a class="nav-link" href="{{ node.sitePageLink[0].url }}">{{ node.title }}</a>
        {% elseif node.type == 'internalAssetLink' %}
          {% set asset = node.siteAssetLink.one() %}
          <a class="nav-link" href="{{ asset.url }}" {% if node.openInNewWindow %} target="_blank" {% endif %}>{{ node.title }}</a>
        {% elseif node.type == 'offsiteLink' %}
          <a class="nav-link" href="{{ node.offsiteLink }}" {% if node.openInNewWindow %} target="_blank" {% endif %}>{{ node.title }}</a>
        {% endif %}
      </li>

      {% endif %}
      {% endnav %}
    </ul>

  </div><!--/.navbar-collapse -->
</nav>

As new Bootstrap 4 and Craft 3 releases come out you may need to tweak the code. Just watch their changelogs for any changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment