Menu System¶
Django Gentelella Widgets provides a flexible menu system through the MenuItem model. Menus can be displayed in the top navigation bar, sidebar, or sidebar footer, and support hierarchical structures, permissions, and custom widgets.
MenuItem Model¶
The MenuItem model stores menu configuration in the database and supports tree-based hierarchies using django-tree-queries.
Fields¶
Field |
Type |
Description |
|---|---|---|
|
CharField |
Display text for the menu item |
|
CharField |
URL pattern name (for reversed URLs) or direct URL path |
|
CharField |
Menu location: |
|
BooleanField |
If True, |
|
CharField |
Keyword arguments for URL reverse (format: |
|
CharField |
Positional arguments for URL reverse (comma-separated, can use context like |
|
BooleanField |
If True, |
|
CharField |
CSS class for icon (e.g., |
|
BooleanField |
If True, only display icon without title (useful for footer) |
|
IntegerField |
Order of items within the same parent |
|
ForeignKey |
Parent MenuItem for hierarchical menus (None for top-level) |
|
ManyToManyField |
Permissions required to view this menu item |
Menu Categories¶
djgentelella supports three menu locations:
- main - Top Navigation Bar
Horizontal menu in the top navigation area. Supports dropdowns for child items.
- sidebar - Left Sidebar
Vertical menu in the left sidebar. Supports multiple levels of nesting with collapsible sections.
- sidebarfooter - Sidebar Footer
Icons displayed at the bottom of the sidebar. Typically used for settings, logout, and help widgets.
Template Tags¶
Load the menu template tags in your template:
{% load gentelellamenu %}
Available Tags¶
{% top_menu %}Renders the top navigation bar menu (category
'main').{% sidebar_menu %}Renders the sidebar menu (category
'sidebar').{% footer_sidebar_menu %}Renders the sidebar footer icons (category
'sidebarfooter').{% render_external_widget %}Renders content for any menu widgets. Place this where widget content should appear.
{% render_menu_js_widget %}Renders JavaScript for menu widgets. Place this in the JS block.
{% render_extra_html_menu %}Renders additional HTML for menu widgets (modals, etc.).
Example Template¶
{% extends 'gentelella/base.html' %}
{% load gentelellamenu %}
{% block sidebar %}
{% sidebar_menu %}
{% endblock %}
{% block top_navigation %}
{% top_menu %}
{% endblock %}
{% block content %}
{% render_external_widget %}
<!-- Your content here -->
{% endblock %}
{% block js %}
{% render_menu_js_widget %}
{% endblock %}
Creating Menu Items¶
Basic Link¶
A simple link without URL reversal:
from djgentelella.models import MenuItem
MenuItem.objects.create(
title='Home',
url_name='/',
category='sidebar',
is_reversed=False,
icon='fa fa-home'
)
With Django URL Reverse¶
Link to a named URL pattern:
MenuItem.objects.create(
title='Dashboard',
url_name='dashboard',
category='sidebar',
is_reversed=True,
icon='fa fa-tachometer'
)
With URL Parameters (kwargs)¶
Pass keyword arguments to the URL reverse:
MenuItem.objects.create(
title='Edit User',
url_name='user_edit',
category='sidebar',
is_reversed=True,
reversed_kwargs='pk:1', # Results in reverse('user_edit', kwargs={'pk': 1})
icon='fa fa-user'
)
With Dynamic Context¶
Access template context values like request.user.pk:
MenuItem.objects.create(
title='My Profile',
url_name='user_profile',
category='sidebar',
is_reversed=True,
reversed_args='request.user.pk', # Dynamic value from context
icon='fa fa-user-circle'
)
Hierarchical Menus¶
Create parent-child relationships for nested menus:
# Create parent
settings_menu = MenuItem.objects.create(
parent=None,
title='Settings',
url_name='#',
category='sidebar',
is_reversed=False,
icon='fa fa-cog'
)
# Create children
MenuItem.objects.create(
parent=settings_menu,
title='General',
url_name='settings_general',
category='sidebar',
is_reversed=True,
icon='fa fa-sliders'
)
MenuItem.objects.create(
parent=settings_menu,
title='Security',
url_name='settings_security',
category='sidebar',
is_reversed=True,
icon='fa fa-shield'
)
Custom Widgets¶
Use a custom widget class for special menu functionality:
from django.urls import reverse
MenuItem.objects.create(
title='', # Widget handles its own title
url_name='djgentelella.notification.widgets.NotificationMenu',
category='main',
is_reversed=False,
reversed_args=reverse('notifications'), # API URL for widget
is_widget=True,
icon='fa fa-bell'
)
With Permissions¶
Restrict menu visibility based on Django permissions:
from django.contrib.auth.models import Permission
perm = Permission.objects.get(codename='can_manage_users')
item = MenuItem.objects.create(
title='User Management',
url_name='user_list',
category='sidebar',
is_reversed=True,
icon='fa fa-users'
)
item.permission.add(perm) # Only visible to users with this permission
Sidebar Footer Items¶
Create icon-only items for the sidebar footer:
MenuItem.objects.create(
title='Logout',
url_name='/accounts/logout/',
category='sidebarfooter',
is_reversed=False,
icon='fa fa-power-off',
only_icon=True
)
Using Django Admin¶
Menu items can also be managed through the Django admin interface. The MenuItem model is registered with the admin and supports:
Creating and editing menu items
Setting parent-child relationships
Assigning permissions
Ordering items by position
Management Commands¶
The demo application includes commands for creating sample menus:
python manage.py createdemoCreates a full demo menu structure with all widget examples, blog, dashboard, and various form widgets.
python manage.py demomenuCreates a simple menu structure for basic testing.
These commands can serve as reference for creating your own menu structures programmatically.
Complete Example¶
Here’s a complete example creating a typical application menu:
from django.urls import reverse
from djgentelella.models import MenuItem
def create_application_menu():
# Clear existing menu
MenuItem.objects.all().delete()
# Home section
home = MenuItem.objects.create(
title='Home',
url_name='/',
category='sidebar',
is_reversed=False,
icon='fa fa-home',
position=0
)
# Dashboard under Home
MenuItem.objects.create(
parent=home,
title='Dashboard',
url_name='dashboard',
category='sidebar',
is_reversed=True,
icon='fa fa-tachometer',
position=0
)
# Reports section
reports = MenuItem.objects.create(
title='Reports',
url_name='#',
category='sidebar',
is_reversed=False,
icon='fa fa-bar-chart',
position=1
)
MenuItem.objects.create(
parent=reports,
title='Sales Report',
url_name='report_sales',
category='sidebar',
is_reversed=True,
icon='fa fa-line-chart',
position=0
)
MenuItem.objects.create(
parent=reports,
title='User Report',
url_name='report_users',
category='sidebar',
is_reversed=True,
icon='fa fa-users',
position=1
)
# Footer items
MenuItem.objects.create(
title='Settings',
url_name='settings',
category='sidebarfooter',
is_reversed=True,
icon='fa fa-cog',
only_icon=True,
position=0
)
MenuItem.objects.create(
title='Logout',
url_name='/accounts/logout/',
category='sidebarfooter',
is_reversed=False,
icon='fa fa-power-off',
only_icon=True,
position=1
)
# Notification widget in top bar
MenuItem.objects.create(
title='Notifications',
url_name='djgentelella.notification.widgets.NotificationMenu',
category='main',
is_reversed=False,
reversed_args=reverse('notifications'),
is_widget=True,
icon='fa fa-bell',
position=0
)