Skip to content

A simple, flexible, and extensible navigation menu for Django

License

Notifications You must be signed in to change notification settings

joshuadavidthomas/django-simple-nav

django-simple-nav

PyPI PyPI - Python Version Django Version

Define your navigation in Python, render it in templates. django-simple-nav handles URL resolution, active state detection, and permission filtering so your nav stays in sync with your project.

Requirements

  • Python 3.10, 3.11, 3.12, 3.13, 3.14
  • Django 4.2, 5.2, 6.0

Installation

uv add django-simple-nav
# or
python -m pip install django-simple-nav

Add django_simple_nav to your INSTALLED_APPS:

INSTALLED_APPS = [
    # ...,
    "django_simple_nav",
    # ...,
]

Getting Started

Define your navigation in a Python file. items is what gets rendered, and template_name points to the template that controls the markup:

# config/nav.py
from django_simple_nav.nav import Nav
from django_simple_nav.nav import NavGroup
from django_simple_nav.nav import NavItem


class MainNav(Nav):
    template_name = "main_nav.html"
    items = [
        NavItem(title="Home", url="/"),
        NavItem(title="About", url="/about/"),
        NavGroup(
            title="Resources",
            items=[
                NavItem(title="Blog", url="/blog/"),
                NavItem(title="Contact", url="/contact/"),
            ],
        ),
    ]

Create main_nav.html. The template receives the items defined above — each has a title, url, active state, and groups have nested items:

<!-- main_nav.html -->
<nav>
  <ul>
    {% for item in items %}
      <li>
        <a href="{{ item.url }}"{% if item.active %} class="active"{% endif %}>
          {{ item.title }}
        </a>
        {% if item.items %}
          <ul>
            {% for subitem in item.items %}
              <li>
                <a href="{{ subitem.url }}"{% if subitem.active %} class="active"{% endif %}>
                  {{ subitem.title }}
                </a>
              </li>
            {% endfor %}
          </ul>
        {% endif %}
      </li>
    {% endfor %}
  </ul>
</nav>

Then use the template tag wherever you want the nav to appear. The string is the import path to your Nav class:

{% load django_simple_nav %}

{% django_simple_nav "config.nav.MainNav" %}

Examples

The example directory contains a simple Django project that demonstrates how to use django-simple-nav, including navigation definitions for a few different scenarios and some popular CSS frameworks.

git clone https://github.com/joshuadavidthomas/django-simple-nav
cd django-simple-nav
uv sync
uv run example/demo.py runserver

Then open your browser to http://localhost:8000.

Documentation

For the full documentation — including permissions, extra context, Jinja2 support, self-rendering items, and more — please visit the documentation site.

License

django-simple-nav is licensed under the MIT license. See the LICENSE file for more information.

About

A simple, flexible, and extensible navigation menu for Django

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Sponsor this project