0

I am developing a Flask application, and have it set so that my app's CSS file is generated with a random name via this build script:

rm style/main-*.css;
KEY=`tr -dc A-Za-z0-9 </dev/urandom | head -c 6`;
postcss build ./style/src/main.css -o ./style/main-$KEY.css

This is mostly for cache-related reasons; but it regardless results in a name with the wildcard pattern main-*.css Since this name is randomized every build, I do not want to edit the template I include it in. Unfortunately, wildcards do not appear to work in Flask, as this:

<link rel='stylesheet" href='{{ url_for('static', filename='style/main-*.css') }}'>

… does nothing (except, of course, yield a 404). Is there a way to do this kind of behavior via Flask? Thank you.

  • 2
    A more common way to force a cache to update stylesheets/js/etc...is with a version parameter. See [here](https://stackoverflow.com/a/32427/4032503). – noslenkwah Feb 10 '21 at 23:29
  • 1
    better use the same url but with random parameter or with current timestamp or date and time ie. `main.css?2021.02.11_02.28.58` And this way you don't have to change url in template but you have to add function which always add different parameter to url. – furas Feb 11 '21 at 01:29
  • Nice idea @furas, however I was in the process of implementing it (since it was simpler) when I thought of a kink: if the user's browser caches a different url every time it loads a page, that can fill up their cache. At least with my method there's only a new url if the CSS was updated, making it more efficient for the end-user — and not any different for me. Either way, it's a hack. – K. Russell Smith Feb 11 '21 at 01:58
  • 1
    you can always use variable with the same value and change this variable only when you update `main.css` - you could even use function which get file time of creation for this variable. – furas Feb 11 '21 at 02:10

1 Answers1

2

You can write your own function and add it to the jinja2 environment as a global function.

import os
from glob import glob
from flask import current_app

def glob_assets(target):
    root = current_app.static_folder
    return [f[len(root)+1:] for f in glob(os.path.join(root, target))]

app.jinja_env.globals.update(get_assets=glob_assets)

Then you can add the stylesheets to the template within one iteration.

{% for css in get_assets('style/main-*.css') -%}
<link rel="stylesheet" href="{{ url_for('static', filename=css) }}">
{% endfor -%}
Detlef
  • 1,285
  • 2
  • 3
  • 12