django include template from another app

DjangoTemplates

Django Problem Overview


While setting up my project and working to keep apps non-dependent, I've hit a snag. I'd like all of the templates from the different apps to have a consistent header and footer. Here's what I'm trying:

myproject/
         base/
             templates/
                      header.html
                      footer.html
         app1/
             templates/
                      my_app1_page.html -> want to include 'header.html'
                                           and 'footer.html' from base app

Pretend there are many more apps that want to do this as well. Is this possible and/or the right way to do it?

Django Solutions


Solution 1 - Django

As long as the apps are in INSTALLED_APPS and the template loader for apps dirs is enabled, you can include any template from another app, i.e.:

{% include "header.html" %}

... since your templates are located directly in the templates dir of your app. Generally, in order to avoid name clashes it is better to use:

app1/
    templates/
        app1/
            page1.html
            page2.html
app2/
    templates/
        app2/
            page1.html
            page2.html

And {% include "app1/page1.html" %} or {% include "app2/page1.html" %} ...

But: for keeping a consistent look and feel, it is so much better to use template inheritance rather than inclusion. Template inheritance is one of the really good things of the Django template system, choose inheritance over inclusion whenever it makes sense (most of the time).

My recommendations:

  • Have a base template for your project ("base.html" is the default convention) with header and footer and a {%block content%} for your main content.
  • Have your other templates inherit form base.html {% extends "base.html" %} and override the content section

See another response to this question for links to the doc

Solution 2 - Django

While you can certainly do that by using the include tag and specifying absolute paths, the proper way to work in Django is by using Template inheritance.

Solution 3 - Django

If you start a project with "$ django-admin startproject project" a folder named "project-folder-name" i.e. project/ is created. After adding a few apps and adding the apps in the "settings.py" -> INSTALLED_APPS=[..., app1, app2] and creating a templates folder within the project/ I got structure like this:

project/
    project/
        templates/
            base.html
    app1/
        templates/
            app1/
                page1.html
                page2.html
    app2/
        templates/
            app2/
                page1.html
                page2.html

in template app1/template/page1.html I wrote

{% extends 'base.html' %}
and the "TemplateDoesNotExist at /" Error message appeared.

Then I added another App named "core" and added base.html to the template folder (+edit INSTALLED_APPS in settings.py) and i got this structure now:

project/
    project/
        templates/    (unused)
            base.html (not seen)
    core/
        templates/
            base.html
    app1/
        templates/
            app1/
                page1.html
                page2.html
    [...]

Now the error message disappears and the base.html is found with templates/app1/page1.html:

{% extends 'base.html' %}

You can change the folder structure like this:

    core/
        templates/
            core/
                base.html

then you need to change the template app1/page1.html to

{% extends 'core/base.html' %}

as well.

As an alternative you can also add "your-project-name" in this explaination "project" into your settings file like this:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'project', # your project name main folder
    'core',
    'App1',
    'App2',
]

And now django finds the project/templates/base.html as well. However I don't know if this solution is recommended.

project/
    project/
        templates/    
            base.html (now it is found)

P.S. Thanks (my upvotes aren't counted yet) and comment me if this answer was somehow clear and understandable

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionScottView Question on Stackoverflow
Solution 1 - DjangoCarles BarrobésView Answer on Stackoverflow
Solution 2 - DjangoTiagoView Answer on Stackoverflow
Solution 3 - DjangoZykratesView Answer on Stackoverflow