-1

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.

Ed Eddy
  • 11
  • 3

2 Answers2

0

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") }}
  • Hi Linh, thanks for the comment. I don't think this error is caused by the placeholder. Even if I simply remove the placeholder part, the error remains as it is. The core issue is why the labels cannot be formatted? What is the loophole that is overseen by me in the code shared above? Waiting for your kind response. – Ed Eddy Sep 11 '20 at 04:35
  • Change: {{ form.username.label(extra_classes='uname1') }} {{ form.username(placeholder='email here') }}
    {{ form.password.label(extra_classes='passwd1') }} {{ form.password}}
    – Linh Nguyễn Ngọc Sep 11 '20 at 05:04
  • Linh, what needs to be changed in place of those two lines of code where I'm trying to inject jinja templating to the HTML? Can you give me the code which ensures username & password labels are formatted corresponding to the mentioned class names? The link shared by you specifically mentioned about placeholders, and my code has no importance for placeholders. We can simply exclude the placeholder part in my code. The problem is getting the labels formatted, kindly guide what needs to be written/included in HTML. Thanks – Ed Eddy Sep 11 '20 at 05:35
  • {{ form.username.label(extra_classes='uname1') }} {{ form.username() }}
    {{ form.password.label(extra_classes='passwd1') }} {{ form.password}} Even if I remove placeholder part, formatting of username & password labels aren't being done. What am I missing in here? Looking for your kind response. Than you
    – Ed Eddy Sep 11 '20 at 05:37
  • jinja2.exceptions.TemplateSyntaxError: expected token 'end of print statement', got '=' Because your code: {{ form.username.label, extra_classes='uname1' }}. It dont have (), you should change to {{ form.username.label(extra_classes='uname1') }}. Try to do that and let me know result – Linh Nguyễn Ngọc Sep 11 '20 at 05:39
  • Hi Linh, as instructed I did the modification. Although I no longer see the jinja2 exception, still the labels aren't formatted yet. Neither their color changed not their alignment as they should as per css file. – Ed Eddy Sep 11 '20 at 05:45
  • I've also tried to use the following, but these didn't work either: { form.username.label(class='uname1') }} {{ form.username(placeholder='email here') }}
    {{ form.password.label(class='passwd1') }} {{ form.password}} { form.username.label(class_='uname1') }} {{ form.username(placeholder='email here') }}
    {{ form.password.label(class_='passwd1') }} {{ form.password}}
    – Ed Eddy Sep 11 '20 at 05:46
  • I dont know why, i have the same code, it worked well {{ form.service_price.label(class_ = 'h4 border-bottom') }} {{ form.service_price(class_="next-input") }}. In Form: service_price = StringField('Price', [DataRequired()]) – Linh Nguyễn Ngọc Sep 11 '20 at 05:52
  • class_ ='"adasfsafsafd" .not class="adfafasfasfafsdfadsf" – Linh Nguyễn Ngọc Sep 11 '20 at 05:54
  • i think you should use the bootstrap. It is so easy. And for css, you have to put in the code like that – Linh Nguyễn Ngọc Sep 11 '20 at 05:57
  • Linh, I tried both class_= and class= apart from trying extra_classes= in brackets. Did you mean to say that code that I have pasted in the question works for you? – Ed Eddy Sep 11 '20 at 05:59
  • I'm using the bootstrap as well, kindly see the css file I've posted. It's like I'm stuck at formatting the jinja templates. – Ed Eddy Sep 11 '20 at 06:00
  • check dot dot, href="../static/css.css", it have two dots. Your code href=" {{ url_for('static',filename='Login_Page1.css') }}"> change to ../static/Login_Page1.css – Linh Nguyễn Ngọc Sep 11 '20 at 06:08
  • The static folder is in same folder where main .py file is, that's why I didn't use two dots. When it comes to connecting the HTML with css, that is not the problem. The background image and other things are successfully getting styled/formatted. It's the jinja2 templates that I'm having a hard time with. – Ed Eddy Sep 11 '20 at 06:26
  • I just tried to include two dots in css as per your instruction, but received an exception when I tried to run the flask app. – Ed Eddy Sep 11 '20 at 06:28
  • so mayby for you css file :D Check it. For you question about the jinja2-exceptions, it is fixed, right? https://stackoverflow.com/questions/16351826/link-to-flask-static-files-with-url-for – Linh Nguyễn Ngọc Sep 11 '20 at 06:32
  • Linh, the motive/agenda is to stylize the labels. I was using a variety of templating keywords (extra_classes=, class=, class_=) as mentioned in my original question, but nothing worked out. I'm desperately looking for a way to stylize the labels. Thanks – Ed Eddy Sep 11 '20 at 06:41
  • In my project, I do {{ form.another.label(class_ = 'h4 border-bottom') }}, it is work so well. Please check it carefully. Maby you try to download an example css file, and try it. Maybe problem belong to you css file. – Linh Nguyễn Ngọc Sep 11 '20 at 06:43
  • Okay, I'll scan thru it and probably create another css. Thanks very much for your valuable help, appreciate it. Take care. – Ed Eddy Sep 11 '20 at 06:53
0

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") }}