Skip to content

Instantly share code, notes, and snippets.

@code
Created February 9, 2010 05:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save code/298937 to your computer and use it in GitHub Desktop.
Save code/298937 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
# WARNING: THIS CODE MAY HURT YOUR EYES.
import logging, os
def patch_mako():
import os, logging
from mako import template as template_module
from mako.lookup import TemplateLookup
from mako.template import Lexer, codegen, types
from google.appengine.api import memcache
if not hasattr(template_module, '_compile_text_orig'):
setattr( template_module, '_compile_text_orig', template_module._compile_text )
else:
return
cvid = os.environ.get('CURRENT_VERSION_ID','')
dev = os.environ.get('SERVER_SOFTWARE','').lower().startswith("dev")
def _get_module(source, identifier):
"""copy second half of template._compile_text() into here"""
# logging.debug("being called here.")
cid = identifier
if isinstance(cid, unicode):
cid = cid.encode()
module = types.ModuleType(cid)
code = compile(source, cid, 'exec')
exec code in module.__dict__, module.__dict__
return module
def _compile_text(template, text, filename):
#logging.info( 'patched _compile_text called' )
identifier = template.module_id
no_cache = identifier.startswith('memory:')
if dev:
no_cache = True
cachekey = 'makosource:%s:%s' % (str(cvid), str(identifier))
if not no_cache:
logging.debug("Getting source code. %s" % filename)
source = memcache.get(cachekey)
if ( dev and source is not None and os.path.exists(filename)
and os.path.getmtime(filename) > memcache.get(cachekey + '_mtime') ):
source = None
if no_cache or source is None:
logging.debug('compiling text')
(source, module) = template_module._compile_text_orig( template, text, filename )
if not no_cache:
memcache.set(cachekey, source)
if dev:
memcache.set(cachekey + '_mtime', os.path.getmtime(filename))
logging.log( logging.INFO, "store mako source: "+cachekey )
else:
logging.log( logging.INFO, 'patched _compile_text cache hit' )
module = _get_module(source, identifier)
return (source, module)
def __load(self, filename, uri):
self._mutex.acquire()
try:
template = Template(uri=uri, filename=posixpath.normpath(filename), lookup=self, module_filename=(self.modulename_callable is not None and self.modulename_callable(filename, uri) or None), **self.template_args)
return template
finally:
self._mutex.release()
def get_template(self, uri):
import re, posixpath
logging.debug("patched get_template called !!!")
u = re.sub(r'^\/+', '', uri)
for dir in self.directories:
srcfile = posixpath.normpath(posixpath.join(dir, u))
if os.path.exists(srcfile):
filename = srcfile
return Template(uri=uri, filename=posixpath.normpath(filename), lookup=self, module_filename=(self.modulename_callable is not None and self.modulename_callable(filename, uri) or None), **self.template_args)
else:
raise exceptions.TopLevelLookupException("Cant locate template for uri '%s'" % uri)
template_module._compile_text = _compile_text
if dev:
TemplateLookup.get_template = get_template
patch_mako()
from mako.lookup import TemplateLookup
from mako.template import Template
from mako.exceptions import TopLevelLookupException
from mako import exceptions
import os
import logging
import settings
'''
configurations:
MAKO_TEMPLATE_DIRS:
A tuple, specify the directories in which to find the mako templates,
just like TEMPLATE_DIRS .
default value is ('mako_templates',)
MAKO_MODULE_DIR:
A string, if specified, all of the compiled template module files will be
stored in this directory.
MAKO_MODULENAME_CALLABLE:
A callable, if MAKO_MODULE_DIR is not specified, this will be
used to determine the filename of compiled template module file.
See [http://www.makotemplates.org/trac/ticket/14]
Default to the function `default_module_name`, which
just appends '.py' to the template filename.
'''
app_template_dirs = []
# for app_dir in app_dirs:
# template_dir = os.path.join(app_dir, 'templates')
# if os.path.isdir(template_dir):
# app_template_dirs.append(template_dir)
template_dirs = getattr(settings, 'MAKO_TEMPLATE_DIRS', None) or ('templates',)
template_dirs += tuple(app_template_dirs)
def default_module_name(filename, uri):
'''
Will store module files in the same directory as the corresponding template files.
detail about module_name_callable, go to
http://www.makotemplates.org/trac/ticket/14
'''
return filename+'.py'
# To be honest im not 100% sure what exactly the code below is doing.
# Need to read through it and get to grips with it, for now skip to end :)
dev = os.environ.get('SERVER_SOFTWARE','').lower().startswith("dev")
# module_dir = getattr(settings, 'MAKO_MODULE_DIR', None)
# if module_dir:
# lookup = TemplateLookup(directories=template_dirs,
# module_directory=module_dir, input_encoding='utf-8', output_encoding='utf-8', encoding_errors='replace',
# filesystem_checks=False, cache_type="memcached", cache_dir=".", cache_url="memcached://", auto_reload=dev)
# else:
# module_name_callable = getattr(settings, 'MAKO_MODULENAME_CALLABLE', None)
#
# if callable(module_name_callable):
# lookup = TemplateLookup(directories=template_dirs,
# modulename_callable=module_name_callable, input_encoding='utf-8', output_encoding='utf-8', encoding_errors='replace',
# filesystem_checks=False, cache_type="memcached", cache_dir=".", cache_url="memcached://")
# else:
# lookup = TemplateLookup(directories=template_dirs,
# modulename_callable=default_module_name, input_encoding='utf-8', output_encoding='utf-8', encoding_errors='replace',
# filesystem_checks=False, cache_type="memcached", cache_dir=".", cache_url="memcached://")
# lookup = TemplateLookup(directories=template_dirs, input_encoding='utf-8', output_encoding='utf-8', encoding_errors='replace',
# filesystem_checks=False, cache_type="memcached", cache_dir=".", cache_url="memcached://", cache_enabled=False)
lookup = TemplateLookup(
directories=template_dirs,
input_encoding='utf-8',
output_encoding='utf-8',
encoding_errors='replace',
filesystem_checks=False,
cache_type="memcached",
cache_dir=".",
cache_url="memcached://",
cache_enabled=True
)
# end of skip.
def select_template(template_name_list):
for template_name in template_name_list:
try:
return lookup.get_template(template_name)
except TopLevelLookupException:
pass
raise Exception('mako templates missing: '+', '.join(template_name_list))
def get_template(template_name):
try:
return lookup.get_template(template_name)
except TopLevelLookupException:
raise Exception('mako templates missing: '+template_name)
def render_to_response(template_name, dictionary=None):
try:
if isinstance(template_name, (list, tuple)):
template = select_template(template_name)
else:
# logging.debug("Get template called: %s" % template_name)
template = get_template(template_name)
data = dictionary or {}
return Response(template.render(**data))
except:
#raise
return Response(exceptions.html_error_template().render(), status=500)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment