Serve static files from blueprints without url prefix

前端 未结 1 1727
粉色の甜心
粉色の甜心 2021-01-16 05:19

For development, I\'d like to serve static files from the blueprint\'s static folder. However, I don\'t want to load all files via the url prefix of the blueprint. Is there

相关标签:
1条回答
  • 2021-01-16 05:47

    You can't with default flask mechanism.

    In your your example you will create 3 rules for static forlder:

    Rule "/assets/<path:filename>" for "static" endpoint
    Rule "/assets/<path:filename>" for "foo.static" endpoint
    Rule "/assets/<path:filename>" for "bar.static" endpoint
    

    When flask will match your URL to rule it take first match and return it. In this case it return static endpoint rule. After will dispatched function for this endpoint, e.g. one folder.

    PS. I don't sure that exactly static endpoint, better check Map.update method.

    But you always can write own request descriptor, which will look at blue prints folders:

    class MyApp(Flask):
        def static_dispatchers(self):
            yield super(MyApp, self).send_static_file
            for blueprint in self.blueprints.values():
                yield blueprint.send_static_file
    
        def send_static_file(self, filename):
            last_exception = None
            for static_dispatcher in self.static_dispatchers():
                try:
                    return static_dispatcher(filename)
                except NotFound as e:
                    last_exception = e
            raise last_exception
    

    PS. This example doesn't include the blueprint registration sequence, because it stored in dict.

    But if you have two files with same name, then first file will processed. For example if you have next structure:

    /static
    /static/app.js "console.log('app');"
    /foo/static/app.js "console.log('foo app');"
    /foo/static/blue.js "console.log('foo blue');"
    /foo/static/foo.js "console.log('foo self');"
    /bar/static/app.js "console.log('bar app');"
    /bar/static/blue.js "console.log('foo blue');"
    /bar/static/bar.js "console.log('bar self');"
    

    And include scripts to page:

    <script src="{{ url_for('static', filename='app.js') }}"></script>
    <script src="{{ url_for('foo.static', filename='app.js') }}"></script>
    <script src="{{ url_for('bar.static', filename='app.js') }}"></script>
    <script src="{{ url_for('foo.static', filename='blue.js') }}"></script>
    <script src="{{ url_for('bar.static', filename='blue.js') }}"></script>
    <script src="{{ url_for('foo.static', filename='foo.js') }}"></script>
    <script src="{{ url_for('bar.static', filename='bar.js') }}"></script>
    

    You will have next result:

    app
    app
    app
    foo blue (or bar blue)
    foo blue (or bar blue)
    foo self
    bar self
    

    For js and css can concatenate files with same path, but can't do this for images.

    However I prefer use unique URL prefix for each blueprint, because it simple with url_for.

    0 讨论(0)
提交回复
热议问题