Jürgen Gmach
Jürgen Gmach

Reputation: 6121

Is it possible to style a part of a label in Flask-WTForms?

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.

Upvotes: 2

Views: 3178

Answers (4)

Omnilord
Omnilord

Reputation: 884

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

Upvotes: 0

J&#252;rgen Gmach
J&#252;rgen Gmach

Reputation: 6121

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.

Upvotes: 4

Victor
Victor

Reputation: 612

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

Upvotes: 1

GAEfan
GAEfan

Reputation: 11360

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

Upvotes: 1

Related Questions