Django: use global variables on rendering templates


Some settings or global value is used in every template or, for example, in base layout template. This value should be passed as context variable to each template. I call such value a global context variable in this post.

For instance, it can be a Google Analytics Code, which should be used in production, but not in staging or development environments. In this case, it’s fine to move GA code to the settings file (of course, if different settings used for different environments). Though need to find a way to get the value from the settings and pass it to the template context before rendering.


There are a few simple solutions that solve the described problem:
  1. Add global variable to the template context in every view. But according to DRY and good sense this is a bad solution.
  2. Write a tag to fetch setting value by name and output it. Nice solution and flexible enough in case we need to show different settings in different pages. The only disadvantage is fetching setting value each time it’s accessed. But in most cases this is a minor.
  3. Write a context processor. In the documentation said that context processor is a method that takes a request object as argument and returns a dictionary of items to be merged into the context. In other words, context processor returns a dictionary of items that will be available in template on render phase. In our case, we can get setting value and return from our own context processor method.

    from django.conf import settings
    def global_vars(request):
        return {'GA_CODE': settings.GA_CODE}
    Also, need to declare our context processor in settings.TEMPLATE_CONTEXT_PROCESSORS:

       . . . 
    From now, GA_CODE context variable can be used in any template, and will be processed correctly.

In my opinion, the best decision for fixed list of globally accessed template context variables is a custom context provider. It's also a right way, if most or all templates use same global variables. Otherwise, it's good to write a few tags to cover access to the global state, like settings.

No comments: