Browse Source

Refactored static folder registration

pull/112/head
Armin Ronacher 15 years ago
parent
commit
15012af700
  1. 27
      flask/app.py
  2. 24
      flask/helpers.py
  3. 28
      flask/module.py

27
flask/app.py

@ -10,7 +10,6 @@
"""
import os
import posixpath
from threading import Lock
from datetime import timedelta, datetime
from itertools import chain
@ -21,7 +20,7 @@ from werkzeug.routing import Map, Rule
from werkzeug.exceptions import HTTPException, InternalServerError, NotFound
from flask.helpers import _PackageBoundObject, url_for, get_flashed_messages, \
_tojson_filter, send_file
_tojson_filter
from flask.wrappers import Request, Response
from flask.config import ConfigAttribute, Config
from flask.ctx import _default_template_ctx_processor, _RequestContext
@ -101,6 +100,9 @@ class Flask(_PackageBoundObject):
#: Path for the static files. If you don't want to use static files
#: you can set this value to `None` in which case no URL rule is added
#: and the development server will no longer serve any static files.
#:
#: This is the default used for application and modules unless a
#: different value is passed to the constructor.
static_path = '/static'
#: The debug flag. Set this to `True` to enable debugging of the
@ -190,8 +192,10 @@ class Flask(_PackageBoundObject):
'SERVER_NAME': None
})
def __init__(self, import_name):
def __init__(self, import_name, static_path=None):
_PackageBoundObject.__init__(self, import_name)
if static_path is not None:
self.static_path = static_path
#: The configuration dictionary as :class:`Config`. This behaves
#: exactly like a regular dictionary but supports additional methods
@ -258,7 +262,8 @@ class Flask(_PackageBoundObject):
#: app.url_map.converters['list'] = ListConverter
self.url_map = Map()
if self.static_path is not None:
# if there is a static folder, register it for the application.
if self.has_static_folder:
self.add_url_rule(self.static_path + '/<filename>',
endpoint='static',
view_func=self.send_static_file)
@ -377,20 +382,6 @@ class Flask(_PackageBoundObject):
options.setdefault('use_debugger', self.debug)
return run_simple(host, port, self, **options)
def send_static_file(self, filename):
"""Function used internally to send static files from the static
folder to the browser.
.. versionadded:: 0.5
"""
filename = posixpath.normpath(filename)
if filename.startswith('../'):
raise NotFound()
filename = os.path.join(self.root_path, 'static', filename)
if not os.path.isfile(filename):
raise NotFound()
return send_file(filename, conditional=True)
def test_client(self):
"""Creates a test client for this application. For information
about unit testing head over to :ref:`testing`.

24
flask/helpers.py

@ -11,6 +11,7 @@
import os
import sys
import posixpath
import mimetypes
from time import time
from zlib import adler32
@ -330,6 +331,29 @@ class _PackageBoundObject(object):
#: Where is the app root located?
self.root_path = _get_package_path(self.import_name)
@property
def has_static_folder(self):
"""This is `True` if the package bound object's container has a
folder named ``'static'``.
.. versionadded:: 0.5
"""
return os.path.isdir(os.path.join(self.root_path, 'static'))
def send_static_file(self, filename):
"""Function used internally to send static files from the static
folder to the browser.
.. versionadded:: 0.5
"""
filename = posixpath.normpath(filename)
if filename.startswith('../'):
raise NotFound()
filename = os.path.join(self.root_path, 'static', filename)
if not os.path.isfile(filename):
raise NotFound()
return send_file(filename, conditional=True)
def open_resource(self, resource):
"""Opens a resource from the application's resource folder. To see
how this works, consider the following folder structure::

28
flask/module.py

@ -12,6 +12,27 @@
from flask.helpers import _PackageBoundObject
def _register_module_static(module):
"""Internal helper function that returns a function for recording
that registers the `send_static_file` function for the module on
the application of necessary.
"""
def _register_static(state):
# do not register the rule if the static folder of the
# module is the same as the one from the application.
if state.app.root_path == module.root_path:
return
path = static_path
if path is None:
path = state.app.static_path
if state.url_prefix:
path = state.url_prefix + path
state.app.add_url_rule(path + '/<filename>',
'%s.static' % module.name,
view_func=module.send_static_file)
return _register_static
class _ModuleSetupState(object):
def __init__(self, app, url_prefix=None):
@ -67,7 +88,8 @@ class Module(_PackageBoundObject):
:ref:`working-with-modules` section.
"""
def __init__(self, import_name, name=None, url_prefix=None):
def __init__(self, import_name, name=None, url_prefix=None,
static_path=None):
if name is None:
assert '.' in import_name, 'name required if package name ' \
'does not point to a submodule'
@ -77,6 +99,10 @@ class Module(_PackageBoundObject):
self.url_prefix = url_prefix
self._register_events = []
# if there is a static folder, register it for this module
if self.has_static_folder:
self._record(_register_module_static(self))
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.

Loading…
Cancel
Save