Created
July 18, 2012 03:57
-
-
Save Kaelten/3134075 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import wraps | |
from django.conf import settings | |
from django.core.exceptions import ImproperlyConfigured | |
from django.http import HttpResponse | |
from django.template.base import TemplateDoesNotExist | |
from django.template.context import RequestContext, Context | |
from django.template.loader import BaseLoader, find_template | |
from django.utils._os import safe_join | |
from django.utils.importlib import import_module | |
import os, re, sys | |
class AppSpecificLoader(BaseLoader): | |
is_usable = True | |
template_dirs = None | |
def get_template_sources(self, template_name, template_app=None): | |
if template_app is None: | |
# This block is a little bit of a hack in order to allow for the template-loader | |
# postmortems to work | |
matches = re.match(r"^app: ([^\s]+) template: ([^\s]+)$", template_name, re.S) | |
if matches is None: | |
yield template_name | |
template_app = matches.group(1) | |
template_name = matches.group(2) | |
if template_app in self.template_dirs: | |
try: | |
yield safe_join(self.template_dirs[template_app], template_name) | |
except UnicodeDecodeError: | |
raise | |
except ValueError: | |
pass | |
def populate_template_dirs(self): | |
fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() | |
self.template_dirs = {} | |
for app in settings.INSTALLED_APPS: | |
try: | |
module = import_module(app) | |
except ImportError, e: | |
raise ImproperlyConfigured('ImportError %s: %s' % (app, e.args[0])) | |
template_dir = os.path.join(os.path.dirname(module.__file__), 'templates') | |
if os.path.isdir(template_dir): | |
if '.' in app: | |
app = '.'.join(app.split('.')[1:]) | |
self.template_dirs[app] = template_dir.decode(fs_encoding) | |
def load_template_source(self, template_name, template_app): | |
if self.template_dirs is None: | |
self.populate_template_dirs() | |
if template_app in self.template_dirs: | |
for template_path in self.get_template_sources(template_name, template_app): | |
try: | |
with open(template_path) as template: | |
return (template.read().decode(settings.FILE_CHARSET), template_path) | |
except IOError: | |
pass | |
raise TemplateDoesNotExist(template_name) | |
def find_specific_template(app, name): | |
try: | |
return find_template(name, app) | |
except TemplateDoesNotExist: | |
error_message ='app: {app} template: {template}'.format(app=app, template=name) | |
raise TemplateDoesNotExist(error_message) | |
def render_to_string(template_app, template_name, dictionary=None, context_instance=None): | |
if dictionary is None: | |
dictionary = {} | |
template, origin = find_specific_template(template_app, template_name) | |
if context_instance is None: | |
return template.render(Context(dictionary)) | |
else: | |
context_instance.update(dictionary) | |
try: | |
return template.render(context_instance) | |
finally: | |
context_instance.pop() | |
def render_to_response(*args, **kwargs): | |
response_kwargs = {'mimetype': kwargs.pop('mimetype', None)} | |
return HttpResponse(render_to_string(*args, **kwargs), **response_kwargs) | |
def using_template(app, template, mimetype=None): | |
def renderer(function): | |
@wraps(function) | |
def wrapper(request, *args, **kwargs): | |
context = function(request, *args, **kwargs) | |
return render_to_response(app, template, context, | |
context_instance=RequestContext(request), mimetype=mimetype) | |
return wrapper | |
return renderer |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment