2

I am making a website using Flask. It's utilizing a base template in HTML, which is used for all pages. In the base page (called base.html) there is some references to various static files. The references are using relative paths.

Here is a couple of examples from base.html:

<link rel="stylesheet" href="../static/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="../static/css/main.css">

This works fine, as long as I don't include input parameters in my route, but rather get them from requests like this:

@app.route('/person/delete')
def delete_person():
    id = request.args.get('id')
    # some more logic here...

However, if I change my route to include the input parameters, like this:

@app.route('/person/delete/<int:id>')
def delete_person(id):
    # some more logic here...

Then my relative path will fail. It seems that I am one level to deep, in the latter example. At least I get the following error in the log:

127.0.0.1 - - [29/Dec/2019 19:20:14] "GET /person/static/css/bootstrap-theme.min.css HTTP/1.1" 404 -
127.0.0.1 - - [29/Dec/2019 19:20:14] "GET /person/static/css/main.css HTTP/1.1" 404 -

The person part should not be a part of the URL, as the static folder is in the root level. Is there some clever way to counter this behavior?

Note: I could probably avoid relative paths in the base.html file and simply use some sort of shortcut to the base folder, but that would potentially mean that I can never use relative paths. That would be quite sad.

Jakob Busk Sørensen
  • 5,599
  • 7
  • 44
  • 96

1 Answers1

4

As mentioned in comments, url_for is the proper solution.

An example from other project:

<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='nnn.min.css') }}">

In general, url_for cannot be replaced by hardcoded URLs, not even absolute ones, because the whole Flask application may be deployed with a prefix in its base URL, e.g. https://www.example.com/appname. The appname is a part of the configuration and it is known only at runtime.

VPfB
  • 14,927
  • 6
  • 41
  • 75
  • 1
    Thanks, I will use that instead of a relative path. If anyone else, like me, should struggle with subfolders, they go in front of the file name :-). – Jakob Busk Sørensen Dec 29 '19 at 20:52