2

I generate a form via Flask-WTF.

The relevant checkbox looks like this:

    conditions = BooleanField(
        "I agree to the above conditions.", validators=[DataRequired()])

I'd like to have the I agree bold or strong - NOT the rest of the sentence.

I cannot pass in HTML tags, as they get escaped and rendered as text.

This would look like this:

[] <strong>I agree</strong> to the above conditions.

I'd like to get this result:

I agree to the above conditions.

Is this possible?

Thanks for any hints.

Jürgen Gmach
  • 5,366
  • 3
  • 20
  • 37

4 Answers4

3

Thanks to the other answer by @gaefan, I read more about Jinja templating and the safe filter and came up with a another working solution.

from flask import Markup

label_for_conditions = Markup('<span class="customClass">I agree</span> to the above conditions.')
conditions = BooleanField(label_for_conditions, validators=[DataRequired()])

This solution does not need even a safe filter in the template.

This answer is inspired by the following discussion:

Passing HTML to template using Flask/Jinja2

It is not a perfect solution, as now HTML and Python is mixed in the form definition, but it looks like you have to make a compromise.

Jürgen Gmach
  • 5,366
  • 3
  • 20
  • 37
1

A simple solution would be to just do it in the template. Instead of:

{{ user_form.conditions.errors }}{{ user_form.conditions.label_tag }}<br />{{ user_form.conditions }}

do:

{{ user_form.conditions.errors }}<strong>I agree</strong> to the above conditions.<br />{{ user_form.conditions }}

I haven't tested this, but you may be able to do:

conditions = BooleanField(
    "<strong>I agree</strong> to the above conditions.", validators=[DataRequired()])

and then, in the template:

{{ user_form.conditions.errors }}{{ user_form.conditions.label_tag|safe }}<br />{{ user_form.conditions }}
GAEfan
  • 11,244
  • 2
  • 17
  • 33
  • While your second answer still escapes the html tags, and thus prints them as text, your first answer is as simple as brilliant. Your second answer was not in vain. I read more about `safe` and Jinja templating and came up with another working answer, which I will post in a minute. Thanks a lot! – Jürgen Gmach Aug 07 '20 at 06:08
1

There are two solutions:

  • When creating the Field using render_kw.
  • When rendering the Field in the template (when the field is being called [form.field()]).

Initialize Field with style:

All the Field objects in WTForms have a render_kw arg in __init__.

render_kw (dict) – If provided, a dictionary which provides default keywords that will be given to the widget at render time.

When your template is being rendered, Jinja2 is going to read this render_kw. In your case, you can define:

conditions = BooleanField(
    "I agree to the above conditions.", validators=[DataRequired()],
    render_kw={"style": "font-weight: bold;")

Rendering while templating

When Jinja2 is rendering, you can specify other rendering options by calling the field.

form.field()

__call__(**kwargs): Render this field as HTML, using keyword args as additional attributes.

[...]

In all of the WTForms HTML widgets, keyword arguments are turned to HTML attributes, though in theory a widget is free to do anything it wants with the supplied keyword arguments, and widgets don’t have to even do anything related to HTML.

So in your template file, you can do something like that:

{{ form.field(style="font-weight: bold;") }}

Note that there is an exception for the class keyword, probably reserved by something else, then the key should be class_.


Source: Fields - WTForms Documencation

Victor
  • 602
  • 4
  • 12
  • Thank you very much for your extensive answer, even with an alternate proposal. Unfortunately, this does not answer my question. I am super sorry that I have not made my question more explicit - I only need to style a part of the label - not the complete label. Both your solutions apply only to the complete label. – Jürgen Gmach Aug 07 '20 at 06:01
  • Exactly, I did not notice that you wanted only a part of the label. Nevermind, my answer will probably be useful for you later. – Victor Aug 07 '20 at 06:14
  • 1
    While I knew about adding attributes within the template, I did not know that you can already initialize a field with `render_kw`! So, I learned something new! Thanks! – Jürgen Gmach Aug 07 '20 at 06:19
0

I'm using WTForm 2.3.3 on Flask 1.1.2 and I ended up using the following since piping the label itself, the label_tag, etc. to safe were not working for me but this does:

{{ field.label.text|safe }}
Omnilord
  • 844
  • 2
  • 16
  • 23