Skip to content

Commit

Permalink
Started work on URL value preprocessors
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed May 29, 2011
1 parent f7e71b5 commit 5da1fc2
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
50 changes: 49 additions & 1 deletion flask/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,28 @@ def __init__(self, import_name, static_path=None, static_url_path=None,
#: .. versionadded:: 0.7
self.teardown_request_funcs = {}

#: A dictionary with lists of functions that can be used as URL
#: value processor functions. Whenever a URL is built these functions
#: are called to modify the dictionary of values in place. The key
#: `None` here is used for application wide
#: callbacks, otherwise the key is the name of the blueprint.
#: Each of these functions has the chance to modify the dictionary
#:
#: .. versionadded:: 0.7
self.url_value_preprocessors = {}

#: A dictionary with lists of functions that can be used as URL value
#: preprocessors. The key `None` here is used for application wide
#: callbacks, otherwise the key is the name of the blueprint.
#: Each of these functions has the chance to modify the dictionary
#: of URL values before they are used as the keyword arguments of the
#: view function. For each function registered this one should also
#: provide a :meth:`url_defaults` function that adds the parameters
#: automatically again that were removed that way.
#:
#: .. versionadded:: 0.7
self.url_default_functions = {}

#: A dictionary with list of functions that are called without argument
#: to populate the template context. The key of the dictionary is the
#: name of the blueprint this function is active for, `None` for all
Expand Down Expand Up @@ -826,6 +848,22 @@ def context_processor(self, f):
self.template_context_processors[None].append(f)
return f

def url_value_preprocessor(self, f):
"""Registers a function as URL value preprocessor for all view
functions of the application. It's called before the view functions
are called and can modify the url values provided.
"""
self.url_value_preprocessors.setdefault(None, []).append(f)
return f

def url_defaults(self, f):
"""Callback function for URL defaults for all view functions of the
application. It's called with the endpoint and values and should
update the values passed in place.
"""
self.url_default_functions.setdefault(None, []).append(f)
return f

def handle_http_exception(self, e):
"""Handles an HTTP exception. By default this will invoke the
registered error handlers and fall back to returning the
Expand Down Expand Up @@ -981,9 +1019,19 @@ def preprocess_request(self):
If any of these function returns a value it's handled as
if it was the return value from the view and further
request handling is stopped.
This also triggers the :meth:`url_value_processor` functions before
the actualy :meth:`before_request` functions are called.
"""
funcs = self.before_request_funcs.get(None, ())
bp = request.blueprint

funcs = self.url_value_preprocessors.get(None, ())
if bp is not None and bp in self.url_value_preprocessors:
funcs = chain(funcs, self.url_value_preprocessors[bp])
for func in funcs:
func(request.endpoint, request.values)

funcs = self.before_request_funcs.get(None, ())
if bp is not None and bp in self.before_request_funcs:
funcs = chain(funcs, self.before_request_funcs[bp])
for func in funcs:
Expand Down
32 changes: 32 additions & 0 deletions flask/blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,35 @@ def decorator(f):
self._record_once(lambda s: s.app.errorhandler(code)(f))
return f
return decorator

def url_value_preprocessor(self, f):
"""Registers a function as URL value preprocessor for this
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
.setdefault(self.name, []).append(f))
return f

def url_defaults(self, f):
"""Callback function for URL defaults for this module. It's called
with the endpoint and values and should update the values passed
in place.
"""
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
.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
.setdefault(None, []).append(f))
return f

0 comments on commit 5da1fc2

Please sign in to comment.