Zaur Nasibov
Zaur Nasibov

Reputation: 22659

Django cross-referencing application templates

I am refactoring a ton of legacy code based on Django. The project structure is as follows:

core_app
app1
app2
...

I've encountered the following pattern in various templates, e.g. in app1:

{% if "app2" in INSTALLED_APPS %}
  {% include app2/path/to/template.html %}
{% endif %}

Intuitively this looks very wrong to me. Is there a way to avoid such a tight coupling?

A complex solution that I have in mind is a providers/services mechanism, so that e.g. app2 provides service X, app1 calls {% include_service_X %}, so that app1 and app2 are unaware of each-other's existence.

Upvotes: 0

Views: 183

Answers (1)

catavaran
catavaran

Reputation: 45575

You can create the template named app/app2_inc.html with the following content:

{% if "app2" in INSTALLED_APPS %}
    {% include app2_tpl %}
{% endif %}

And the include it with the with parameter:

{% include "app1/app2_inc.html" with app2_tpl="app2/path/to/template.html" %}

As alternative option you can create custom template tag:

from django.conf import settings
from django.template.loader import render_to_string

@register.simple_tag(takes_context=True)
def include_app2(context, template_name):
    if 'app2' in settings.INSTALLED_APPS:
        return render_to_string(template_name, context)
    return ''

And then call it from your app1 templates:

{% load my_tags %}

{% include_app2 "app2/path/to/template.html" %}

UPDATE: If you want to silently ignore the case if the template does not exist then change the template tag to:

from django.template import TemplateDoesNotExist
from django.template.loader import render_to_string

@register.simple_tag(takes_context=True)
def include_if_exist(context, template_name):
    try:
        return render_to_string(template_name, context)
    except TemplateDoesNotExist:
        return ''

So now you can safely include any template from any app. If this template is not available then template tag will just ignore it:

{% load my_tags %}

{% include_if_exist "app2/path/to/template.html" %}

Upvotes: 1

Related Questions