Skip to content

Instantly share code, notes, and snippets.

@mtayseer
Last active February 16, 2017 13:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mtayseer/fb4ad0991b0a5d7e2dd2 to your computer and use it in GitHub Desktop.
Save mtayseer/fb4ad0991b0a5d7e2dd2 to your computer and use it in GitHub Desktop.
Load templates (even included & extended templates) based on Mezzanine HOST_THEME
import os
import sys
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.template.base import TemplateDoesNotExist
from django.template.loaders.app_directories import Loader as BaseLoader
from django.utils._os import safe_join
from django.utils.importlib import import_module
from django.utils import six
from mezzanine.core.request import current_request
try:
from collections import OrderedDict
except ImportError:
from django.utils.datastructures import SortedDict as OrderedDict
# Copied from django.template.loaders.app_directories
# At compile time, cache the directories to search.
def get_template_dir(app):
try:
mod = import_module(app)
except ImportError as e:
raise ImproperlyConfigured('ImportError %s: %s' % (app, e.args[0]))
template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
if os.path.isdir(template_dir):
if six.PY2:
template_dir = template_dir.decode(fs_encoding)
return template_dir
if six.PY2:
fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
app_template_dirs = tuple(filter(os.path.isdir, filter(None, map(get_template_dir, settings.INSTALLED_APPS))))
class Loader(BaseLoader):
is_usable = True
def get_template_sources(self, template_name, template_dirs=None):
HOST_THEMES = getattr(settings, 'HOST_THEMES', None)
if not HOST_THEMES:
return
HOST_THEMES = OrderedDict(HOST_THEMES)
assert len(HOST_THEMES) >= 1, "There should be at least one item defined in HOST_THEMES"
host_name = current_request().get_host().split(':')[0].lower()
if host_name not in HOST_THEMES:
return
host_template_dir = get_template_dir(HOST_THEMES[host_name])
if not template_dirs:
template_dirs = app_template_dirs
# Here is the magic: we add the path of the host theme before any other app
template_dirs = (host_template_dir,) + template_dirs
for template_dir in super(Loader, self).get_template_sources(template_name, template_dirs):
yield template_dir
# `host_template_loader` needs to be the 1st entry in `TEMPLATE_LOADERS`
TEMPLATE_LOADERS = (
"host_template_loader.Loader",
"django.template.loaders.filesystem.Loader",
"django.template.loaders.app_directories.Loader",
)
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'host_theme',
# You need to add the theme apps in `INSTALLED_APPS`
'english',
'arabic',
)
# Now you can set `HOST_THEMES` as usual
HOST_THEMES = (
# Host URL, Host theme app
('ar.localtest.me', 'arabic'),
('en.localtest.me', 'english'),
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment