Thanks for this. I think this is definitely nicer, and had it on my personal clean-up list for b6 , but have been totally swamped the last few days.
--Mark Ramm On Mon, Feb 16, 2009 at 5:52 PM, <[email protected]> wrote: > > Author: faide > Date: Mon Feb 16 16:52:24 2009 > New Revision: 6337 > URL: http://trac.turbogears.org/changeset/6337 > > Log: > Move DottedTemplateLookup in a separate file > > Added: > trunk/tg/dottednamesupport.py > Modified: > trunk/tg/configuration.py > > Modified: trunk/tg/configuration.py > ============================================================================== > --- trunk/tg/configuration.py (original) > +++ trunk/tg/configuration.py Mon Feb 16 16:52:24 2009 > @@ -18,7 +18,7 @@ > import tg > from tg import TGApp > from tg.error import ErrorHandler > -from tg.util import Bunch, get_partial_dict, get_dotted_filename > +from tg.util import Bunch, get_partial_dict > from routes import Mapper > from routes.middleware import RoutesMiddleware > from webob import Request > @@ -246,165 +246,11 @@ > provided by tg.render. > > """ > + from tg.dottednamesupport import DottedTemplateLookup > from mako.lookup import TemplateLookup > - from mako.template import Template > > from tg.render import render_mako > > - class DottedTemplateLookup(object): > - """Mako template lookup emulation that supports > - zipped applications and dotted filenames. > - > - This is an emulation of the Mako template lookup that will handle > - get_template and support dotted names in Python path notation > - to support zipped eggs. > - > - This is necessary because Mako asserts that your project will > always > - be installed in a zip-unsafe manner with all files somewhere on > the > - hard drive. > - This is not the case when you want your application to be > deployed > - in a single zip file (zip-safe). If you want to deploy in a zip > - file _and_ use the dotted template name notation then this class > - is necessary because it emulates files on the filesystem for the > - underlying Mako engine while they are in fact in your zip file. > - > - """ > - > - def __init__(self, input_encoding, output_encoding, > - imports, default_filters): > - > - try: > - import threading > - except: > - import dummy_threading as threading > - > - self.input_encoding = input_encoding > - self.output_encoding = output_encoding > - self.imports = imports > - self.default_filters = default_filters > - # implement a cache for the loaded templates > - self.template_cache = dict() > - # implement a cache for the filename lookups > - self.template_filenames_cache = dict() > - > - # a mutex to ensure thread safeness during template loading > - self._mutex = threading.Lock() > - > - def adjust_uri(self, uri, relativeto): > - """Adjust the given uri relative to a filename. > - > - This method is used by mako for filesystem based reasons. > - In dotted lookup land we don't adjust uri so we just return > - the value we are given without any change. > - > - """ > - if '.' in uri: > - # We are in the DottedTemplateLookup system so dots in > - # names should be treated as a Python path. Since this > - # method is called by template inheritance we must > - # support dotted names also in the inheritance. > - result = get_dotted_filename(template_name=uri, > - template_extension='.mak') > - > - if not self.template_filenames_cache.has_key(uri): > - # feed our filename cache if needed. > - self.template_filenames_cache[uri] = result > - > - else: > - # no dot detected, just return plain name > - result = uri > - > - return result > - > - def __check(self, template): > - """private method used to verify if a template has changed > - since the last time it has been put in cache... > - > - This method being based on the mtime of a real file this > should > - never be called on a zipped deployed application. > - > - This method is a ~copy/paste of the original caching system > from > - the Mako lookup loader. > - > - """ > - if template.filename is None: > - return template > - > - if not os.path.exists(template.filename): > - # remove from cache. > - self.template_cache.pop(template.filename, None) > - raise exceptions.TemplateLookupException( > - "Cant locate template '%s'" % template.filename) > - > - elif template.module._modified_time < os.stat( > - template.filename)[stat.ST_MTIME]: > - > - # cache is too old, remove old template > - # from cache and reload. > - self.template_cache.pop(template.filename, None) > - return self.__load(template.filename) > - > - else: > - # cache is correct, use it. > - return template > - > - def __load(self, filename): > - """real loader function. copy paste from the mako template > - loader. > - > - """ > - # make sure the template loading from filesystem is only done > - # one thread at a time to avoid bad clashes... > - self._mutex.acquire() > - try: > - try: > - # try returning from cache one more time in case > - # concurrent thread already loaded > - return self.template_cache[filename] > - > - except KeyError: > - # not in cache yet... we can continue normally > - pass > - > - try: > - self.template_cache[filename] = > Template(open(filename).read(), > - filename=filename, > - input_encoding=self.input_encoding, > - output_encoding=self.output_encoding, > - default_filters=self.default_filters, > - imports=self.imports, > - lookup=self) > - > - return self.template_cache[filename] > - > - except: > - self.template_cache.pop(filename, None) > - raise > - > - finally: > - # _always_ release the lock once done to avoid > - # "thread lock" effect > - self._mutex.release() > - > - def get_template(self, template_name): > - """this is the emulated method that must return a template > - instance based on a given template name > - > - """ > - if not self.template_cache.has_key(template_name): > - # the template string is not yet loaded into the cache. > - # Do so now > - self.__load(template_name) > - > - if tg.config.get('templating.mako.reloadfromdisk', > 'false').lower() == 'true': > - # AUTO RELOADING will be activated only if user has > - # explicitly asked for it in the configuration > - # return the template, but first make sure it's not > outdated > - # and if outdated, refresh the cache. > - return self.__check(self.template_cache[template_name]) > - > - else: > - return self.template_cache[template_name] > > if config.get('use_dotted_templatenames', False): > # Support dotted names by injecting a slightly different template > > Added: trunk/tg/dottednamesupport.py > ============================================================================== > --- (empty file) > +++ trunk/tg/dottednamesupport.py Mon Feb 16 16:52:24 2009 > @@ -0,0 +1,163 @@ > +"""a reimplementation of the mako template loader > +that supports dotted names > +""" > + > +import tg > +from tg.util import get_dotted_filename > +from mako.template import Template > +try: > + import threading > +except: > + import dummy_threading as threading > + > + > +class DottedTemplateLookup(object): > + """Mako template lookup emulation that supports > + zipped applications and dotted filenames. > + > + This is an emulation of the Mako template lookup that will handle > + get_template and support dotted names in Python path notation > + to support zipped eggs. > + > + This is necessary because Mako asserts that your project will always > + be installed in a zip-unsafe manner with all files somewhere on the > + hard drive. > + This is not the case when you want your application to be deployed > + in a single zip file (zip-safe). If you want to deploy in a zip > + file _and_ use the dotted template name notation then this class > + is necessary because it emulates files on the filesystem for the > + underlying Mako engine while they are in fact in your zip file. > + > + """ > + > + def __init__(self, input_encoding, output_encoding, > + imports, default_filters): > + > + self.input_encoding = input_encoding > + self.output_encoding = output_encoding > + self.imports = imports > + self.default_filters = default_filters > + # implement a cache for the loaded templates > + self.template_cache = dict() > + # implement a cache for the filename lookups > + self.template_filenames_cache = dict() > + > + # a mutex to ensure thread safeness during template loading > + self._mutex = threading.Lock() > + > + def adjust_uri(self, uri, relativeto): > + """Adjust the given uri relative to a filename. > + > + This method is used by mako for filesystem based reasons. > + In dotted lookup land we don't adjust uri so we just return > + the value we are given without any change. > + > + """ > + if '.' in uri: > + # We are in the DottedTemplateLookup system so dots in > + # names should be treated as a Python path. Since this > + # method is called by template inheritance we must > + # support dotted names also in the inheritance. > + result = get_dotted_filename(template_name=uri, > + template_extension='.mak') > + > + if not self.template_filenames_cache.has_key(uri): > + # feed our filename cache if needed. > + self.template_filenames_cache[uri] = result > + > + else: > + # no dot detected, just return plain name > + result = uri > + > + return result > + > + def __check(self, template): > + """private method used to verify if a template has changed > + since the last time it has been put in cache... > + > + This method being based on the mtime of a real file this should > + never be called on a zipped deployed application. > + > + This method is a ~copy/paste of the original caching system from > + the Mako lookup loader. > + > + """ > + if template.filename is None: > + return template > + > + if not os.path.exists(template.filename): > + # remove from cache. > + self.template_cache.pop(template.filename, None) > + raise exceptions.TemplateLookupException( > + "Cant locate template '%s'" % template.filename) > + > + elif template.module._modified_time < os.stat( > + template.filename)[stat.ST_MTIME]: > + > + # cache is too old, remove old template > + # from cache and reload. > + self.template_cache.pop(template.filename, None) > + return self.__load(template.filename) > + > + else: > + # cache is correct, use it. > + return template > + > + def __load(self, filename): > + """real loader function. copy paste from the mako template > + loader. > + > + """ > + # make sure the template loading from filesystem is only done > + # one thread at a time to avoid bad clashes... > + self._mutex.acquire() > + try: > + try: > + # try returning from cache one more time in case > + # concurrent thread already loaded > + return self.template_cache[filename] > + > + except KeyError: > + # not in cache yet... we can continue normally > + pass > + > + try: > + self.template_cache[filename] = > Template(open(filename).read(), > + filename=filename, > + input_encoding=self.input_encoding, > + output_encoding=self.output_encoding, > + default_filters=self.default_filters, > + imports=self.imports, > + lookup=self) > + > + return self.template_cache[filename] > + > + except: > + self.template_cache.pop(filename, None) > + raise > + > + finally: > + # _always_ release the lock once done to avoid > + # "thread lock" effect > + self._mutex.release() > + > + def get_template(self, template_name): > + """this is the emulated method that must return a template > + instance based on a given template name > + > + """ > + if not self.template_cache.has_key(template_name): > + # the template string is not yet loaded into the cache. > + # Do so now > + self.__load(template_name) > + > + if tg.config.get('templating.mako.reloadfromdisk', 'false').lower() > == 'true': > + # AUTO RELOADING will be activated only if user has > + # explicitly asked for it in the configuration > + # return the template, but first make sure it's not outdated > + # and if outdated, refresh the cache. > + return self.__check(self.template_cache[template_name]) > + > + else: > + return self.template_cache[template_name] > + > -- Mark Ramm-Christensen email: mark at compoundthinking dot com blog: www.compoundthinking.com/blog --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "TurboGears Trunk" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/turbogears-trunk?hl=en -~----------~----~----~----~------~----~------~--~---
