Browse Source

Added support for basic URL generation without request contexts.

pull/483/head
Armin Ronacher 13 years ago
parent
commit
307d1bc4e5
  1. 19
      flask/app.py
  2. 1
      flask/ctx.py
  3. 50
      flask/helpers.py
  4. 38
      flask/testsuite/appctx.py

19
flask/app.py

@ -250,7 +250,8 @@ class Flask(_PackageBoundObject):
'SESSION_COOKIE_SECURE': False,
'MAX_CONTENT_LENGTH': None,
'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
@ -1370,9 +1371,21 @@ class Flask(_PackageBoundObject):
so the request is passed explicitly.
.. 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,
server_name=self.config['SERVER_NAME'])
if request is not None:
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):
"""Injects the URL defaults for the given endpoint directly into

1
flask/ctx.py

@ -70,6 +70,7 @@ class AppContext(object):
def __init__(self, app):
self.app = app
self.url_adapter = app.create_url_adapter(None)
def push(self):
"""Binds the app context to the current context."""

50
flask/helpers.py

@ -50,7 +50,8 @@ except ImportError:
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():
@ -197,27 +198,40 @@ def url_for(endpoint, **values):
:param _anchor: if provided this is added as anchor to the URL.
:param _method: if provided this explicitly specifies an HTTP method.
"""
ctx = _request_ctx_stack.top
blueprint_name = request.blueprint
if not ctx.request._is_old_module:
if endpoint[:1] == '.':
if blueprint_name is not None:
endpoint = blueprint_name + endpoint
else:
appctx = _app_ctx_stack.top
reqctx = _request_ctx_stack.top
# If request specific information is available we have some extra
# features that support "relative" urls.
if reqctx is not None:
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:]
external = values.pop('_external', False)
# Otherwise go with the url adapter from the appctx and make
# the urls external by default.
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:]
external = values.pop('_external', False)
url_adapter = appctx.url_adapter
external = values.pop('_external', True)
anchor = values.pop('_anchor', None)
method = values.pop('_method', None)
ctx.app.inject_url_defaults(endpoint, values)
rv = ctx.url_adapter.build(endpoint, values, method=method,
force_external=external)
appctx.app.inject_url_defaults(endpoint, values)
rv = url_adapter.build(endpoint, values, method=method,
force_external=external)
if anchor is not None:
rv += '#' + url_quote(anchor)
return rv

38
flask/testsuite/appctx.py

@ -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…
Cancel
Save