Started documentation for blueprints

This commit is contained in:
Armin Ronacher 2011-06-07 15:32:44 +02:00
parent b4ffa4d9ac
commit bfd67764fb
4 changed files with 94 additions and 30 deletions

View file

@ -52,6 +52,9 @@ class Blueprint(_PackageBoundObject):
.. versionadded:: 0.7
"""
warn_on_modifications = False
_got_registered_once = False
def __init__(self, name, import_name, static_folder=None,
static_url_path=None, url_prefix=None,
subdomain=None):
@ -64,14 +67,29 @@ class Blueprint(_PackageBoundObject):
self.deferred_functions = []
self.view_functions = {}
def _record(self, func):
def record(self, func):
"""Registers a function that is called when the blueprint is
registered on the application. This function is called with the
state as argument as returned by the :meth:`make_setup_state`
method.
"""
if self._got_registered_once and self.warn_on_modifications:
from warnings import warn
warn(Warning('The blueprint was already registered once '
'but is getting modified now. These changes '
'will not show up.'))
self.deferred_functions.append(func)
def _record_once(self, func):
def record_once(self, func):
"""Works like :meth:`record` but wraps the function in another
function that will ensure the function is only called once. If the
blueprint is registered a second time on the application, the
function passed is not called.
"""
def wrapper(state):
if state.first_registration:
func(state)
return self._record(update_wrapper(wrapper, func))
return self.record(update_wrapper(wrapper, func))
def make_setup_state(self, app, options, first_registration=False):
return BlueprintSetupState(self, app, options, first_registration)
@ -83,6 +101,7 @@ class Blueprint(_PackageBoundObject):
:func:`~flask.Flask.register_blueprint` are directly forwarded to this
method in the `options` dictionary.
"""
self._got_registered_once = True
state = self.make_setup_state(app, options, first_registration)
if self.has_static_folder:
state.add_url_rule(self.static_url_path + '/<path:filename>',
@ -105,7 +124,7 @@ class Blueprint(_PackageBoundObject):
"""Like :meth:`Flask.add_url_rule` but for a module. The endpoint for
the :func:`url_for` function is prefixed with the name of the module.
"""
self._record(lambda s:
self.record(lambda s:
s.add_url_rule(rule, endpoint, view_func, **options))
def endpoint(self, endpoint):
@ -118,7 +137,7 @@ class Blueprint(_PackageBoundObject):
def decorator(f):
def register_endpoint(state):
state.app.view_functions[endpoint] = f
self._record_once(register_endpoint)
self.record_once(register_endpoint)
return f
return decorator
@ -127,7 +146,7 @@ class Blueprint(_PackageBoundObject):
is only executed before each request that is handled by a function of
that module.
"""
self._record_once(lambda s: s.app.before_request_funcs
self.record_once(lambda s: s.app.before_request_funcs
.setdefault(self.name, []).append(f))
return f
@ -135,7 +154,7 @@ class Blueprint(_PackageBoundObject):
"""Like :meth:`Flask.before_request`. Such a function is executed
before each request, even if outside of a module.
"""
self._record_once(lambda s: s.app.before_request_funcs
self.record_once(lambda s: s.app.before_request_funcs
.setdefault(None, []).append(f))
return f
@ -144,7 +163,7 @@ class Blueprint(_PackageBoundObject):
is only executed after each request that is handled by a function of
that module.
"""
self._record_once(lambda s: s.app.after_request_funcs
self.record_once(lambda s: s.app.after_request_funcs
.setdefault(self.name, []).append(f))
return f
@ -152,7 +171,7 @@ class Blueprint(_PackageBoundObject):
"""Like :meth:`Flask.after_request` but for a module. Such a function
is executed after each request, even if outside of the module.
"""
self._record_once(lambda s: s.app.after_request_funcs
self.record_once(lambda s: s.app.after_request_funcs
.setdefault(None, []).append(f))
return f
@ -160,7 +179,7 @@ class Blueprint(_PackageBoundObject):
"""Like :meth:`Flask.context_processor` but for a module. This
function is only executed for requests handled by a module.
"""
self._record_once(lambda s: s.app.template_context_processors
self.record_once(lambda s: s.app.template_context_processors
.setdefault(self.name, []).append(f))
return f
@ -168,7 +187,7 @@ class Blueprint(_PackageBoundObject):
"""Like :meth:`Flask.context_processor` but for a module. Such a
function is executed each request, even if outside of the module.
"""
self._record_once(lambda s: s.app.template_context_processors
self.record_once(lambda s: s.app.template_context_processors
.setdefault(None, []).append(f))
return f
@ -177,7 +196,7 @@ class Blueprint(_PackageBoundObject):
handler is used for all requests, even if outside of the module.
"""
def decorator(f):
self._record_once(lambda s: s.app.errorhandler(code)(f))
self.record_once(lambda s: s.app.errorhandler(code)(f))
return f
return decorator
@ -186,7 +205,7 @@ class Blueprint(_PackageBoundObject):
blueprint. It's called before the view functions are called and
can modify the url values provided.
"""
self._record_once(lambda s: s.app.url_value_preprocessors
self.record_once(lambda s: s.app.url_value_preprocessors
.setdefault(self.name, []).append(f))
return f
@ -195,21 +214,21 @@ class Blueprint(_PackageBoundObject):
with the endpoint and values and should update the values passed
in place.
"""
self._record_once(lambda s: s.app.url_default_functions
self.record_once(lambda s: s.app.url_default_functions
.setdefault(self.name, []).append(f))
return f
def app_url_value_preprocessor(self, f):
"""Same as :meth:`url_value_preprocessor` but application wide.
"""
self._record_once(lambda s: s.app.url_value_preprocessor
self.record_once(lambda s: s.app.url_value_preprocessor
.setdefault(self.name, []).append(f))
return f
def app_url_defaults(self, f):
"""Same as :meth:`url_defaults` but application wide.
"""
self._record_once(lambda s: s.app.url_default_functions
self.record_once(lambda s: s.app.url_default_functions
.setdefault(None, []).append(f))
return f
@ -227,7 +246,7 @@ class Blueprint(_PackageBoundObject):
.. versionadded:: 0.7
"""
def decorator(f):
self._record_once(lambda s: s.app._register_error_handler(
self.record_once(lambda s: s.app._register_error_handler(
self.name, code_or_exception, f))
return f
return decorator