从无蓝图前缀的蓝图中提供静态文件 [英] Serve static files from blueprints without url prefix
问题描述
原因是当我部署应用程序时,构建过程将把我们的蓝图的所有文件,并把它们放到一个单独的文件夹(类似于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
。
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屋!