Create directory of dynamically created html files. Flask - python

I've got a simple flask app, with a templates folder with a bunch of html files that are created by a separate program. I want to (1) serve each of these html files by hitting localhost:8888/<html_filename> and
(2) create a directory with hyperlinks to these endpoints on my main / endpoint.
Thoughts on how I could get a jinja template to create links to those endpoints? Heres what I've been thinking.
Flask App:
#app.route('/')
def index():
reports = [f_name for f_name in os.listdir("templates") if f_name.endswith(".html")]
return render_template("index.html", reports=reports)
#app.route('/<report>')
def render_report(report):
return render_template(report+'.html')
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Report Directory</title>
</head>
<body>
<ul>
{% for r in reports %}
<li>
{{ r }}
</li>
{% endfor %}
</ul>
</body>
</html>

Off the top of my head and not tested in any way define a route along the lines of the following:
#route("/<string:slug>/", methods=['GET'])
def page(self, slug):
if slug_exists_as_a_html_file(slug):
return render_template(slug)
abort(404)
The function (or inline it) )slug_exists_as_a_html_file needs to return True if the slug matches a valid html template file, otherwise false.
To generate your report listing use something like :
<!DOCTYPE html>
<html lang="en">
<head>
<title>Report Directory</title>
</head>
<body>
<ul>
{% for r in reports %}
<li>
{{ r }}
</li>
{% endfor %}
</ul>
</body>
</html>

Related

python flask render_template and another return value

I use Python flask for my web application. the application provide a CSV file to download. CSV file is the response in below code block. Also I need to send a variable to html template. How can I have two return value?
#application.route("/log_analysis", methods=['POST'])
def get_response():
output='The result of your query : '+str(i-1)+' . The full report is downloaded automatically.'
cw.writerows(csv_rows)
response = make_response(si.getvalue())
response.headers["Content-Disposition"] = f"attachment; filename={return_file_name}"
response.headers["Content-type"] = "text/csv"
return render_template('base.html',output=output)
return response, 200
The output will be shown in the html but the response in the second return doesn't work.
After reading your question, I think what you are looking for is something like flash messages. The variable content you are passing in, is just text and used to display a message.
Flash messages
You'll need to set this up in your base.html or whatever template you are rendering.
Template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link href="{{ url_for('static', filename='css/main.css')}}" rel="stylesheet">
</head>
<body>
<main>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</main>
</body>
</html>
from flask import render_template, url_for, flash, redirect
#application.route("/log_analysis", methods=['POST'])
def get_response():
output=f'The result of your query : {i-1} . The full report is downloaded automatically.'
cw.writerows(csv_rows)
response = make_response(si.getvalue())
response.headers["Content-Disposition"] = f"attachment; filename={return_file_name}"
response.headers["Content-type"] = "text/csv"
flash(output,'success')
return response, 200
You can also try and do something like alerts in html template

How do you render a variable as html using flask?

Using flask, I'm passing in a list of dictionaries to one of the pages. One of the variables contains html text (ex:var x = <h1>hello</h1>). How would I get it to display as hello rather than just print out "<h1>hello</h1>"? Here's my code so far (post.description has the html variable; It's equal to <h1>hello</h1>):
<!DOCTYPE html>
<html>
<head>
</head>
<body>
{% for post in posts %}
<p>{{post.title}}<p>
{{post.description}}
{% endfor %}
</body>
</html>
You can use safe to render the HTML code with Jinja.
Example: {{ post.description | safe }}

'str' object has no attribute 'method'

I am trying to access a request.method in a python view, but I'm getting the error
'str' object has no attribute 'method'
The really odd thing is that I can see no difference between how I set up this page and how I set up another similar page; yet that one works fine and this one does not.
The code I am using is as follows:
main/views.py:
from .alphabetize import alphabetize
from .forms import WordListForm
def alphabetize(request):
if request.method == "POST":
form = WordListForm(request.POST)
if form.is_valid():
word_list = alphabetize(form.cleaned_data['word_list'])
return render(request, 'main/alphabetize.html', {'form': form, 'word_list': word_list})
else:
form = WordListForm()
return render(request, 'main/alphabetize.html', {'form': form})
/main/forms.py
class WordListForm(forms.Form):
word_list = forms.CharField(label="Word List")
main/urls.py
from django.conf.urls import url
from main import views
urlpatterns = [
url(r'alphabetize', views.alphabetize, name='alphabetize'),
]
main/alphabetize.py
def alphabetize(s):
word_list = []
for word in s.split(','):
word_list.append(word.strip())
word_list.sort()
return ', '.join(word_list)
templates/main/alphabetize.html
{% extends "base.html" %}
{% block content %}
<form action="/alphabetize" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
<p>Your list alphabetized: {{ alpha_list }}</p>
{% endblock content %}
/templates/base.html
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Awesome Django Page</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
<div class="main">
{% block content %}{% endblock content %}
</div>
</body>
</html>
It seems that for some reason request is a string rather than an HttpRequest object, but I can't figure out why that would be.
You have two different functions called alphabetize; your view, and your utility function. As a result your view is calling itself, rather than the other function.
You should rename one of these.
Your view name overrides imported function alphabetize. Change view name to fix:
from .alphabetize import alphabetize
from .forms import WordListForm
def alphabetize_view(request):

How to handle a variable in HTML?

I have the following flask application that displays a dashboard with various buttons. Each button executes a python function. After the execution of such a function I want the application to return to the dashboard. In order to give the user a simple log I want to output some string on the html page. For that thought about a tag above the buttons on the dashboard that get filled with the respective value. How can I do that?
Flask:
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def main():
return render_template('index.html')
#app.route('/something')
def do_something():
print("Hello")
return render_template('index.html', user="Successfully executed!")
if __name__ == "__main__":
app.run()
HTML:
<!DOCTYPE html>
<html>
<head>
<head>
<meta charset="UTF-8">
</head>
<title>MP Reporting</title>
</head>
<body>
<div value=user></div>
Your button
</body>
</html>
For flask template use "{{kwarg}}" i.e. in your example
<div>{{user}}</div>
will render as
<div>Successfully executed!</div>
In addition to other answers, I suggest using Flask's built-in message flashing which is simpler, and neater instead of passing variables to render_template manually. It's simple as that:
(template)
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div>{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
(flask view)
from flask import flash
flash("Successfully executed!")
You can get more information from here.
You can print variables using Jinja2.
To print out the variable user in your example add
{{ user }} in the html template.
If you send a list of items to the html you can output them by using a simple for:
{% for item in items %}
{{ item }}
{% endfor %}

flask isnt reading or interpreting css file

I'm basically trying to follow this tutorial ( http://net.tutsplus.com/tutorials/python-tutorials/an-introduction-to-pythons-flask-framework/)
Now when the css part comes in, and i copy the code it simply wont come out styled even afterr main.css is added it still shows up unstyled like if it wasn't importing the css file here's the HTML code
<!DOCTYPE html>
<html>
<head>
<title>Flask</title>
<strong><link rel="stylesheet" type"text/css" href="{{ url_for('static', filename='css/main.css') }}"></strong>
</head>
<body>
<header>
<div class="container">
<h1 class="logo">Flask App</h1>
</div>
</header>
<div class="container">
{% block content %}
{% endblock %}
</div>
</body>
</html>
layout.html ^
Home.html v
{% extends "layout.html" %}
{% block content %}
<div class="jumbo">
<h2>Welcome to the Flask app<h2>
<h3>This is the home page for the Flask app<h3>
</div>
{% endblock %}
routes.py v
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def home():
return render_template('home.html')
if __name__ == '__main__':
app.run(debug=True)
This is probably due to the directory structure of your app. By default, flask looks for the static directory in the same level as the file that the app object is created in. This is the example structure for a small application from the flask docs.
/yourapplication
/yourapplication.py
/static
/style.css
/templates
layout.html
index.html
login.html
You can also change the location of the static files by setting the "static_folder" attribute on the app object. Check the docs here for setting the static_folder

Categories