From 20bf8edcf4efed9405c6148ee070c22c32fbb7ea Mon Sep 17 00:00:00 2001 From: Ron DuPlain Date: Tue, 7 Jun 2011 21:55:07 -0400 Subject: [PATCH 1/3] Rename teardown example to avoid confusion. --- docs/reqcontext.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/reqcontext.rst b/docs/reqcontext.rst index 088502eb..832f0e66 100644 --- a/docs/reqcontext.rst +++ b/docs/reqcontext.rst @@ -174,13 +174,14 @@ It's easy to see the behavior from the command line: >>> app = Flask(__name__) >>> @app.teardown_request -... def after_request(exception=None): -... print 'after request' -... +... def teardown_request(exception=None): +... print 'this runs after request' +... >>> ctx = app.test_request_context() >>> ctx.push() >>> ctx.pop() -after request +this runs after request +>>> .. _notes-on-proxies: From 0313c8b24a40d016e6b64495ce72ed912ce0fc24 Mon Sep 17 00:00:00 2001 From: Ron DuPlain Date: Wed, 8 Jun 2011 08:20:42 -0400 Subject: [PATCH 2/3] Expand documentation on blueprints. --- docs/blueprints.rst | 61 ++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/docs/blueprints.rst b/docs/blueprints.rst index 9d429df1..04ab0d8b 100644 --- a/docs/blueprints.rst +++ b/docs/blueprints.rst @@ -5,42 +5,51 @@ Modular Applications with Blueprints .. versionadded:: 0.7 -Flask knows a concept known as “blueprints” which can greatly simplify how -large applications work. A blueprint is an object works similar to an -actual :class:`Flask` application object, but it is not actually an -application. Rather it is the blueprint of how to create an application. -Think of it like that: you might want to have an application that has a -wiki. So what you can do is creating the blueprint for a wiki and then -let the application assemble the wiki on the application object. +Flask uses a concept of *blueprints* for making application components and +supporting common patterns within an application or across applications. +Blueprints can greatly simplify how large applications work and provide a +central means for Flask extensions to register operations on applications. +A :class:`Blueprint` object works similarly to a :class:`Flask` +application object, but it is not actually an application. Rather it is a +*blueprint* of how to construct or extend an application. Why Blueprints? --------------- -Why have blueprints and not multiple application objects? The utopia of -pluggable applications are different WSGI applications and merging them -together somehow. You can do that (see :ref:`app-dispatch`) but it's not -the right tool for every case. Having different applications means having -different configs. Applications are also separated on the WSGI layer -which is a lot lower level than the level that Flask usually operates on -where you have request and response objects. +Blueprints in Flask are intended for these cases: -Blueprints do not necessarily have to implement applications. They could -only provide filters for templates, static files, templates or similar -things. They share the same config as the application and can change the -application as necessary when being registered. +* Factor an application into a set of blueprints. This is ideal for + larger applications; a project could instantiate an application object, + initialize several extensions, and register a collection of blueprints. +* Register a blueprint on an application at a URL prefix and/or subdomain. + Paremeters in the URL prefix/subdomain become common view arguments + (with defaults) across all view functions in the blueprint. +* Register a blueprint multiple times on an application with different URL + rules. +* Provide template filters, static files, templates, and other utilities + through blueprints. A blueprint does not have to implement applications + or view functions. +* Register a blueprint on an application for any of these cases when + initializing a Flask extension. -The downside is that you cannot unregister a blueprint once application -without having to destroy the whole application object. +A blueprint in Flask is not a pluggable app because it is not actually an +application -- it's a set of operations which can be registered on an +application, even multiple times. Why not have multiple application +objects? You can do that (see :ref:`app-dispatch`), but your applications +will have separate configs and will be managed at the WSGI layer. + +Blueprints instead provide separation at the Flask level, share +application config, and can change an application object as necessary with +being registered. The downside is that you cannot unregister a blueprint +once application without having to destroy the whole application object. The Concept of Blueprints ------------------------- -The basic concept of blueprints is that they record operations that should -be executed when the blueprint is registered on the application. However -additionally each time a request gets dispatched to a view that was -declared to a blueprint Flask will remember that the request was -dispatched to that blueprint. That way it's easier to generate URLs from -one endpoint to another in the same module. +The basic concept of blueprints is that they record operations to execute +when registered on an application. Flask associates view functions with +blueprints when dispatching requests and generating URLs from one endpoint +to another. My First Blueprint ------------------ From 3d6e3e48ad2445c80761c930ddfbe0ce24be3eb3 Mon Sep 17 00:00:00 2001 From: Ron DuPlain Date: Wed, 8 Jun 2011 10:59:32 -0400 Subject: [PATCH 3/3] Replace 'module' with 'blueprint' in docstrings. --- flask/blueprints.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/flask/blueprints.py b/flask/blueprints.py index 41d5ef95..03f01748 100644 --- a/flask/blueprints.py +++ b/flask/blueprints.py @@ -112,8 +112,8 @@ class Blueprint(_PackageBoundObject): deferred(state) def route(self, rule, **options): - """Like :meth:`Flask.route` but for a module. The endpoint for the - :func:`url_for` function is prefixed with the name of the module. + """Like :meth:`Flask.route` but for a blueprint. The endpoint for the + :func:`url_for` function is prefixed with the name of the blueprint. """ def decorator(f): self.add_url_rule(rule, f.__name__, f, **options) @@ -121,15 +121,15 @@ class Blueprint(_PackageBoundObject): return decorator def add_url_rule(self, rule, endpoint=None, view_func=None, **options): - """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. + """Like :meth:`Flask.add_url_rule` but for a blueprint. The endpoint for + the :func:`url_for` function is prefixed with the name of the blueprint. """ self.record(lambda s: s.add_url_rule(rule, endpoint, view_func, **options)) def endpoint(self, endpoint): - """Like :meth:`Flask.endpoint` but for a module. This does not - prefix the endpoint with the module name, this has to be done + """Like :meth:`Flask.endpoint` but for a blueprint. This does not + prefix the endpoint with the blueprint name, this has to be done explicitly by the user of this method. If the endpoint is prefixed with a `.` it will be registered to the current blueprint, otherwise it's an application independent endpoint. @@ -142,9 +142,9 @@ class Blueprint(_PackageBoundObject): return decorator def before_request(self, f): - """Like :meth:`Flask.before_request` but for a module. This function + """Like :meth:`Flask.before_request` but for a blueprint. This function is only executed before each request that is handled by a function of - that module. + that blueprint. """ self.record_once(lambda s: s.app.before_request_funcs .setdefault(self.name, []).append(f)) @@ -152,48 +152,48 @@ class Blueprint(_PackageBoundObject): def before_app_request(self, f): """Like :meth:`Flask.before_request`. Such a function is executed - before each request, even if outside of a module. + before each request, even if outside of a blueprint. """ self.record_once(lambda s: s.app.before_request_funcs .setdefault(None, []).append(f)) return f def after_request(self, f): - """Like :meth:`Flask.after_request` but for a module. This function + """Like :meth:`Flask.after_request` but for a blueprint. This function is only executed after each request that is handled by a function of - that module. + that blueprint. """ self.record_once(lambda s: s.app.after_request_funcs .setdefault(self.name, []).append(f)) return f def after_app_request(self, f): - """Like :meth:`Flask.after_request` but for a module. Such a function - is executed after each request, even if outside of the module. + """Like :meth:`Flask.after_request` but for a blueprint. Such a function + is executed after each request, even if outside of the blueprint. """ self.record_once(lambda s: s.app.after_request_funcs .setdefault(None, []).append(f)) return f def context_processor(self, f): - """Like :meth:`Flask.context_processor` but for a module. This - function is only executed for requests handled by a module. + """Like :meth:`Flask.context_processor` but for a blueprint. This + function is only executed for requests handled by a blueprint. """ self.record_once(lambda s: s.app.template_context_processors .setdefault(self.name, []).append(f)) return f def app_context_processor(self, f): - """Like :meth:`Flask.context_processor` but for a module. Such a - function is executed each request, even if outside of the module. + """Like :meth:`Flask.context_processor` but for a blueprint. Such a + function is executed each request, even if outside of the blueprint. """ self.record_once(lambda s: s.app.template_context_processors .setdefault(None, []).append(f)) return f def app_errorhandler(self, code): - """Like :meth:`Flask.errorhandler` but for a module. This - handler is used for all requests, even if outside of the module. + """Like :meth:`Flask.errorhandler` but for a blueprint. This + handler is used for all requests, even if outside of the blueprint. """ def decorator(f): self.record_once(lambda s: s.app.errorhandler(code)(f)) @@ -210,7 +210,7 @@ class Blueprint(_PackageBoundObject): return f def url_defaults(self, f): - """Callback function for URL defaults for this module. It's called + """Callback function for URL defaults for this blueprint. It's called with the endpoint and values and should update the values passed in place. """