diff --git a/docs/api.rst b/docs/api.rst index d285dbfd..0d8b6cf5 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -15,6 +15,15 @@ Application Object .. autoclass:: Flask :members: + :inherited-members: + + +Module Objects +-------------- + +.. autoclass:: Module + :members: + :inherited-members: Incoming Request Data --------------------- diff --git a/flask.py b/flask.py index e07b7923..6d242aa1 100644 --- a/flask.py +++ b/flask.py @@ -340,7 +340,49 @@ class _ModuleSetupState(object): class Module(_PackageBoundObject): - """Container object that enables pluggable applications""" + """Container object that enables pluggable applications. A module can + be used to organize larger applications. They represent blueprints that, + in combination with a :class:`Flask` object are used to create a large + application. + + A module is like an application bound to an `import_name`. Multiple + modules can share the same import names, but in that case a `name` has + to be provided to keep them apart. If different import names are used, + the rightmost part of the import name is used as name. + + Here an example structure for a larger appliation:: + + /myapplication + /__init__.py + /views + /__init__.py + /admin.py + /frontend.py + + The `myapplication/__init__.py` can look like this:: + + from flask import Flask + from myapplication.views.admin import admin + from myapplication.views.frontend import frontend + + app = Flask(__name__) + app.register_module(admin, url_prefix='/admin') + app.register_module(frontend) + + And here an example view module (`myapplication/views/admin.py`):: + + from flask import Module + + admin = Module(__name__) + + @admin.route('/') + def index(): + pass + + @admin.route('/login') + def login(): + pass + """ def __init__(self, import_name, name=None, url_prefix=None): if name is None: @@ -353,14 +395,18 @@ class Module(_PackageBoundObject): self._register_events = [] def route(self, rule, **options): - """Like :meth:`flask.Flask.route` but for a module""" + """Like :meth:`Flask.route` but for a module. The endpoint for the + :func:`url_for` function is prefixed with the name of the module. + """ def decorator(f): self.add_url_rule(rule, f.__name__, f, **options) return f return decorator def add_url_rule(self, rule, endpoint, view_func=None, **options): - """Like :meth:`flask.Flask.add_url_rule` but for a module""" + """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. + """ def register_rule(state): the_rule = rule if self.url_prefix: @@ -370,17 +416,39 @@ class Module(_PackageBoundObject): self._record(register_rule) def before_request(self, f): - """Like :meth:`flask.Flask.before_request` but for a module""" + """Like :meth:`Flask.before_request` but for a module. This function + is only executed before each request that is handled by a function of + that module. + """ self._record(lambda s: s.app.before_request_funcs .setdefault(self.name, []).append(f)) return f + def before_app_request(self, f): + """Like :meth:`Flask.before_request`. Such a function is executed + before each request. + """ + self._record(lambda s: s.app.before_request_funcs + .setdefault(None, []).append(f)) + return f + def after_request(self, f): - """Like :meth:`flask.Flask.after_request` but for a module""" + """Like :meth:`Flask.after_request` but for a module. This function + is only executed after each request that is handled by a function of + that module. + """ self._record(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. + """ + self._record(lambda s: s.app.after_request_funcs + .setdefault(None, []).append(f)) + return f + def _record(self, func): self._register_events.append(func) @@ -594,7 +662,11 @@ class Flask(_PackageBoundObject): session.save_cookie(response, self.session_cookie_name) def register_module(self, module, **options): - """Registers a module with this application.""" + """Registers a module with this application. The keyword argument + of this function are the same as the ones for the constructor of the + :class:`Module` class and will override the values of the module if + provided. + """ options.setdefault('url_prefix', module.url_prefix) state = _ModuleSetupState(self, **options) for func in module._register_events: