jinja2.exceptions.TemplateSyntaxError: expected token 'end of print statement', got '=' - python

Respected Members,
I'm creating a basic login page sans the DB setup. I'm not sure what I'm doing wrong while passing the jinja templates to the html file.
The .py file:
from flask import Flask, render_template, flash, session, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import StringField,SubmitField
from wtforms.validators import DataRequired
app = Flask(__name__)
app.config['SECRET_KEY'] = 'kmykey'
class SimpleForm(FlaskForm):
username = StringField("Username:", validators=[DataRequired()])
password = StringField("Password:", validators=[DataRequired()])
submit = SubmitField("Submit")
#app.route('/', methods = ['GET', 'POST'])
def index():
form = SimpleForm()
if form.validate_on_submit():
session['username'] = form.username.data
session['password'] = form.password.data
return redirect(url_for('index'))
return render_template('Login_Page1.html', form=form)
if __name__ == '__main__':
app.run()
The html file:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Ticket Booking</title>
<link rel="stylesheet" type= "text/css" href=" {{ url_for('static',filename='Login_Page1.css') }}">
<link href="https://fonts.googleapis.com/css2?family=Anton&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<!-- JS, Popper.js, and jQuery -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</head>
<body>
<div align="center" class="main1">
<form method="POST">
<h1>Railway Booking Portal</h1>
<h2>Welcome!</h2>
<br>
{# This hidden_tag is a CSRF security feature. #}
{{ form.hidden_tag() }}
{{ form.username.label, extra_classes='uname1' }} {{ form.username(placeholder='email here') }}
<br>
{{ form.password.label, extra_classes='passwd1' }} {{ form.password}}
<br>
<a class="abc" href="Sign_Up.html"><u>SignUp</u></a>
<br>
<a class="abc1" href="Password_Reset.html"><u>ForgotPassword</u></a>
<br>
<br>
{{ form.submit() }}
<br>
<p>"One's destination is never a place, but a new way of seeing things." - Henry Miller</p>
</form>
</div>
The css file:
body{
background: url(railway-tracks.jpeg);
background-repeat: no-repeat;
}
h1{
color: black;
}
p{
font-family: 'Anton', sans-serif;
font-size: 200%;
color: black;
}
.uname1{
display: inline-block;
min-width: 90px;
color: red;
}
.passwd1{
display: inline-block;
min-width: 90px;
color: red;
}
.main1{
background-color: rgba(255, 255, 255, 0.6);
}
.abc{
color: black;
}
.abc1{
color: black;
}
Kindly guide, what is the part that I've done wrong.
I also tried inject the wtf form's attributes to html via (also used class instead of class_):
{{ form.username.label(class_='uname') }} {{ form.username(placeholder='email here') }}
{{ form.password.label(class_='passwd') }} {{ form.password}}
Although didn't receive an error, and successfully flask app ran and the page was shown with all relevant syling/formatting, but the labels weren't formatted.

You can see the answer here
Updated for WTForms 2.1
You can now as of WTForms 2.1 (December 2015) set rendering keywords by using the render_kw= parameter to the field constructor.
So the field would look like:
abc = StringField('abc', [InputRequired()], render_kw={"placeholder": "test"})
(Old answer, still true for versions older than WTForms 2.1)
placeholder is not supported in the Python constructor in WTforms 2.0.x and below.
However, you can do this easily in your template:
{{ form.abc(placeholder="test") }}

You can see the answer here
Change code, i use pycharm and see that
{{ form.username.label(extra_classes='uname1') }} {{ form.username(placeholder='email here') }}
<br>
{{ form.password.label(extra_classes='passwd1') }} {{ form.password}}
Updated for WTForms 2.1
You can now as of WTForms 2.1 (December 2015) set rendering keywords by using the render_kw= parameter to the field constructor.
So the field would look like:
abc = StringField('abc', [InputRequired()], render_kw={"placeholder": "test"})
(Old answer, still true for versions older than WTForms 2.1)
placeholder is not supported in the Python constructor in WTforms 2.0.x and below.
However, you can do this easily in your template:
{{ form.abc(placeholder="test") }}

Related

Flask: How can I send a text from python to a HTML textArea

I just started learning how to use flask in python and I'm doing a little practice to get information from my frontend , analyze it and then send the result back to the frontend in a TxtArea. I'm able to get the information from the first txtArea and analyze it, but I'm not sure of how to send the analysis output back to the frontend.
Basically I should be showing 'Hello world' in the right txtArea as a result of the input of the left txtArea.
Here is my code.
#app.route('/analisis',methods=["POST","GET"])
def analisis():
if request.method=="POST":
content=request.form["text1"]
result=analysis(content)
return redirect(url_for("analisis"))
else:
return render_template('analisis.html')```
And this is what I got for the html file:
<!DOCTYPE html>
<html>
<head>
<style>
textarea {
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<form action="#" method="post">
<h1>Input</h1>
<p><input type="submit" value="Analizar"/></p>
<textarea id="txt1" name="text1" rows="4" cols="50">
</textarea>
<textarea id="txt2" name="text2" rows="4" cols="50">
</textarea>
</form>
</body>
</html>
Any ideas?
You need to pass your data from the textarea, process it and return both values to the html
below is a sample route
#app.route('/sample', methods=["POST", "GET"])
def sample():
if request.method == 'POST':
sample_input = request.form.get('text1')
sample_output = sample_input + ' -> Processed'
return render_template('index.html', sample_input=sample_input, sample_output=sample_output)
elif request.method == 'GET':
return render_template('index.html')
sample html template
<!DOCTYPE html>
<html>
<head>
<style>
textarea {
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<form action="/sample" method="post">
<h1>Input</h1>
<p><input type="submit" value="Analizar"/></p>
<textarea id="txt1" name="text1" rows="4" cols="50">
{{ sample_input }}
</textarea>
<textarea id="txt2" name="text2" rows="4" cols="50">
{{ sample_output }}
</textarea>
</form>
</body>
</html>
When there is a POST requst, it will update the textarea with the appropriate values, when it is a GET request, it will give a blank textarea
content=request.form["text1"]
result=analysis(content) #I assume you have a function that analyzes this parameter
url_for('remove', variable=result)
and then in HTML
{{ variable }}

Flask & jQuery: Image-picker doesn't show the pictures

1. Background:
I am new to Flask, JavaScript or web development. I am currently trying to build an interface for a project of mine, which does extract the linear area of a curve. So far so good, my python code works: It reads data from an .csv or .xlsx file and returns the area, it's slope and plots for each sample. Now I am desperately trying to put them in some kind of user interface, so you can decide which ones to plot. I recognized image-picker (github.com/rvera/image-picker) as a suitable tool for the job, so I decided to implement it into my project. For this I started to build a simple test-page with the image-picker.
2. Problem
Unfortunately, I wasn't able to achieve this. Instead of seeing a list of the image names followed by the pictures, I can only get the list. I will add screenshots of the outcomes.
3. My Code
The project structure
Both, image-picker.css and image-picker.js are taken from the image-picker github
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{{ url_for('static', filename = 'css/main.css') }}">
{% block head %} {% endblock %}
</head>
<body>
{% block body %} {% endblock %}
</body>
</html>
img_picker.html
{% extends 'base.html' %}
{% block head %}<title>Image Picker</title> {% endblock %}
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='image-picker.css') }}">
<script src="{{ url_for('static', filename='image-picker.js') }}" type="text/javascript"></script>
{% block body %}
<select multiple="multiple" class="image-picker show-html">
<option data-img-src='http://placekitten.com/220/200' value='1'>Cute Kitten 1</option>
<option data-img-src='http://placekitten.com/180/200' value='2'>Cute Kitten 2</option>
<option data-img-src='http://placekitten.com/130/200' value='3'>Cute Kitten 3</option>
<option data-img-src='http://placekitten.com/270/200' value='4'>Cute Kitten 4</option>
</select>
<script> $('.image-picker').imagepicker();
</script>
{% endblock %}
app.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template('img_picker.html')
if __name__ == '__main__':
app.run()
main.css
body{
margin: 0;
font-family: sans-serif;
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
How it looks
How it should look
(The website I took the example from: https://rvera.github.io/image-picker/)
If you need any more information, I will be glad to provide it. There has been another question regarding this problem before, but it wasn't solved.
Thanks for any help,
Carroll

Unable to add a task to todo list

When I try to add a new task on my website I get the message "POST /templates/todo" Error (404): "Not found" and cannot find what is wrong with the code. Can anyone help me figure it out? It was done on cs50ide software. If anyone could inform me whether I am able to create a functioning link for my website (I use python, flask, html and css) I would be very grateful! Thank you so much
add.html code:
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/css/styles.css" rel="stylesheet">
<title>
Add a New Task :)
</title>
</head>
<body>
<h1 class = "aligncenter">
<img class = "img1" src = "/static/images/logocarol.jpg" alt = "Logo" height = "200" width = "550"/>
</h1>
<h1 class="centergeneral fontsize">
Add any goals, dreams and aspirations you might have here:
</h1>
<form class="aligncenter" action="todo" method="POST">
<input id="task" name="task" type="text" placeholder="New Task :)">
<input id="submit" type="submit" disabled>
</form>
<script>
document.querySelector('#task').onkeyup = function(){
if (document.querySelector('#task').value === ''){
document.querySelector('#submit').disabled = true;
} else {
document.querySelector('#submit').disabled = false;
}
}
</script>
<form action="/">
<button type="submit" id = "back" class="btn btn-info margin"> BACK TO HOMEPAGE </button> <br> <br>
</form>
<form action="todo">
<button type="submit" id = "back" class="btn btn-outline-info margin"> BACK TO TO DO LIST </button> <br> <br>
</form>
</body>
todo.html code:
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/css/styles.css" rel="stylesheet">
<title>
To Do List! :)
</title>
</head>
<body>
<h1 class = "aligncenter">
<img class = "img1" src = "/static/images/logocarol.jpg" alt = "Logo" height = "200" width = "550"/>
</h1>
<h1 class="fonts centergeneral"> To Do List </h1>
<h2 class="fs-4 centergeneral"> What I Want to Achieve: </h2> <br>
<ul class="listcenter">
<script>
{%for todo in todos%}
<li> {{ todo }} <input type="checkbox" id="checkbox1"> </li>
{%endfor%}
</script>
</ul>
<a class="btn btn-outline-info margin" href = "add"> Add a New Task</a>
<a class="btn btn-outline-info" href = "clear"> Clear Tasks </a> <br>
<div class="backbuttons">
<form action="/">
<button type="submit" id = "back" class="btn btn-info"> BACK TO HOMEPAGE </button> <br> <br>
</form>
</div>
application.py code:
from flask import Flask, render_template, send_from_directory, request, redirect, session
from flask_session import Session
from cs50 import SQL
app = Flask(__name__)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/f1inschools')
def f1():
return render_template('f1inschools.html')
#app.route('/pdwt')
def pdwt():
return render_template('pdwt.html')
#app.route('/pros')
def pros():
return render_template('pros.html')
#app.route('/bookrecommendations')
def books():
return render_template('bookrecs.html')
#app.route('/todolist')
def todo():
if "todos" not in session:
session["todos"] = []
return render_template('todo.html', todos=session["todos"])
#app.route('/clear')
def clear():
return redirect("/todolist")
session["todos"] = []
#app.route('/add', methods=["GET", "POST"])
def add():
if request.method == "GET":
return render_template("add.html")
else:
todo = request.form.get("task")
session["todos"].append(todo)
return redirect("/todolist")
The function for adding tasks is at app.route("/add",methods=["GET","POST"]), but your form in the HTML has action="todo", so your form tries to send data to /todo which is nonexistent. To fix, simply change action="todo" to action="add".

CSS isn't linking from my Python/Flask application

Can't seem to get my style sheet to link, can someone please tell me why?
I'm trying to set up an sample instance with a database, ran on Flask.
I thought it was my folder location, but I've double checked it is on the right place and can't figure out why, spent hours trying to fix it.
My HTML:
{% extends "layout.html" %}
{% block title %}
CS50_Web_Project1
{% endblock %}
{% block body %}
<h1>Login to CS50_Web_Project1</h1>
<form action="{{ url_for('register') }}" method="POST">
<button>Register</button>
</form>
{% endblock %}
My layout.html:
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous">
<!-- #olaf: own link to own style sheet-->
<link rel="stylesheet" href="css/style.css" type="text/css" >
<!-- #olaf: copied from https://bootsnipp.com/snippets/GaEOX-->
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
{% block body %}
{% endblock %}
</div>
</body>
</html>
My CSS in css/style.css location:
/* style.css */
.note
{
text-align: center;
height: 80px;
background: -webkit-linear-gradient(left, #0072ff, #8811c5);
color: #fff;
font-weight: bold;
line-height: 80px;
}
.form-content
{
padding: 5%;
border: 1px solid #ced4da;
margin-bottom: 2%;
}
.form-control{
border-radius:1.5rem;
}
.btnSubmit
{
border:none;
border-radius:1.5rem;
padding: 1%;
width: 20%;
cursor: pointer;
background: #0062cc;
color: #fff;
}
My application.py:
import os
from flask import Flask, session, render_template, jsonify, request
from flask_session import Session
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
app = Flask(__name__)
#from the internet...# app.config['DATABASE_URL'] = "path_to_db"
# Check for environment variable
if not "DATABASE_URL":
raise RuntimeError("DATABASE_URL is not set")
# Configure session to use filesystem
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Set up database
engine = create_engine("DATABASE_URL")
db = scoped_session(sessionmaker(bind=engine))
#olaf: create a login page that has a form, containing "login" & "register" button
#app.route("/")
def index():
return render_template("index.html")
#olaf: Login button
#app.route("/register", methods=["POST"])
def register():
"""Register for the site"""
return render_template("registerSuccess.html")
To provide CSS file in your Flask template you need to use a specific method for that in your HTML template {{ url_for(STATIC_DIR_NAME, filename=PATH_TO_FILE_IN_STATIC_DIR)}}.
In your layout.html
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous">
<!-- #olaf: own link to own style sheet-->
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" type="text/css" >
<!-- #olaf: copied from https://bootsnipp.com/snippets/GaEOX-->
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
{% block body %}
{% endblock %}
</div>
</body>
</html>
Also, if you follow the official documentation tips on the layout should do it.
But if you have a custom project setup then you might need to provide to your app where a static folder is.
For example in your application.py
import os
from flask import Flask, session, render_template, jsonify, request
from flask_session import Session
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_DIR = os.path.join(THIS_DIR, 'specific_path_to_static', 'static')
app = Flask(__name__, static_url_path=STATIC_DIR)
#from the internet...# app.config['DATABASE_URL'] = "path_to_db"
# Check for environment variable
if not "DATABASE_URL":
raise RuntimeError("DATABASE_URL is not set")
# Configure session to use filesystem
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Set up database
engine = create_engine("DATABASE_URL")
db = scoped_session(sessionmaker(bind=engine))
#olaf: create a login page that has a form, containing "login" & "register" button
#app.route("/")
def index():
return render_template("index.html")
#olaf: Login button
#app.route("/register", methods=["POST"])
def register():
"""Register for the site"""
return render_template("registerSuccess.html")
Then the flask template should find the style.css file provided in layout.html file.
The first solution i can propose is that you download the bootstrap files and have them on your local working directory, then make a folder to contain static files and try the following code
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">

Loading URLs into an iFrame using Flask

I'm new to Flask and
I'm trying to create a Stumbleupon like website but I'm having problems while loading the content into an iFrame. I just cant figure it out how to iterate through each url and load them into the iFrame while clicking in the <a> tag.
Here is what I've done:
app.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def index():
urls = [
'http://www.w3schools.com',
'http://techcrunch.com/',
'https://www.fayerwayer.com/',
]
return render_template('index.html', urls=urls)
if __name__ == "__main__":
app.run(debug=True)
templates/layout.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="/static/css/normalize.css"/>
<link rel="stylesheet" type="text/css" href="/static/css/foundation.css"/>
</head>
<body>
<nav class="top-bar">
<h3 align="center">Stumble</h3>
</nav>
{% block content %}
{% endblock content %}
</body>
</html>
templates/index.html
{% extends 'layout.html' %}
{% block content %}
<iframe frameborder='0' noresize='noresize' style='position: absolute; background: transparent; width: 100%; height:100%;' src="????????" frameborder="0"></iframe>
{% endblock content %}
After adding import random at the top of your app.py file you could structure your code like this:
def index():
urls = [
'http://www.w3schools.com',
'http://techcrunch.com/',
'https://www.fayerwayer.com/',
]
iframe = random.choice(urls)
return render_template('index.html', iframe=iframe)
Then access the value in your template:
<iframe frameborder='0' noresize='noresize' style='position: absolute; background: transparent; width: 100%; height:100%;' src="{{ iframe }}" frameborder="0"></iframe>
And simply set the Stumble button to refresh the page.
<h3 align="center">Stumble</h3>
This will be pretty basic, but it will have the behaviour you're describing.
An improvement will be to use the session object to make sure that two subsequent requests do not display the same page inside the iframe.

Categories