从无蓝图前缀的蓝图中提供静态文件 [英] Serve static files from blueprints without url prefix

查看:171
本文介绍了从无蓝图前缀的蓝图中提供静态文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于开发,我想从蓝图的静态文件夹中提供静态文件。但是,我不想通过蓝图的url前缀加载所有文件。有没有可能配置瓶,所以它会查看所有蓝图的静态文件夹,并返回它找到的第一个文件?
原因是当我部署应用程序时,构建过程将把我们的蓝图的所有文件,并把它们放到一个单独的文件夹(类似于Django的collectstatics)。



换句话说,我有两个蓝图: foo bar

  app 
+ --- foo
| + ---资产
| | + --- css
| | |
| | + --- js
| +
| |
| + --- __init__.py:foo_blueprint = Blueprint('foo',__name__,static_folder ='assets')
|
+ --- bar
+
|
+ __init__.py:bar_blueprint =蓝图('bar',__name__,static_folder ='assets')

我希望可以从url /static/js/file.js找到特定 js 子文件夹中的所有js文件。这可能吗?

解决方案

您不能使用默认的 flask 机制。
$ b $ p

在你的例子中,你将为static forlder创建3条规则:

 规则/ assets /<路径:文件名>为静态端点
规则/ assets /<路径:文件名>为foo.static端点
规则/ assets /<路径:文件名>为bar.static端点

当烧瓶符合您的网址规则时,首先匹配并返回它。在这种情况下,它返回静态端点规则。之后将调度该端点的功能,例如一个文件夹。



PS。我不确定静态端点,最好检查 Map.update 方法。



但是你总是可以编写自己的请求描述符,它会查看蓝色的打印文件夹:

  class MyApp(Flask):
def static_dispatchers(self):
产生超级(MyApp,self).send_static_file
为blueprint self.blueprints.values():
产生蓝图。 send_static_file
$ b def send_static_file(self,filename):
last_exception = None
for self.static_dispatchers()中的static_dispatcher:
try:
return static_dispatcher(文件名)
,不包括NotFound作为e:
last_exception = e
提升last_exception

PS。这个例子不包括蓝图注册序列,因为它存储在字典中。



但是如果你有两个同名的文件,那么第一个文件将被处理。例如,如果你有下一个结构:

$ $ p $ code $静态
/static/app.js console.log('应用);
/foo/static/app.jsconsole.log('foo app');
/foo/static/blue.jsconsole.log('foo blue');
/foo/static/foo.jsconsole.log('foo self');
/bar/static/app.jsconsole.log('bar app');
/bar/static/blue.jsconsole.log('foo blue');
/bar/static/bar.jsconsole.log('bar self');

并包含脚本到页面:

 < 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>

您将获得下一个结果:

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

对于js和css可以连接具有相同路径的文件,但是不能这样做不过我更喜欢每个蓝图都使用唯一的URL前缀,因为它简单易用 url_for

p>

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 a possibility to configure flask, so it looks in all blueprint's static folders and returns the first file it finds? The reason for this is that when I deploy the application, the build process will pull all the files our of the blueprints and put them into a separate folder (similar to Django's collectstatics).

In other words, I have 2 blueprints: foo and bar:

app
  +--- foo
  |    +--- assets
  |    |     +--- css
  |    |     |
  |    |     +--- js
  |    +
  |    |
  |    +--- __init__.py:  foo_blueprint = Blueprint('foo', __name__, static_folder='assets')
  |
  +--- bar
       +
       |
       +--- __init__.py: bar_blueprint = Blueprint('bar', __name__, static_folder='assets')

I want all js files in the particular js subfolders to be available from the url /static/js/file.js. Is this possible?

解决方案

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.

这篇关于从无蓝图前缀的蓝图中提供静态文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆