-
-
Save webmaven/80e211d6d5080be600f5 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import inspect | |
import morepath | |
import os | |
class ChameleonApp(morepath.App): | |
@morepath.reify | |
def chameleon_template_paths(self): | |
""" Returns *absolute* paths to chameleon templates. | |
The expected result is an iterable with one absolute path string per | |
iteration, i.e. a list of directories. The directories are searched in | |
order for the name of the template. | |
Alternatively, a morepath app inheriting from ChameleonApp may be | |
returned, which will result in the paths of that application being | |
expanded. | |
This is useful if one app with templates should be considered for | |
the template lookup. For examle:: | |
@MyApp.setting(section='chameleon', name='search_paths') | |
def get_search_paths(): | |
return ['templates'] | |
Will be expanded to:: | |
[ | |
'path to MyAppClass/templates' | |
] | |
And:: | |
@MyDifferentApp.setting(section='chameleon', name='search_paths') | |
def get_search_paths(): | |
return ['templates', MyApp] | |
Will be expanded to: | |
[ | |
'path to MyDifferentClass/templates', | |
'path to MyAppClass/templates' | |
] | |
""" | |
def expand_paths(paths): | |
for ix, item in enumerate(paths): | |
# if the returned item is | |
if inspect.isclass(item): | |
for path in item().chameleon_template_paths: | |
yield path | |
elif not item.startswith('/'): | |
yield os.path.join( | |
os.path.dirname(inspect.getfile(self.__class__)), item) | |
else: | |
yield item | |
return list( | |
expand_paths(self.registry.settings.chameleon.search_paths)) | |
@morepath.reify | |
def chameleon_templates(self): | |
""" Returns an instanace of the chameleon.PageTemplateLoader with | |
the template paths set to `chameleon_template_paths` | |
""" | |
if self.registry.settings.chameleon.auto_reload: | |
# this will result in a warning from chameleon at the moment: | |
# https://github.com/malthe/chameleon/issues/183 | |
os.environ['CHAMELEON_RELOAD'] = 'true' | |
# Only import after setting the environment variable, or it won't | |
# be recognized. | |
import chameleon | |
return chameleon.PageTemplateLoader(self.chameleon_template_paths) | |
@ChameleonApp.setting(section="chameleon", name="search_paths") | |
def get_search_paths(): | |
""" Returns the chameleon search paths for the app. """ | |
raise NotImplementedError | |
@ChameleonApp.setting(section="chameleon", name="auto_reload") | |
def get_debug(): | |
""" Returns True if the template files should be automatically reloaded. | |
""" | |
# TODO configure this for deployment | |
return True | |
def render_chameleon(content, request): | |
""" Renders the content with a chameleon template. | |
The content is a dictionary of template variables used in the template. | |
""" | |
template = request.app.chameleon_templates[content.pop('template')] | |
rendered = template(**content) | |
return morepath.request.Response(rendered, content_type='text/html') | |
@ChameleonApp.directive('chameleon') | |
class ChameleonDirective(morepath.directive.ViewDirective): | |
""" Chameleon template view directive. Use like a morepath view:: | |
@MyApp.chameleon(model=Root, path='') | |
def root(self, request, form=None): | |
return { | |
'template': 'blogpost.pt', | |
'title': 'My Blog Post' | |
} | |
""" | |
def __init__(self, app, model, render=None, permission=None, | |
internal=False, **predicates): | |
""" Register Chameleon view. """ | |
render = render or render_chameleon | |
super(ChameleonDirective, self).__init__( | |
app, model, render, permission, internal, **predicates) | |
def group_key(self): | |
return morepath.directive.ViewDirective |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment