I am trying to dynamically create a list of links to files in a static folder and failing with nested {{ {{ }} }} that would be logically required.
A Flask server has files in
/Static/FileFolder
they are collected in a list with
FileList = []
for path in os.listdir(FileFolderPath):
if os.path.isfile(os.path.join(FileFolderPath, path)):
Filelist.append(path)
the Link is built with
return render_template('list.html', FileList = FileList)
and the Html has this piece
{% for item in FileList %}
<li><a href=" {{url_for('static', filename=' {{item}} ') }}">{{item}}</a> </li>
{% endfor %}
which fails as
filename=' {{item}} '
does not give me the url for the link to the file but just a nonsense link to
http://127.0.0.1:5020/static/ {{item}}
which has the wrong folder and name. So how can i give the correct folder and place a link to a {{item}} inside a {{ }} used for url_for ?
CodePudding user response:
You don't need the double curly braces inside a block that is already jinja templated
templates/lists.html
{% for item in FileList %}
<li><a href=" {{ url_for('file', variable=item) }}">{{item}}</a> </li>
{% endfor %}
app.py
import os
from flask import Flask, render_template
app = Flask(__name__)
def funk():
FileList = []
FileFolderPath = '.'
for path in os.listdir(FileFolderPath):
if os.path.isfile(os.path.join(FileFolderPath, path)):
FileList.append(path)
return FileList
@app.route('/')
def hello_world():
FileList = funk()
return render_template('./list.html', FileList = FileList)
@app.route('/<variable>/')
def file(variable):
return variable
terminal
export FLASK_APP=app.py
flask run
tree
.
├── app.py
└── templates
└── list.html
CodePudding user response:
What if you only use once the jinja2 markdown as it follows:
{% for link in links %}
<li><a href="/static/{{ link }}">{{ link }}</a> </li>
{% endfor %}
Another option, but this mainly depends on what you're trying to accomplish, is adding another route to your app.py
@app.route('/static/<page>')
def get_link(page):
return f'{page}'
and afterwards in your html file:
<li><a href="{{ url_for('get_link', page=link) }}">{{ link }}</a></li>
Also, you might want to consider using the PEP8 naming guidelines > https://peps.python.org/pep-0008/#type-variable-names
CodePudding user response:
As already mentioned, you can pass the variable containing the relative path to the file directly without brackets and quotation marks.
Note that you need the full relative path inside the static folder to reference the file with url_for('static', filename=...)
.
The following example uses the pathlib
module to implement your requirements.
from pathlib import Path
@app.route('/')
def index():
# ./static/path/to/folder/
p = Path(app.static_folder, 'path', 'to', 'folder')
filenames = [x.relative_to(app.static_folder) for x in p.iterdir() if x.is_file()]
return render_template('index.html', **locals())
<ul>
{% for filename in filenames -%}
<li><a href="{{ url_for('static', filename=filename) }}">{{ filename }}</a></li>
{% endfor -%}
</ul>