diff --git a/docs/sanic/blueprints.md b/docs/sanic/blueprints.md index 5be33cb6..1a7c5293 100644 --- a/docs/sanic/blueprints.md +++ b/docs/sanic/blueprints.md @@ -93,7 +93,14 @@ def ignore_404s(request, exception): Static files can be served globally, under the blueprint prefix. ```python -bp.static('/folder/to/serve', '/web/path') + +# suppose bp.name == 'bp' + +bp.static('/web/path', '/folder/to/serve') +# also you can pass name parameter to it for url_for +bp.static('/web/path', '/folder/to/server', name='uploads') +app.url_for('static', name='bp.uploads', filename='file.txt') == '/bp/web/path/file.txt' + ``` ## Start and stop diff --git a/docs/sanic/routing.md b/docs/sanic/routing.md index 49b7c0b8..7a562b66 100644 --- a/docs/sanic/routing.md +++ b/docs/sanic/routing.md @@ -301,3 +301,34 @@ def handler(request): # app.url_for('handler') == '/get' # app.url_for('post_handler') == '/post' ``` + +## Build URL for static files + +You can use `url_for` for static file url building now. +If it's for file directly, `filename` can be ignored. + +```python + +app = Sanic('test_static') +app.static('/static', './static') +app.static('/uploads', './uploads', name='uploads') +app.static('/the_best.png', '/home/ubuntu/test.png', name='best_png') + +bp = Blueprint('bp', url_prefix='bp') +bp.static('/static', './static') +bp.static('/uploads', './uploads', name='uploads') +bp.static('/the_best.png', '/home/ubuntu/test.png', name='best_png') +app.blueprint(bp) + +# then build the url +app.url_for('static', filename='file.txt') == '/static/file.txt' +app.url_for('static', name='static', filename='file.txt') == '/static/file.txt' +app.url_for('static', name='uploads', filename='file.txt') == 'uploads/file.txt' +app.url_for('static', name='best_png') == '/the_best.png' + +# blueprint url building +app.url_for('static', name='bp.static', filename='file.txt') == '/bp/static/file.txt' +app.url_for('static', name='bp.uploads', filename='file.txt') == '/bp/uploads/file.txt' +app.url_for('static', name='bp.best_png') == '/bp/static/the_best.png' + +``` diff --git a/docs/sanic/static_files.md b/docs/sanic/static_files.md index f0ce9d78..3419cad1 100644 --- a/docs/sanic/static_files.md +++ b/docs/sanic/static_files.md @@ -6,16 +6,40 @@ filename. The file specified will then be accessible via the given endpoint. ```python from sanic import Sanic +from sanic.blueprints import Blueprint + app = Sanic(__name__) # Serves files from the static folder to the URL /static app.static('/static', './static') +# use url_for to build the url, name defaults to 'static' and can be ignored +app.url_for('static', filename='file.txt') == '/static/file.txt' +app.url_for('static', name='static', filename='file.txt') == '/static/file.txt' # Serves the file /home/ubuntu/test.png when the URL /the_best.png # is requested -app.static('/the_best.png', '/home/ubuntu/test.png') +app.static('/the_best.png', '/home/ubuntu/test.png', name='best_png') + +# you can use url_for to build the static file url +# you can ignore name and filename parameters if you don't define it +app.url_for('static', name='best_png') == '/the_best.png' +app.url_for('static', name='best_png', filename='any') == '/the_best.png' + +# you need define the name for other static files +app.static('/another.png', '/home/ubuntu/another.png', name='another') +app.url_for('static', name='another') == '/another.png' +app.url_for('static', name='another', filename='any') == '/another.png' + +# also, you can use static for blueprint +bp = Blueprint('bp', url_prefix='/bp') +bp.static('/static', './static') + +# servers the file directly +bp.static('/the_best.png', '/home/ubuntu/test.png', name='best_png') +app.blueprint(bp) + +app.url_for('static', name='bp.static', filename='file.txt') == '/bp/static/file.txt' +app.url_for('static', name='bp.best_png') == '/bp/test_best.png' app.run(host="0.0.0.0", port=8000) ``` - -Note: currently you cannot build a URL for a static file using `url_for`. diff --git a/sanic/app.py b/sanic/app.py index 20c02a5c..3776c915 100644 --- a/sanic/app.py +++ b/sanic/app.py @@ -354,13 +354,13 @@ class Sanic: # Static Files def static(self, uri, file_or_directory, pattern=r'/?.+', use_modified_since=True, use_content_range=False, - stream_large_files=False): + stream_large_files=False, name='static'): """Register a root to serve files from. The input can either be a file or a directory. See """ static_register(self, uri, file_or_directory, pattern, use_modified_since, use_content_range, - stream_large_files) + stream_large_files, name) def blueprint(self, blueprint, **options): """Register a blueprint on the application. @@ -410,12 +410,32 @@ class Sanic: URLBuildError """ # find the route by the supplied view name - uri, route = self.router.find_route_by_view_name(view_name) + kw = {} + # special static files url_for + if view_name == 'static': + kw.update(name=kwargs.pop('name', 'static')) + elif view_name.endswith('.static'): # blueprint.static + kwargs.pop('name', None) + kw.update(name=view_name) - if not uri or not route: + uri, route = self.router.find_route_by_view_name(view_name, **kw) + if not (uri and route): raise URLBuildError('Endpoint with name `{}` was not found'.format( view_name)) + if view_name == 'static' or view_name.endswith('.static'): + filename = kwargs.pop('filename', None) + # it's static folder + if '