forked from orbit-oss/flask
Chnaged a bunch of behavior in blueprints for it to be more flexible. Improved backwards compat.
This commit is contained in:
parent
59a92ebd71
commit
abe1378cae
6 changed files with 50 additions and 54 deletions
|
|
@ -206,8 +206,9 @@ class Flask(_PackageBoundObject):
|
||||||
test_client_class = None
|
test_client_class = None
|
||||||
|
|
||||||
def __init__(self, import_name, static_path=None, static_url_path=None,
|
def __init__(self, import_name, static_path=None, static_url_path=None,
|
||||||
static_folder='static'):
|
static_folder='static', template_folder='templates'):
|
||||||
_PackageBoundObject.__init__(self, import_name)
|
_PackageBoundObject.__init__(self, import_name,
|
||||||
|
template_folder=template_folder)
|
||||||
if static_path is not None:
|
if static_path is not None:
|
||||||
from warnings import warn
|
from warnings import warn
|
||||||
warn(DeprecationWarning('static_path is now called '
|
warn(DeprecationWarning('static_path is now called '
|
||||||
|
|
@ -456,7 +457,7 @@ class Flask(_PackageBoundObject):
|
||||||
rv.filters['tojson'] = _tojson_filter
|
rv.filters['tojson'] = _tojson_filter
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def create_jinja_loader(self):
|
def create_global_jinja_loader(self):
|
||||||
"""Creates the loader for the Jinja2 environment. Can be used to
|
"""Creates the loader for the Jinja2 environment. Can be used to
|
||||||
override just the loader and keeping the rest unchanged.
|
override just the loader and keeping the rest unchanged.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,9 @@ class Blueprint(_PackageBoundObject):
|
||||||
_got_registered_once = False
|
_got_registered_once = False
|
||||||
|
|
||||||
def __init__(self, name, import_name, static_folder=None,
|
def __init__(self, name, import_name, static_folder=None,
|
||||||
static_url_path=None, url_prefix=None,
|
static_url_path=None, template_folder=None,
|
||||||
subdomain=None):
|
url_prefix=None, subdomain=None):
|
||||||
_PackageBoundObject.__init__(self, import_name)
|
_PackageBoundObject.__init__(self, import_name, template_folder)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.url_prefix = url_prefix
|
self.url_prefix = url_prefix
|
||||||
self.subdomain = subdomain
|
self.subdomain = subdomain
|
||||||
|
|
|
||||||
|
|
@ -485,13 +485,15 @@ class locked_cached_property(object):
|
||||||
|
|
||||||
class _PackageBoundObject(object):
|
class _PackageBoundObject(object):
|
||||||
|
|
||||||
template_folder = 'templates'
|
def __init__(self, import_name, template_folder=None):
|
||||||
|
|
||||||
def __init__(self, import_name):
|
|
||||||
#: The name of the package or module. Do not change this once
|
#: The name of the package or module. Do not change this once
|
||||||
#: it was set by the constructor.
|
#: it was set by the constructor.
|
||||||
self.import_name = import_name
|
self.import_name = import_name
|
||||||
|
|
||||||
|
#: location of the templates. `None` if templates should not be
|
||||||
|
#: exposed.
|
||||||
|
self.template_folder = template_folder
|
||||||
|
|
||||||
#: Where is the app root located?
|
#: Where is the app root located?
|
||||||
self.root_path = _get_package_path(self.import_name)
|
self.root_path = _get_package_path(self.import_name)
|
||||||
|
|
||||||
|
|
@ -544,8 +546,7 @@ class _PackageBoundObject(object):
|
||||||
"""
|
"""
|
||||||
if not self.has_static_folder:
|
if not self.has_static_folder:
|
||||||
raise RuntimeError('No static folder for this object')
|
raise RuntimeError('No static folder for this object')
|
||||||
return send_from_directory(os.path.join(self.root_path, 'static'),
|
return send_from_directory(self.static_folder, filename)
|
||||||
filename)
|
|
||||||
|
|
||||||
def open_resource(self, resource):
|
def open_resource(self, resource):
|
||||||
"""Opens a resource from the application's resource folder. To see
|
"""Opens a resource from the application's resource folder. To see
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from .helpers import _PackageBoundObject, _endpoint_from_view_func
|
|
||||||
from .blueprints import Blueprint
|
from .blueprints import Blueprint
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -37,7 +36,7 @@ class Module(Blueprint):
|
||||||
'does not point to a submodule'
|
'does not point to a submodule'
|
||||||
name = import_name.rsplit('.', 1)[1]
|
name = import_name.rsplit('.', 1)[1]
|
||||||
Blueprint.__init__(self, name, import_name, url_prefix=url_prefix,
|
Blueprint.__init__(self, name, import_name, url_prefix=url_prefix,
|
||||||
subdomain=subdomain)
|
subdomain=subdomain, template_folder='templates')
|
||||||
|
|
||||||
if os.path.isdir(os.path.join(self.root_path, 'static')):
|
if os.path.isdir(os.path.join(self.root_path, 'static')):
|
||||||
self._static_folder = 'static'
|
self._static_folder = 'static'
|
||||||
|
|
|
||||||
|
|
@ -38,69 +38,64 @@ class Environment(BaseEnvironment):
|
||||||
|
|
||||||
def __init__(self, app, **options):
|
def __init__(self, app, **options):
|
||||||
if 'loader' not in options:
|
if 'loader' not in options:
|
||||||
options['loader'] = app.create_jinja_loader()
|
options['loader'] = app.create_global_jinja_loader()
|
||||||
BaseEnvironment.__init__(self, **options)
|
BaseEnvironment.__init__(self, **options)
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
def join_path(self, template, parent):
|
|
||||||
if template and template[0] == ':':
|
|
||||||
template = parent.split(':', 1)[0] + template
|
|
||||||
return template
|
|
||||||
|
|
||||||
|
|
||||||
class DispatchingJinjaLoader(BaseLoader):
|
class DispatchingJinjaLoader(BaseLoader):
|
||||||
"""A loader that looks for templates in the application and all
|
"""A loader that looks for templates in the application and all
|
||||||
the module folders.
|
the blueprint folders.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
def get_source(self, environment, template):
|
def get_source(self, environment, template):
|
||||||
# newstyle template support. blueprints are explicit and no further
|
for loader, local_name in self._iter_loaders(template):
|
||||||
# magic is involved. If the template cannot be loaded by the
|
try:
|
||||||
# blueprint loader it just gives up, no further steps involved.
|
return loader.get_source(environment, local_name)
|
||||||
if ':' in template:
|
except TemplateNotFound:
|
||||||
blueprint_name, local_template = template.split(':', 1)
|
pass
|
||||||
local_template = posixpath.normpath(local_template)
|
|
||||||
blueprint = self.app.blueprints.get(blueprint_name)
|
|
||||||
if blueprint is None:
|
|
||||||
raise TemplateNotFound(template)
|
|
||||||
loader = blueprint.jinja_loader
|
|
||||||
if loader is not None:
|
|
||||||
return loader.get_source(environment, local_template)
|
|
||||||
|
|
||||||
# if modules are enabled we call into the old style template lookup
|
raise TemplateNotFound(template)
|
||||||
# and try that before we go with the real deal.
|
|
||||||
loader = None
|
def _iter_loaders(self, template):
|
||||||
|
loader = self.app.jinja_loader
|
||||||
|
if loader is not None:
|
||||||
|
yield loader, template
|
||||||
|
|
||||||
|
# old style module based loaders in case we are dealing with a
|
||||||
|
# blueprint that is an old style module
|
||||||
try:
|
try:
|
||||||
module, name = posixpath.normpath(template).split('/', 1)
|
module, local_name = posixpath.normpath(template).split('/', 1)
|
||||||
blueprint = self.app.blueprints[module]
|
blueprint = self.app.blueprints[module]
|
||||||
if blueprint_is_module(blueprint):
|
if blueprint_is_module(blueprint):
|
||||||
loader = blueprint.jinja_loader
|
loader = blueprint.jinja_loader
|
||||||
except (ValueError, KeyError, TemplateNotFound):
|
if loader is not None:
|
||||||
pass
|
yield loader, local_name
|
||||||
try:
|
except (ValueError, KeyError):
|
||||||
if loader is not None:
|
|
||||||
return loader.get_source(environment, name)
|
|
||||||
except TemplateNotFound:
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# at the very last, load templates from the environment
|
for blueprint in self.app.blueprints.itervalues():
|
||||||
return self.app.jinja_loader.get_source(environment, template)
|
loader = blueprint.jinja_loader
|
||||||
|
if loader is not None:
|
||||||
|
yield loader, template
|
||||||
|
|
||||||
def list_templates(self):
|
def list_templates(self):
|
||||||
result = set(self.app.jinja_loader.list_templates())
|
result = set()
|
||||||
|
loader = self.app.jinja_loader
|
||||||
for name, module in self.app.modules.iteritems():
|
if loader is not None:
|
||||||
if module.jinja_loader is not None:
|
result.update(loader.list_templates())
|
||||||
for template in module.jinja_loader.list_templates():
|
|
||||||
result.add('%s/%s' % (name, template))
|
|
||||||
|
|
||||||
for name, blueprint in self.app.blueprints.iteritems():
|
for name, blueprint in self.app.blueprints.iteritems():
|
||||||
if blueprint.jinja_loader is not None:
|
loader = blueprint.jinja_loader
|
||||||
for template in blueprint.jinja_loader.list_templates():
|
if loader is not None:
|
||||||
result.add('%s:%s' % (name, template))
|
for template in loader.list_templates():
|
||||||
|
prefix = ''
|
||||||
|
if not blueprint_is_module(blueprint):
|
||||||
|
prefix = name + '/'
|
||||||
|
result.add(prefix + template)
|
||||||
|
|
||||||
return list(result)
|
return list(result)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -992,7 +992,7 @@ class TemplatingTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_custom_template_loader(self):
|
def test_custom_template_loader(self):
|
||||||
class MyFlask(flask.Flask):
|
class MyFlask(flask.Flask):
|
||||||
def create_jinja_loader(self):
|
def create_global_jinja_loader(self):
|
||||||
from jinja2 import DictLoader
|
from jinja2 import DictLoader
|
||||||
return DictLoader({'index.html': 'Hello Custom World!'})
|
return DictLoader({'index.html': 'Hello Custom World!'})
|
||||||
app = MyFlask(__name__)
|
app = MyFlask(__name__)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue