Stellar Sword
Stellar Sword

Reputation: 6216

Flask blueprint looks for static file in blueprint instead of root directory

The blueprint I have should look for static files in the root directory but it isn't.

Say I have a blueprint named 'frontend'. 'frontend' only has template_folder='frontend' passed in.

Even if I put the static files under /app/frontend/static/file.css, it doesn't find it. Neither does it find it in /app/static/file.css.

The console webserver says '404' for every css or js static file every time.

But I do have this showing when I print out url_maps:

<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>])

I initiated register_blueprint('frontend') like that.

frontend = Blueprint('frontend', __name__,template_folder='templates')

My index in view returns:

return render_template('frontend.html', pagination=pagination)

frontend.html can ONLY work in /app/frontend/templates

If you put frontend.html at /app/templates it does not work there either. Even if you remove the "template_folder" param.

File structure:

app
-app.py
--frontend
--frontend/templates  contains: (frontend.html) (base.html) (errors/404.html)
--static
--static/css (bootstrap.min.css) (what I want to grab with url_for inside base.html)

Upvotes: 4

Views: 7058

Answers (2)

tbicr
tbicr

Reputation: 26110

1. Templates

Each flask application, blueprint and module has jinja_loader. When your render_template start find your template it find before in application and then in each blueprint (see get_source and _iter_loader), until not find first exist file.

jinja_loader builds from object path and template folder name, for example, if your application, blueprint or module in /home/www/myapp (/usr/lib/python3.4/site-packages/myapp) folder and template folder than full template folder will be /home/www/myapp/template (/usr/lib/python3.4/site-packages/myapp/template).

It's mean if you have file in application template folder then you render it even if you render template in blueprint. Also if you don't have file in application template folder but in any in blueprint it steel will be rendered. So for blueprints better use unique template prefix to avoid template overriding (falsk_admin - admin/ template prefix).

For example for extension it helps use templates in packages and already have ability replace it in your application if you need it (if you want just inherit you need give new name for template).

2. URL rules

Rules do not have any blueprints prefixes - in blueprint you just concatenate prefix and rule and then use just it.

So all url rules will resolved with exist rules (see another answer https://stackoverflow.com/a/17146563/880326).

You can have same url rule descriptions (/static and /static) and only one endpoint.

3. Static files

For application by default exist static folder. For blueprint you should add static_folder argument. But if both rules will have same descriptions then you can't get files from both by default (with little code can).

For flask application, blueprint and module full static folder dependence form root_path which depends from __name__ argument.

However if you have blueprint without url prefix better set another static_url_path to avoid mistakes.

Upvotes: 4

Jahaja
Jahaja

Reputation: 3302

Try adding static_folder='static' when creating your Blueprint.

Furthermore, you can use the url_for function in jinja to print out your static paths.

{{ url_for(".static", filename="css/bootstrap.min.css") }}

Upvotes: 0

Related Questions