forked from orbit-oss/flask
Added support for basic URL generation without request contexts.
This commit is contained in:
parent
47288231fe
commit
307d1bc4e5
4 changed files with 87 additions and 21 deletions
19
flask/app.py
19
flask/app.py
|
|
@ -250,7 +250,8 @@ class Flask(_PackageBoundObject):
|
||||||
'SESSION_COOKIE_SECURE': False,
|
'SESSION_COOKIE_SECURE': False,
|
||||||
'MAX_CONTENT_LENGTH': None,
|
'MAX_CONTENT_LENGTH': None,
|
||||||
'TRAP_BAD_REQUEST_ERRORS': False,
|
'TRAP_BAD_REQUEST_ERRORS': False,
|
||||||
'TRAP_HTTP_EXCEPTIONS': False
|
'TRAP_HTTP_EXCEPTIONS': False,
|
||||||
|
'PREFERRED_URL_SCHEME': 'http'
|
||||||
})
|
})
|
||||||
|
|
||||||
#: The rule object to use for URL rules created. This is used by
|
#: The rule object to use for URL rules created. This is used by
|
||||||
|
|
@ -1370,9 +1371,21 @@ class Flask(_PackageBoundObject):
|
||||||
so the request is passed explicitly.
|
so the request is passed explicitly.
|
||||||
|
|
||||||
.. versionadded:: 0.6
|
.. versionadded:: 0.6
|
||||||
|
|
||||||
|
.. versionchanged:: 0.9
|
||||||
|
This can now also be called without a request object when the
|
||||||
|
UR adapter is created for the application context.
|
||||||
"""
|
"""
|
||||||
return self.url_map.bind_to_environ(request.environ,
|
if request is not None:
|
||||||
server_name=self.config['SERVER_NAME'])
|
return self.url_map.bind_to_environ(request.environ,
|
||||||
|
server_name=self.config['SERVER_NAME'])
|
||||||
|
# We need at the very least the server name to be set for this
|
||||||
|
# to work.
|
||||||
|
if self.config['SERVER_NAME'] is not None:
|
||||||
|
return self.url_map.bind(
|
||||||
|
self.config['SERVER_NAME'],
|
||||||
|
script_name=self.config['APPLICATION_ROOT'] or '/',
|
||||||
|
url_scheme=self.config['PREFERRED_URL_SCHEME'])
|
||||||
|
|
||||||
def inject_url_defaults(self, endpoint, values):
|
def inject_url_defaults(self, endpoint, values):
|
||||||
"""Injects the URL defaults for the given endpoint directly into
|
"""Injects the URL defaults for the given endpoint directly into
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ class AppContext(object):
|
||||||
|
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
self.app = app
|
self.app = app
|
||||||
|
self.url_adapter = app.create_url_adapter(None)
|
||||||
|
|
||||||
def push(self):
|
def push(self):
|
||||||
"""Binds the app context to the current context."""
|
"""Binds the app context to the current context."""
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,8 @@ except ImportError:
|
||||||
|
|
||||||
from jinja2 import FileSystemLoader
|
from jinja2 import FileSystemLoader
|
||||||
|
|
||||||
from .globals import session, _request_ctx_stack, current_app, request
|
from .globals import session, _request_ctx_stack, _app_ctx_stack, \
|
||||||
|
current_app, request
|
||||||
|
|
||||||
|
|
||||||
def _assert_have_json():
|
def _assert_have_json():
|
||||||
|
|
@ -197,27 +198,40 @@ def url_for(endpoint, **values):
|
||||||
:param _anchor: if provided this is added as anchor to the URL.
|
:param _anchor: if provided this is added as anchor to the URL.
|
||||||
:param _method: if provided this explicitly specifies an HTTP method.
|
:param _method: if provided this explicitly specifies an HTTP method.
|
||||||
"""
|
"""
|
||||||
ctx = _request_ctx_stack.top
|
appctx = _app_ctx_stack.top
|
||||||
blueprint_name = request.blueprint
|
reqctx = _request_ctx_stack.top
|
||||||
if not ctx.request._is_old_module:
|
|
||||||
if endpoint[:1] == '.':
|
# If request specific information is available we have some extra
|
||||||
if blueprint_name is not None:
|
# features that support "relative" urls.
|
||||||
endpoint = blueprint_name + endpoint
|
if reqctx is not None:
|
||||||
else:
|
url_adapter = reqctx.url_adapter
|
||||||
|
blueprint_name = request.blueprint
|
||||||
|
if not reqctx.request._is_old_module:
|
||||||
|
if endpoint[:1] == '.':
|
||||||
|
if blueprint_name is not None:
|
||||||
|
endpoint = blueprint_name + endpoint
|
||||||
|
else:
|
||||||
|
endpoint = endpoint[1:]
|
||||||
|
else:
|
||||||
|
# TODO: get rid of this deprecated functionality in 1.0
|
||||||
|
if '.' not in endpoint:
|
||||||
|
if blueprint_name is not None:
|
||||||
|
endpoint = blueprint_name + '.' + endpoint
|
||||||
|
elif endpoint.startswith('.'):
|
||||||
endpoint = endpoint[1:]
|
endpoint = endpoint[1:]
|
||||||
|
external = values.pop('_external', False)
|
||||||
|
|
||||||
|
# Otherwise go with the url adapter from the appctx and make
|
||||||
|
# the urls external by default.
|
||||||
else:
|
else:
|
||||||
# TODO: get rid of this deprecated functionality in 1.0
|
url_adapter = appctx.url_adapter
|
||||||
if '.' not in endpoint:
|
external = values.pop('_external', True)
|
||||||
if blueprint_name is not None:
|
|
||||||
endpoint = blueprint_name + '.' + endpoint
|
|
||||||
elif endpoint.startswith('.'):
|
|
||||||
endpoint = endpoint[1:]
|
|
||||||
external = values.pop('_external', False)
|
|
||||||
anchor = values.pop('_anchor', None)
|
anchor = values.pop('_anchor', None)
|
||||||
method = values.pop('_method', None)
|
method = values.pop('_method', None)
|
||||||
ctx.app.inject_url_defaults(endpoint, values)
|
appctx.app.inject_url_defaults(endpoint, values)
|
||||||
rv = ctx.url_adapter.build(endpoint, values, method=method,
|
rv = url_adapter.build(endpoint, values, method=method,
|
||||||
force_external=external)
|
force_external=external)
|
||||||
if anchor is not None:
|
if anchor is not None:
|
||||||
rv += '#' + url_quote(anchor)
|
rv += '#' + url_quote(anchor)
|
||||||
return rv
|
return rv
|
||||||
|
|
|
||||||
38
flask/testsuite/appctx.py
Normal file
38
flask/testsuite/appctx.py
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
flask.testsuite.appctx
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Tests the application context.
|
||||||
|
|
||||||
|
:copyright: (c) 2012 by Armin Ronacher.
|
||||||
|
:license: BSD, see LICENSE for more details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import with_statement
|
||||||
|
|
||||||
|
import flask
|
||||||
|
import unittest
|
||||||
|
from flask.testsuite import FlaskTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class AppContextTestCase(FlaskTestCase):
|
||||||
|
|
||||||
|
def test_basic_support(self):
|
||||||
|
app = flask.Flask(__name__)
|
||||||
|
app.config['SERVER_NAME'] = 'localhost'
|
||||||
|
app.config['PREFERRED_URL_SCHEME'] = 'https'
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
pass
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
rv = flask.url_for('index')
|
||||||
|
self.assert_equal(rv, 'https://localhost/')
|
||||||
|
|
||||||
|
|
||||||
|
def suite():
|
||||||
|
suite = unittest.TestSuite()
|
||||||
|
suite.addTest(unittest.makeSuite(AppContextTestCase))
|
||||||
|
return suite
|
||||||
Loading…
Add table
Add a link
Reference in a new issue