Skip to content

Commit

Permalink
Chnaged a bunch of behavior in blueprints for it to be more flexible.…
Browse files Browse the repository at this point in the history
… Improved backwards compat.
  • Loading branch information
mitsuhiko committed Jun 16, 2011
1 parent 59a92eb commit abe1378
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 54 deletions.
7 changes: 4 additions & 3 deletions flask/app.py
Expand Up @@ -206,8 +206,9 @@ class Flask(_PackageBoundObject):
test_client_class = None

def __init__(self, import_name, static_path=None, static_url_path=None,
static_folder='static'):
_PackageBoundObject.__init__(self, import_name)
static_folder='static', template_folder='templates'):
_PackageBoundObject.__init__(self, import_name,
template_folder=template_folder)
if static_path is not None:
from warnings import warn
warn(DeprecationWarning('static_path is now called '
Expand Down Expand Up @@ -456,7 +457,7 @@ def create_jinja_environment(self):
rv.filters['tojson'] = _tojson_filter
return rv

def create_jinja_loader(self):
def create_global_jinja_loader(self):
"""Creates the loader for the Jinja2 environment. Can be used to
override just the loader and keeping the rest unchanged.
Expand Down
6 changes: 3 additions & 3 deletions flask/blueprints.py
Expand Up @@ -56,9 +56,9 @@ class Blueprint(_PackageBoundObject):
_got_registered_once = False

def __init__(self, name, import_name, static_folder=None,
static_url_path=None, url_prefix=None,
subdomain=None):
_PackageBoundObject.__init__(self, import_name)
static_url_path=None, template_folder=None,
url_prefix=None, subdomain=None):
_PackageBoundObject.__init__(self, import_name, template_folder)
self.name = name
self.url_prefix = url_prefix
self.subdomain = subdomain
Expand Down
11 changes: 6 additions & 5 deletions flask/helpers.py
Expand Up @@ -485,13 +485,15 @@ def __get__(self, obj, type=None):

class _PackageBoundObject(object):

template_folder = 'templates'

def __init__(self, import_name):
def __init__(self, import_name, template_folder=None):
#: The name of the package or module. Do not change this once
#: it was set by the constructor.
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?
self.root_path = _get_package_path(self.import_name)

Expand Down Expand Up @@ -544,8 +546,7 @@ def send_static_file(self, filename):
"""
if not self.has_static_folder:
raise RuntimeError('No static folder for this object')
return send_from_directory(os.path.join(self.root_path, 'static'),
filename)
return send_from_directory(self.static_folder, filename)

def open_resource(self, resource):
"""Opens a resource from the application's resource folder. To see
Expand Down
3 changes: 1 addition & 2 deletions flask/module.py
Expand Up @@ -11,7 +11,6 @@

import os

from .helpers import _PackageBoundObject, _endpoint_from_view_func
from .blueprints import Blueprint


Expand All @@ -37,7 +36,7 @@ def __init__(self, import_name, name=None, url_prefix=None,
'does not point to a submodule'
name = import_name.rsplit('.', 1)[1]
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')):
self._static_folder = 'static'
75 changes: 35 additions & 40 deletions flask/templating.py
Expand Up @@ -38,69 +38,64 @@ class Environment(BaseEnvironment):

def __init__(self, app, **options):
if 'loader' not in options:
options['loader'] = app.create_jinja_loader()
options['loader'] = app.create_global_jinja_loader()
BaseEnvironment.__init__(self, **options)
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):
"""A loader that looks for templates in the application and all
the module folders.
the blueprint folders.
"""

def __init__(self, app):
self.app = app

def get_source(self, environment, template):
# newstyle template support. blueprints are explicit and no further
# magic is involved. If the template cannot be loaded by the
# blueprint loader it just gives up, no further steps involved.
if ':' in template:
blueprint_name, local_template = template.split(':', 1)
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)
for loader, local_name in self._iter_loaders(template):
try:
return loader.get_source(environment, local_name)
except TemplateNotFound:
pass

raise TemplateNotFound(template)

# if modules are enabled we call into the old style template lookup
# 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:
module, name = posixpath.normpath(template).split('/', 1)
module, local_name = posixpath.normpath(template).split('/', 1)
blueprint = self.app.blueprints[module]
if blueprint_is_module(blueprint):
loader = blueprint.jinja_loader
except (ValueError, KeyError, TemplateNotFound):
pass
try:
if loader is not None:
return loader.get_source(environment, name)
except TemplateNotFound:
if loader is not None:
yield loader, local_name
except (ValueError, KeyError):
pass

# at the very last, load templates from the environment
return self.app.jinja_loader.get_source(environment, template)
for blueprint in self.app.blueprints.itervalues():
loader = blueprint.jinja_loader
if loader is not None:
yield loader, template

def list_templates(self):
result = set(self.app.jinja_loader.list_templates())

for name, module in self.app.modules.iteritems():
if module.jinja_loader is not None:
for template in module.jinja_loader.list_templates():
result.add('%s/%s' % (name, template))
result = set()
loader = self.app.jinja_loader
if loader is not None:
result.update(loader.list_templates())

for name, blueprint in self.app.blueprints.iteritems():
if blueprint.jinja_loader is not None:
for template in blueprint.jinja_loader.list_templates():
result.add('%s:%s' % (name, template))
loader = blueprint.jinja_loader
if loader is not None:
for template in loader.list_templates():
prefix = ''
if not blueprint_is_module(blueprint):
prefix = name + '/'
result.add(prefix + template)

return list(result)

Expand Down
2 changes: 1 addition & 1 deletion tests/flask_tests.py
Expand Up @@ -992,7 +992,7 @@ def index():

def test_custom_template_loader(self):
class MyFlask(flask.Flask):
def create_jinja_loader(self):
def create_global_jinja_loader(self):
from jinja2 import DictLoader
return DictLoader({'index.html': 'Hello Custom World!'})
app = MyFlask(__name__)
Expand Down

0 comments on commit abe1378

Please sign in to comment.