4

I tried following a tutorial which intends to demonstrate how to change the location the static and template folder from being in the root directory. However I cannot get the example to work. The application runs fine but returns a 404 when it looks for the stylesheet "GET /static/style.css HTTP/1.1" 404. So it seems like it can find the template but not the stylesheet.

My hello world example is below. Should I be using root_path, or maybe instance_path or template_folder and static_folder?

api_files
  static
    style.css
  templates
    index.html
api.py

api.py from flask import Flask, render_template, url_for

# here we can set a different root path
app = Flask(__name__, root_path='api_files/')

@app.route('/')
def index():
    """Render home page."""
    return render_template('index.html')  # we can render templates as usual

if __name__ == '__main__':
    app.run(debug=True)

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <link rel= "stylesheet" type= "text/css" href= {{ url_for('static', filename='style.css') }}>
</head>
<body>
  hello world
</body>
</html>

style.css

body {
  color: red;
}
Max888
  • 3,089
  • 24
  • 55
  • try this line instead? : static_url_path='api_files/static') – gittert Sep 27 '18 at 10:08
  • @gittert adding that line generates this error: ValueError: urls must start with a leading slash. If I add a leading slash static_url_path='/api_files/static' then the app runs but still 404 for the stylesheet. – Max888 Sep 27 '18 at 10:47
  • explanation as how it should work can be found here: https://stackoverflow.com/questions/16351826/link-to-flask-static-files-with-url-for – gittert Sep 27 '18 at 11:22
  • @gittert thanks. didn't need too change the url_for, just needed static_folder='api_files/static'. Not sure if this approach is correct but works for now :) – Max888 Sep 27 '18 at 13:50
  • That indeed was one of the things I noticed. Well done for figuring out yourself. – gittert Sep 27 '18 at 14:01

1 Answers1

6

I was following this very tutorial and faced the same problem. This Stack Overflow comment is correct -- you have pass an absolute path to root_path. If you don't, templates will work -- but the static content definitely won't.

My files look like this:

# │   hello.py
# │
# └───web-content
#     ├───static
#     │       style.css
#     │
#     └───templates
#             welcome.html

and hello.py now looks like:

import os
from flask import Flask, render_template

# important - pass an absolute path to root_path
app = Flask(__name__, root_path=os.path.join(os.getcwd(), 'web-content'))

@app.route('/page/<string:page_name>')
def render_static(page_name):
    return render_template(f'{page_name}.html')

if __name__ == "__main__":
    app.run()
sigint
  • 1,842
  • 1
  • 22
  • 27