Inheritance Paths and Template Location¶
Contents
In addition, you can also render the normal Django API way.
Template Inheritance Across Apps¶
You may have noticed that this tutorial has focused on a single app. Most projects consist of many apps. For example, a sales site might have an app for user management, an app for product management, and an app for the catalog and sales/shopping-cart experience. All of these apps probably want the same look and feel, and all of them likely want to extend from the same base.htm
file.
When you run python3 manage.py dmp_startapp <appname>
, you get new base.htm
and base_ajax.htm
files each time. This is done to get you started on your first app. On your second, third, and subsequent apps, you probably want to delete these starter files and instead extend your templates from the base.htm
and base_ajax.htm
files in your first app.
In my projects, I usually place all the common files in the homepage
app. I delete base.htm
and base_ajax.htm
from all other apps. Homepage contains the common html code, site-wide CSS, and site-wide Javascript.
DMP supports cross-app inheritance by including your project root (e.g. settings.BASE_DIR
) in the template lookup path. All you need to do is use the full path (relative to the project root) to the template in the inherits statement.
Suppose I have the following app structure:
myproject/
account/
__init__.py
media/
scripts/
styles/
templates/
login.html
views/
__init__.py
homepage/
__init__.py
media/
scripts/
styles/
templates/
base_ajax.htm
base.htm
index.html
views/
__init__.py
I set account/templates/login.html
to extend from homepage/templates/base.htm
using the following code at the top of the template:
<%inherit file="/homepage/templates/site_base.htm" />
Again, the front slash in the name above tells DMP to start the lookup at the project root.
In fact, my pages are often three inheritance levels deep:homepage/templates/base.htm -> account/templates/app_base.htm -> account/templates/index.html
to provide for site-wide page code, app-general page code, and specific page code.
Templates in Other Apps¶
Most of the time, you’ll render templates in the request’s current app. This is easy with request.dmp.render(...)
.
Infrequently, you’ll likely need to render templates in apps other than the current one. There’s two ways to do it:
- Method 1: Use the
render_template
convenience function: from django.conf import settings from django.http import HttpResponse from django_mako_plus import view_function, render_template from datetime import datetime @view_function def process_request(request): context = { 'now': datetime.now(), } # replace 'homepage' with the name of any DMP-enabled app: return HttpResponse(render_template(request, 'homepage', 'index.html', context))
- Method 2: Use the standard Django API:
from django.conf import settings from django.shortcuts import render from django_mako_plus import view_function from datetime import datetime @view_function def process_request(request): context = { 'now': datetime.now(), } # replace 'homepage' with the name of any DMP-enabled app: return render(request, 'homepage/index.html', context)
Content Types and Status Codes¶
The request.dmp.render()
function determines the mime type from the template extension and returns a 200 status code. What if you need to return JSON, CSV, or a 404 not found? The function takes these parameters too. A few examples:
from django.http import HttpResponse
# return CSV
return request.dmp.render('my_csv.html', {}, content_type='text/csv')
# return a custom error page
return request.dmp.render('custom_error_page.html', {}, status=404)
# specify a different template charset (or set globally in settings.py)
return request.dmp.render('im_old.html', {}, content_type='cp1252')
Changing the Template Location (globally)¶
Suppose your templates are located in a directory outside your normal project root. For whatever reason, you don’t want to put your templates in the app/templates directory.
Case 1: Templates Within Your Project Directory¶
If the templates you need to access are within your project directory, no extra setup is required. Simply reference those templates relative to the root project directory. For example, to access a template located at BASE_DIR/homepage/mytemplates/sub1/page.html, use the following:
return request.dmp.render('/homepage/mytemplates/sub1/page.html', context)
Note the starting slash on the path. That tells DMP to start searching at your project root.
Don’t confuse the slashes in the above call with the slash used in Django’s render
function. When you call render
, the slash separates the app and filename. The above call uses request.dmp.render
, which is a different function. You should really standardize on one or the other throughout your project.
Case 2: Templates Outside Your Project Directory¶
Suppose your templates are located on a different disk or entirely different directory from your project. DMP allows you to add extra directories to the template search path through the TEMPLATES_DIRS
setting. This setting contains a list of directories that are searched by DMP regardless of the app being referenced. To include the /var/templates/
directory in the search path, set this variable as follows:
'TEMPLATES_DIRS': [
'/var/templates/',
],
Suppose, after making the above change, you need to render the ‘/var/templates/page1.html’ template:
return request.dmp.render('page1.html', context)
DMP will first search the current app’s templates
directory (i.e. the normal way), then it will search the TEMPLATES_DIRS
list, which in this case contains /var/templates/
. Your page1.html
template will be found and rendered.
Cleaning Up¶
DMP caches its compiled mako+templates in subdirectories of each app. The default locations for each app are app/templates/__dmpcache__
, app/scripts/__dmpcache__
, and app/styles/__dmpcache__
, although the exact name depends on your settings.py. Normally, these cache directories are hidden and warrant your utmost apathy. However, there are times when DMP fails to update a cached template as it should. Or you might just need a pristine project without these generated files. This can be done with a Unix find command or through DMP’s dmp_cleanup
management command:
# see what would be be done without actually deleting any cache folders
python3 manage.py dmp_cleanup --trial-run
# really delete the folders
python3 manage.py dmp_cleanup
# see what would be be done without actually deleting any cache folders
python manage.py dmp_cleanup --trial-run
# really delete the folders
python manage.py dmp_cleanup
With this management command, add --verbose
to the command to include messages about skipped files, and add --quiet
to silence all messages (except errors).