Los cargadores de plantillas incluidos con Django (descritos en la sección anterior "Etiquetas de inclusión") normalmente son suficientes para tus necesidades de carga de plantillas, pero es muy sencillo escribir el tuyo propio si necesitas alguna lógica especial en dicha carga. Por ejemplo podrías cargar plantillas desde una base de datos, o directamente desde un repositorio Subversion usando las librerías (bindings) Python de Subversion, o (como veremos) desde un archivo ZIP.
Un cargador de plantillas — esto es, cada entrada en la variables de
configuración TEMPLATE_LOADERS
— debe ser un objeto invocable (callable)
con la siguiente interfaz:
load_template_source(template_name, template_dirs=None)
El argumento template_name
es el nombre de la plantilla a cargar (tal como
fue pasado a loader.get_template()
o loader.select_template()
) y
template_dirs
es una lista opcional de directorios en los que se buscará en
lugar de TEMPLATE_DIRS
.
Si un cargador es capaz de cargar en forma exitosa una plantilla, debe retornar
una tupla: (template_source, template_path)
. Donde template_source
es la
cadena de plantilla que será compilada por la maquinaria de plantillas, y
template_path
es la ruta desde la cual fue cargada la plantilla. Dicha ruta
podría ser presentada al usuario para fines de depuración así que debe
identificar en forma rápida desde dónde fue cargada la plantilla.
Si al cargador no le es posible cargar una plantilla, debe lanzar
django.template.TemplateDoesNotExist
.
Cada función del cargador debe también poseer un atributo de función
is_usable
. Este es un Booleano que le informa a la maquinaria de plantillas
si este cargador está disponible en la instalación de Python actual. Por
ejemplo el cargador desde eggs (que es capaz de cargar plantillas desde eggs
Python) fija is_usable
a False
si el módulo pkg_resources
no se encuentra
instalado, porque pkg_resources
es necesario para leer datos desde eggs.
Un ejemplo ayudará a clarificar todo esto. Aquí tenemos una función cargadora
de plantillas que puede cargar plantillas desde un archivo ZIP. Usa una
variable de configuración personalizada TEMPLATE_ZIP_FILES
como una ruta
de búsqueda en lugar de TEMPLATE_DIRS
y espera que cada ítem en dicha ruta
sea un archivo ZIP contiendo plantillas:
import zipfile
from django.conf import settings
from django.template import TemplateDoesNotExist
def 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
El único paso restante si deseamos usar este cargador es agregarlo a la
variable de configuración TEMPLATE_LOADERS
. Si pusiéramos este código en un
paquete llamado mysite.zip_loader
entonces agregaremos
mysite.zip_loader.load_template_source
a TEMPLATE_LOADERS
.