Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flask html js css img reference 404 error

I have a large website with hundreds of href=".html, href="css/, href="img/ and src="js/ references throughout the various html pages. I've placed all the css, js, img, sound, etc... folders in the "static" folder and all the html files in the "template folder".

I do not want to go through all my html files and manually edit each href using Flask's "url_for" function.

Is there a way that I can leave my existing html files alone and tell flask to use the css/, js/, and image paths defined in these html files?

Right now the following code leads to a bunch of 404 errors

import os
from flask import Flask, render_template

PROJECT_PATH = os.path.dirname(os.path.realpath(__file__))

app = Flask(__name__,
    template_folder=os.path.join(PROJECT_PATH, 'templates'),
    static_folder=os.path.join(PROJECT_PATH, 'static')
)

@app.route('/')

def index():            
    return render_template('index.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080, debug=True)

Okay, based on Martijn's script, I got my site running using the following code. However, to catch my many href=someHTMLfile.html links in my index.html file, I added @app.route('/'). I'm wondering if there is a better way to do this?

from flask import Flask, render_template, safe_join, send_from_directory

app = Flask(__name__)

@app.route('/<any(css, js, img, fonts, sound):folder>/<path:filename>')
def toplevel_static(folder, filename):
filename = safe_join(folder, filename)
cache_timeout = app.get_send_file_max_age(filename)
   return send_from_directory(app.static_folder, filename, cache_timeout=cache_timeout)

@app.route('/<path:filename>')
def public(filename):
    return render_template(filename)

# @app.route('/')
# def index():          
# return render_template('index.html')

if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
like image 477
spitz Avatar asked Nov 10 '22 08:11

spitz


1 Answers

You can register additional routes to serve files from your static folder:

from flask import app, safe_join, send_from_directory

@app.route('/<any(css, img, js, sound):folder>/<path:filename>')
def toplevel_static(folder, filename):
    filename = safe_join(folder, filename)
    cache_timeout = app.get_send_file_max_age(filename)
    return send_from_directory(app.static_folder, filename,
                               cache_timeout=cache_timeout)

@app.route('/<path:htmlfile>.html')
def toplevel_static(htmlfile):
    filename = htmlfile + '.html'
    cache_timeout = app.get_send_file_max_age(filename)
    return send_from_directory(app.template_folder, filename,
                               cache_timeout=cache_timeout)

This replicates what the static view does, but for routes starting with /css/, /img/, /js/ or /sound/ instead. HTML files are loaded from your template folder instead.

like image 197
Martijn Pieters Avatar answered Nov 14 '22 22:11

Martijn Pieters