113 lines
4.5 KiB
Python
113 lines
4.5 KiB
Python
# lint-amnesty, pylint: disable=missing-module-docstring
|
|
|
|
import logging
|
|
|
|
from django.conf import settings
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
from django.template import Engine, TemplateDoesNotExist, engines
|
|
from django.template.loaders.app_directories import Loader as AppDirectoriesLoader
|
|
from django.template.loaders.filesystem import Loader as FilesystemLoader
|
|
|
|
from common.djangoapps.edxmako.template import Template
|
|
from openedx.core.lib.tempdir import mkdtemp_clean
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class MakoLoader:
|
|
"""
|
|
This is a Django loader object which will load the template as a
|
|
Mako template if the first line is "## mako". It is based off Loader
|
|
in django.template.loaders.base.
|
|
We need this in order to be able to include mako templates inside main_django.html.
|
|
"""
|
|
|
|
is_usable = False
|
|
supports_recursion = True
|
|
|
|
def __init__(self, base_loader):
|
|
# base_loader is an instance of a BaseLoader subclass
|
|
self.base_loader = base_loader
|
|
|
|
module_directory = getattr(settings, 'MAKO_MODULE_DIR', None)
|
|
|
|
if module_directory is None:
|
|
log.warning("For more caching of mako templates, set the MAKO_MODULE_DIR in settings!")
|
|
module_directory = mkdtemp_clean()
|
|
|
|
self.module_directory = module_directory
|
|
|
|
def __call__(self, template_name, template_dirs=None):
|
|
return self.load_template(template_name)
|
|
|
|
# pylint: disable=unused-argument
|
|
def get_template(self, template_name, template_dirs=None, skip=None):
|
|
return self.load_template(template_name)
|
|
|
|
def load_template(self, template_name):
|
|
"""
|
|
Method returns loads and returns template if it exists
|
|
"""
|
|
source, origin = self.load_template_source(template_name)
|
|
|
|
# In order to allow dynamic template overrides, we need to cache templates based on their absolute paths
|
|
# rather than relative paths, overriding templates would have same relative paths.
|
|
module_directory = self.module_directory.rstrip("/") + "/{dir_hash}/".format(dir_hash=hash(origin.name))
|
|
|
|
if source.startswith("## mako\n"):
|
|
# This is a mako template
|
|
template = Template(filename=origin.name,
|
|
module_directory=module_directory,
|
|
input_encoding='utf-8',
|
|
output_encoding='utf-8',
|
|
default_filters=['decode.utf8'],
|
|
encoding_errors='replace',
|
|
uri=template_name,
|
|
engine=engines['mako'])
|
|
return template
|
|
else:
|
|
# This is a regular template
|
|
try:
|
|
template = Engine.get_default().from_string(source)
|
|
return template
|
|
except ImproperlyConfigured: # lint-amnesty, pylint: disable=try-except-raise
|
|
# Either no DjangoTemplates engine was configured -or- multiple engines
|
|
# were configured, making the get_default() call above fail.
|
|
raise
|
|
except TemplateDoesNotExist:
|
|
# If compiling the loaded template raises TemplateDoesNotExist, back off to
|
|
# returning the source and display name for the requested template.
|
|
# This allows for eventual correct identification of the actual template that does
|
|
# not exist.
|
|
return source, origin.name
|
|
|
|
def load_template_source(self, template_name):
|
|
"""
|
|
Method returns the contents of the template
|
|
"""
|
|
for origin in self.base_loader.get_template_sources(template_name):
|
|
try:
|
|
return self.base_loader.get_contents(origin), origin
|
|
except TemplateDoesNotExist:
|
|
pass
|
|
raise TemplateDoesNotExist(template_name)
|
|
|
|
def reset(self):
|
|
self.base_loader.reset()
|
|
|
|
|
|
class MakoFilesystemLoader(MakoLoader): # lint-amnesty, pylint: disable=missing-class-docstring
|
|
is_usable = True
|
|
_accepts_engine_in_init = True
|
|
|
|
def __init__(self, *args):
|
|
MakoLoader.__init__(self, FilesystemLoader(*args)) # lint-amnesty, pylint: disable=no-value-for-parameter
|
|
|
|
|
|
class MakoAppDirectoriesLoader(MakoLoader): # lint-amnesty, pylint: disable=missing-class-docstring
|
|
is_usable = True
|
|
_accepts_engine_in_init = True
|
|
|
|
def __init__(self, *args):
|
|
MakoLoader.__init__(self, AppDirectoriesLoader(*args)) # lint-amnesty, pylint: disable=no-value-for-parameter
|