CppLearner
CppLearner

Reputation: 17040

What is the right way to pass global template variables in Django?

Suppose this is what we want in every page, we'd create "base_template.html"

    <title>{% block title %}{{ page_title }}{% endblock %}</title>

    <a href="http://{{domain}}{{current_path}}">{{ page_title }}</a>{% endblock %}

Instead of passing page_title, domain, current_path from every view function such as:

def display_meta(request):
    user_meta = request.META.items()
    sorted_meta = sorted(user_meta)     # a list of tuples
    return render_to_response('meta.html', {'sorted_meta': sorted_meta, 
                              'current_path': request.get_full_path(), 
                              'domain': request.get_host(),
                              'page_title': display_meta.__name__})
# and repeat the dictionary same manner for other views....

#urls.py
('^book_list/$', 'object_get_list', {'model': models.Book}),

A different approach is wrapping view functions

# urls.py
('^book_list/$', views.get_template(views.object_get_list),{'model': models.Book}),

# views.py
def get_template(view, **extrakw):

    def wrapview(request, **extrakw):
        template_dict = {'current_path': request.get_full_path(), 'domain': request.get_host()}
        extrakw['template_dict'] = template_dict
        return view(request, **extrakw)
    return wrapview


def object_get_list(request, **kwargs):
    model = kwargs.pop('model', None)
    model_name = model.__name__.lower()
    template_dict = kwargs.pop('template_dict', None)
    template_dict[model_name] = model.objects.all()
    template_dict['page_title'] = model_name +" list"
    template_name = '%s.html' %(model_name)
    return render_to_response(template_name, template_dict)

Pro: Besides editing htmls, now modification is done in just one view, instead of every view.

Cons: Ugly URLConf and probably error propne too

Attempt 3: Create a global dictionary just like template_dict I created.

template_dict = {/..../}

def view1()
def view2() ...

Problem: I can't use request.path (or anything has to do with request). This falls back to the previous attempt (wrapper).

But there must be an easier way. What is the proper way of passing global template variables throughout a django site so each view function is now indepenednt of gloabl templat variables?

Thank you for you time.

Upvotes: 2

Views: 258

Answers (1)

Marcin
Marcin

Reputation: 49826

Use a context processor.

Add the name of your function to TEMPLATE_CONTEXT_PROCESSORS in settings.py.

A simple context processor I use is:

def common_request_parameters(request):
    return {'home_login_form': AuthenticationForm(request)}

Upvotes: 6

Related Questions