0

Using Flask, I can render different templates based on the url. For example :

This works really great with jinja_loader and a custom Loader, but now I'm stuck with the static files.

The static files depends on the template, so they are located in templates/static/site{0-9}, but of course, I cannot set a jinja_loader on the static_folder parameter because it's not related to Jinja but to Flask.

How can I render the correct static folder based on the current URL?

As an example, here's the loaded code:

Flask(app_name,
        static_url_path = '/public',
        static_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates/static')
    )

and in templates/static, I have :

static/
    site1/
        css/
        js/
        images/
    site2/
        css/
        js/
        images/
    etc...
6
  • I'm not sure what you are asking. Can you provide some URLs and how they should map to actual files? Commented Mar 17, 2014 at 11:42
  • I updated the question, does it helps more ? Commented Mar 17, 2014 at 12:05
  • And your templates are using url_for('static', 'site1/css/...'), etc. to generate the correct URLs already? What is the exact problem here? Commented Mar 17, 2014 at 12:06
  • No, my templates uses {{url_for('static', filename='css/...')}}. Ideally, I would modify where Flask search for the static files when rendering /public/css/..., to search not in /templates/static/css/..., but in /templates/static/site1/css/... Commented Mar 17, 2014 at 12:13
  • You'll need to produce your own static view handler then. Commented Mar 17, 2014 at 12:17

2 Answers 2

1

You either have to use explicit paths in your static views:

url_for('static', filename='site1/css/...')

where site1 could be taken from request.path.split('/', 1)[0]:

url_for('static', filename='{}/css/...'.format(request.path.split('/', 1)[0]))

You could create a custom static view:

from flask import request, send_from_directory, current_app, safe_join
import os.path

@app.route('/<site>/static/<path:filename>')
def per_site_static(site, filename):
    if site is None:
        # pick site from the URL; only works if there is a `/site/` first element.
        site = request.path.split('/')[0]
    static_folder = safe_join(current_app.static_folder, site)
    cache_timeout = current_app.get_send_file_max_age(filename)
    return send_from_directory(static_folder, filename,
                               cache_timeout=cache_timeout)

Then use url_for() to generate urls:

{{ url_for('per_site_static', site=None, filename='css/...') }}
Sign up to request clarification or add additional context in comments.

Comments

0

An other interesting alternative is the following :

class GenericStaticFlask(Flask):
    def send_static_file(self, filename):
        # g.site contains the name of the template path for siteX
        return super(GenericStaticFlask, self).send_static_file("%s/%s" % (g.site, filename))

app = GenericStaticFlask(app_name,
    static_url_path = '/public',
    static_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates/static')
)

Comments

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.