Ace_Gentile
Ace_Gentile

Reputation: 244

django: side menu template visible everywhere

I need to create a side menu in my django admin that should appear in all pages. Ideally my template should be a generic navigation.html file containing this code and parsing app_list param (the same that is used into index.html template populating the dashboard):

{% block side_menu %}
{% if app_list %}
    {% for app in app_list %}
        <ul class="sidebar-menu app-{{ app.app_label }} module">
         <li class="treeview">
           <a href="#">
            <i class="fa fa-dashboard"></i> <span>{{ app.name | truncatechars:"25" }}</span>
            <span class="pull-right-container">
              <i class="fa fa-angle-left pull-right"></i>
            </span>
          </a>

        {% for model in app.models %}
        <ul class="treeview-menu">
            {% if model.admin_url %}
                <li><a href="{{ model.admin_url }}"><strong>{{ model.name }}</strong></a></li>
            {% else %}
                <li>{{ model.name }}</li>
            {% endif %}

            {% if model.add_url %}
                <li><a href="{{ model.add_url }}"><i class="fa fa-plus"></i> {% trans 'Add' %}</a></li>
            {% else %}
                <td>&nbsp;</td>
            {% endif %}

            {% if model.admin_url %}
                <li><a href="{{ model.admin_url }}"><i class="fa fa-pencil-square-o"></i> {% trans 'Change' %}</a></li>
            {% else %}
                <td>&nbsp;</td>
            {% endif %}
        </ul>
        {% endfor %}
        </li>
      </ul>
    {% endfor %}
{% else %}
    <p>{% trans "You don't have permission to edit anything." %}</p>
{% endif %}
{% endblock side_menu %}

My questions are:

1) how can I include my new navigations.html template in all pages?

2) how can I pass to this template the app_list dictionary?

Thanx in advance

Upvotes: 1

Views: 3815

Answers (1)

Jens Astrup
Jens Astrup

Reputation: 2454

1) It looks like you're on the right track - you have {% block %}. You just need to have your other files extend that navigation file (you may want to just make it base.html, like the documentation in the link, and have it contain everything all pages should have) and allow those pages to add their own content.

Make it so navigations.html allows a body:

<html>
    {% block side_menu %}
        ...
    {% endblock side_menu %}
    <body>
        {% block body %}
        {% endblock body %}
    </body>
</html>

Then at the top of every template:

{% extends 'my_app/navigations.html' %}

with that templates content inside of the {% block body %}.

2) You can make a template context processor that passes the context to every template. They're very simple, per the documentation:

It’s a Python function that takes one argument, an HttpRequest object, and returns a dictionary that gets added to the template context

So:

def my_context_processor(request):
    apps = App.objects.all()
    return {'app_list': apps}

and in your settings:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                # Other context processors....
                'my_app.processors.my_context_processor',
            ],
        },
    },
]

Now in every template, you can do {% for app in app_list %} without needing your view to return that context.

Upvotes: 2

Related Questions