Search code examples
python-3.xflaskstatic-files

Define static file directory per route (URL) in flask


I have several files: 1.html, 2.html, etc. which have this content:

1.html has

<h1>Hello</h1>
<img src="1-directory/image.jpg" />

2.html has

<h1>Hello</h1>
<img src="2-directory/image.jpg" />

etc.

So, every file has an image in <i>-directory/ (i varies: 1, 2, 3, ...). How can I load this images in flask for every file.

My route is:

@app.route('/docs/show/<int:i>')
def show(i):
    with open(i + '.html', 'r') as f:
        content = f.read()
        return render_template('show.html', content = content)

and my template show.html is

{content | safe}

So, I want to set <i>-directory in the flask for each file and so displaying the corresponding image.


Solution

  • You have to create the static folder and then you have to add all the folders with the image. You can follow this directory structure:

    PROJECT NAME
    >> static
      >> 1-directory
          >> 1.jpg
      >> 2-directory
          >> 2.jpg
      >> 3-directory
          >> 3.jpg
      >> 4-directory
          >> 4.jpg
    >> templates
      >> 1.html
      >> 2.html
      >> 3.html
      >> 4.html
      >> show.html
    >> venv folder
    >> app.py
    

    You can use this code for app.py:

    import flask
    
    app = flask.Flask(__name__)
    
    @app.route('/docs/show/<string:i>', methods=['GET'])
    def show(i):
        with open('templates/' + str(i) + '.html', 'r') as f:
            content = f.read()
        return flask.render_template('show.html', content = content)
    
    if __name__=='__main__':
        app.run('0.0.0.0',port=<your_port_name>)
    

    You can keep the 1.html as below:

    <h1>Hello</h1>
    <img src="/static/1-directory/1.jpg" />
    

    You can keep the 2.html as below:

    <h1>Hello</h1>
    <img src="/static/2-directory/2.jpg" />
    

    You can keep the 3.html as below:

    <h1>Hello</h1>
    <img src="/static/3-directory/3.jpg" />
    

    You can keep the 4.html as below:

    <h1>Hello</h1>
    <img src="/static/4-directory/4.jpg" />
    

    And, you can display your code in show.html (with the same way you have shown it):

    <html>
    <body>{{content | safe}}</body>
    </html>
    

    EDIT (As per your comments):

    I have created the file structure in the following way as per your comments:

    PROJECT NAME
    >> templates
      >> 1-directory
          >> 1.jpg
      >> 2-directory
          >> 2.jpg
      >> 3-directory
          >> 3.jpg
      >> 4-directory
          >> 4.jpg
      >> 1.html
      >> 2.html
      >> 3.html
      >> 4.html
      >> show.html
    >> venv folder
    >> app.py
    

    You can code for app.py like this:

    @app.route('/docs/show/<string:i>', methods=['GET'])
    def show(i):
        internal_html = flask.render_template(str(i)+'.html', file_name = str(i)+'-directory/'+str(i)+'.jpg')
        return flask.render_template('show.html', content = internal_html)
    
    @app.route('/serve_file/<path:filename>')
    def serve_file(filename):
        return flask.send_from_directory('templates/', filename)
    

    All your HTML files will be as shown below:

    <h1>Hello</h1>
    <img src="{{ url_for('serve_file', filename=file_name) }}" />
    

    Also, your show.html will be the same as the above code. Here, we are using this send_from_directory, because the flask does not serve other than /static folder. Thus, for external use of the folder, we have to use send_from_directory.