71 lines
3.0 KiB
Python
71 lines
3.0 KiB
Python
"""
|
|
Wrapper class that takes a list of template loaders as an argument and attempts
|
|
to load templates from them in order, caching the result.
|
|
"""
|
|
|
|
import hashlib
|
|
|
|
from django.conf import settings
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
from django.template import engines
|
|
from django.template import TemplateDoesNotExist
|
|
from django.template import Origin
|
|
|
|
from django.template.loaders.cached import Loader as DjangoCachedLoader
|
|
from django.template.loaders.filesystem import Loader as DjangoFilesystemLoader
|
|
|
|
from django.utils.encoding import force_bytes
|
|
from django.utils._os import safe_join
|
|
from django.db import connection
|
|
from tenant_schemas.utils import get_public_schema_name
|
|
|
|
|
|
class CachedLoader(DjangoCachedLoader):
|
|
def cache_key(self, template_name, template_dirs, skip=None):
|
|
key = super(CachedLoader, self).cache_key(template_name, template_dirs, skip=skip)
|
|
if connection.tenant:
|
|
return connection.tenant.domain_url + '-' + key
|
|
return key
|
|
|
|
|
|
class FilesystemLoader(DjangoFilesystemLoader):
|
|
def get_template_sources(self, template_name, template_dirs=None):
|
|
"""
|
|
Returns the absolute paths to "template_name", when appended to each
|
|
directory in "template_dirs". Any paths that don't lie inside one of the
|
|
template dirs are excluded from the result set, for security reasons.
|
|
"""
|
|
if not connection.tenant or connection.tenant.schema_name == get_public_schema_name():
|
|
return
|
|
if not template_dirs:
|
|
try:
|
|
template_dirs = settings.TENANT_TEMPLATE_DIRS
|
|
except AttributeError:
|
|
raise ImproperlyConfigured('To use %s.%s you must define the TENANT_TEMPLATE_DIRS' % (__name__, FilesystemLoader.__name__))
|
|
|
|
known_dirnames = ['templates', 'theme/templates']
|
|
if hasattr(settings, 'TEMPLATE_VARS'):
|
|
if settings.TEMPLATE_VARS.get('theme'):
|
|
theme_value = settings.TEMPLATE_VARS['theme']
|
|
known_dirnames = ['%s/variants/%s' % (x, theme_value) for x in known_dirnames] + known_dirnames
|
|
if settings.TEMPLATE_VARS.get('is_portal_agent'):
|
|
known_dirnames = ['%s/portal-agent' % x for x in known_dirnames] + known_dirnames
|
|
|
|
for template_dir in template_dirs:
|
|
for dirname in known_dirnames:
|
|
try:
|
|
template_path = safe_join(template_dir, connection.tenant.domain_url, dirname,
|
|
template_name)
|
|
except UnicodeDecodeError:
|
|
# The template dir name was a bytestring that wasn't valid UTF-8.
|
|
raise
|
|
except ValueError:
|
|
# The joined path was located outside of this particular
|
|
# template_dir (it might be inside another one, so this isn't
|
|
# fatal).
|
|
pass
|
|
|
|
yield Origin(template_path,
|
|
template_name=template_name,
|
|
loader=self,)
|