This article mainly introduces a simple example of compiling a custom Django template loader. Django is one of the most famous popular Python frameworks, you can refer to the built-in template loader of Djangos (described in the previous template loading insider chapter) to meet all your template loading requirements, however, if you have special loading requirements, writing your own template loader will be quite simple. For example, you can load templates from a database or Python library, or from a ZIP file.
The template loader, that is, every item in TEMPLATE_LOADERS, must be called by the following interface:
load_template_source(template_name, template_dirs=None)
The template_name parameter is the name of the loaded template (the same as the name passed to loader. get_template () or loader. select_template (), and template_dirs is an optional search directory list that replaces TEMPLATE_DIRS.
If the loader can successfully load a template, it should return a tuples: (template_source, template_path ). Here, template_source is the template string that will be compiled by the template engine, and template_path is the path of the loaded template. Because the path may be displayed to the user for debugging purposes, it should quickly specify where the template is loaded.
If the loader fails to load the template, the django. template. TemplateDoesNotExist exception is triggered.
Each function to be loaded should have a function attribute named is_usable. This attribute is a Boolean value used to tell the template engine whether the loader is available in the currently installed Python. For example, if the pkg_resources module is not installed, the eggs loader (which can load templates from python eggs) should set is_usable to False, because you must use pkg_resources to read data from eggs.
An example can clarify everything clearly. Here is a template loading function, which can load templates from the ZIP file. It uses custom settings TEMPLATE_ZIP_FILES to replace TEMPLATE_DIRS as the search path, and assumes that every file in this path is a ZIP file containing the template:
from django.conf import settingsfrom django.template import TemplateDoesNotExistimport zipfiledef load_template_source(template_name, template_dirs=None): "Template loader that loads templates from a ZIP file." template_zipfiles = getattr(settings, "TEMPLATE_ZIP_FILES", []) # Try each ZIP file in TEMPLATE_ZIP_FILES. for fname in template_zipfiles: try: z = zipfile.ZipFile(fname) source = z.read(template_name) except (IOError, KeyError): continue z.close() # We found a template, so return the source. template_path = "%s:%s" % (fname, template_name) return (source, template_path) # If we reach here, the template couldn't be loaded raise TemplateDoesNotExist(template_name)# This loader is always usable (since zipfile is included with Python)load_template_source.is_usable = True
The last step is to add it to TEMPLATE_LOADERS. If we add this code to a package named mysite.zip_loader, we need to add mysite.zip _ loader. load_template_source to TEMPLATE_LOADERS.