Reputation: 22659
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
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