6

My app has a lot of routes that use the same set of static files.

I have to define them for every route like this:

css_reset = url_for("static", filename="reset.css")
css_main = url_for("static", filename="main.css")
css_fonts = url_for("static", filename="fonts.css")

js_jquery = url_for("static", filename="jquery-1.7.2.min.js")
js_main = url_for("static", filename="main.js")

And then, when I render a template it looks like this:

return render_template("person.html",
                       css_main=css_main,
                       css_reset=css_reset,
                       css_fonts=css_fonts,
                       js_jquery=js_jquery,
                       js_main=js_main)

I'm new to flask and python and I think that what I'm doing is a bit ridiculous. Can I define them in one place and then just use in my templates, without copying and pasting in every route definition?

3 Answers 3

17

Instead of passing these variables to your templates every time you can register them as globals in Jinja:

app.jinja_env.globals.update(
    css_reset=url_for("static", filename="reset.css"),
    css_main=url_for("static", filename="main.css"),
    ...
)

Or, better yet, register a helper function:

app.jinja_env.globals['static'] = (
    lambda filename: url_for('static', filename=filename))

And then in your templates:

<link ref=stylesheet href="{{ static('main.css') }}">
Sign up to request clarification or add additional context in comments.

Comments

12

The simplest way is to use Flask-Assets extension.

    from flask.ext.assets import Environment, Bundle
    assets = Environment(app)
    css_all = Bundle('reset.css','main.css','fonts.css')
    assets.register('css_all',css_all)

In template:

    {% assets %}
    <link rel="stylesheet" href="{{ ASSET_URL }}">
    {% endassets %}

You can also compress css and js files for production by using certain options of this extension.

Since you need to use these files in many templates, define them in a base.html template and in every template extend that base.html. You don not have to write them again and again.

Comments

-1

You don't need to do that, url_for is for generating urls (so that when you change the structure of a url, you don't need to change it a dozen times). You can just use a fixed path to your static files directly in your templates instead. Just put your static files in /static folder and use it in your template :

<link rel="stylesheet" href="{{ YOUR_SITE_URL_HERE+'/static/main.css' }}">

Instead of replacing YOUR_SITE_URL with your site's url directly, you might want to define a variable in your config.py and use it in your template : {{ config['SITE_URL']+'/static/main.css' }}

3 Comments

Why would you do all that when simply writing this href="{{ url_for('static',filename='main.css')}}" would suffice?
Its premature optimisation at best. It should not matter much.
It's possible the same site could be served from multiple URLs for one. For another, what if the path upon which you're hosting static files changes - for instance, you move them to Amazon S3? I agree with both Simon Sapin and codecool above; use Flask-Assets, or define a Jinja helper, depending on where your assets are hosted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.