Browse Source

Chnaged a bunch of behavior in blueprints for it to be more flexible. Improved backwards compat.

pull/262/head
Armin Ronacher 14 years ago
parent
commit
abe1378cae
  1. 7
      flask/app.py
  2. 6
      flask/blueprints.py
  3. 11
      flask/helpers.py
  4. 3
      flask/module.py
  5. 75
      flask/templating.py
  6. 2
      tests/flask_tests.py

7
flask/app.py

@ -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.

6
flask/blueprints.py

@ -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

11
flask/helpers.py

@ -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

3
flask/module.py

@ -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'

75
flask/templating.py

@ -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) raise TemplateNotFound(template)
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 def _iter_loaders(self, template):
# and try that before we go with the real deal. loader = self.app.jinja_loader
loader = None 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)

2
tests/flask_tests.py

@ -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…
Cancel
Save