4

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)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Dexter
  • 6,170
  • 18
  • 74
  • 101

2 Answers2

4

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.

mementum
  • 3,153
  • 13
  • 20
tbicr
  • 24,790
  • 12
  • 81
  • 106
  • I mean isn't the design philosophically so that you can "common" static_files from "root /app/static" directory, and blueprint-specific files from /app/blueprint/static folder? Shouldn't it check for both by default otherwise every blueprint will have the same files repeating? I think it should be standard that it should first look in ROOT static, then in blueprint's static. – Dexter Aug 01 '14 at 20:41
  • A little disagree because blueprint more independent, for example, you can use admin module what use jquery.js of 1.9.0 and main application with jquery.js of 2.0.0. Also some files can have same names like `styles.css`. Just my opinion: use different urls for static for application and blueprint if blueprint do not use application static. – tbicr Aug 01 '14 at 21:36
0

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") }}

Jahaja
  • 3,222
  • 1
  • 20
  • 11
  • No this doesn't work. The view in the blueprint frontend still cannot detect the templates in root-app /app/templates folder. It also gives 404 for any static files. Despite having both ' (HEAD, OPTIONS, GET) -> static>, ' (HEAD, OPTIONS, GET) -> frontend.static>])... Could there be some sort of pathing, listening, or permissions issue? – Dexter Jul 24 '14 at 18:13
  • This was for the question that the headline was about, static and templates are two different things. The static files should work if done as I've written above. Templates should work, even though you say otherwise, if you remove the `template_folder='templates'` when creating a `Blueprint`. See https://github.com/Jahaja/psdash/tree/master/psdash for an example. – Jahaja Jul 24 '14 at 18:27
  • 1
    I finally got it working, apparently for static files you need a "/app" in your static_url_path... frontend = Blueprint('frontend', __name__, template_folder='../templates', static_folder='static', static_url_path='/app/static') – Dexter Jul 24 '14 at 19:07
  • Nevermind that was because it was under 'static' in 'frontend' folder (frontend/static)... I still can;t get root to work with this blueprint module. – Dexter Jul 24 '14 at 20:24
  • Hmm ok so having ONLY static_folder='app/static' seems to fix the problem inside the Flask object. – Dexter Jul 24 '14 at 20:27