helloflask / helloflask/bootstrap-flask

Consider adding special treatment for Recaptcha field used by Flask-WTF

Open
#408 2 comments 1 reaction 0 assignees View on GitHub
bug form
Dominant language
SCSS
Stars
1.2k
Forks
193
Avg merge
4m
Merged PRs (30d)
3

Description

First of all, I'm not sure if this issue should be addressed in Flask-WTF or Bootstrap-Flask so I opened the issue for both projects. Here is the Flask-WTF side issue: https://github.com/pallets-eco/flask-wtf/issues/695

Not so long ago, this commit has been added to Flask-WTF: https://github.com/pallets-eco/flask-wtf/commit/adf674f80c5c5e55c050729e3ec086b4d6cb0f26

What it does is basically if a `class` is present at widget rendering, then it ignores the `RECAPTCHA_DIV_CLASS` config (or even the default value). This config used to be the way to define the class which the h-captcha and re-captcha scripts are looking for when they inject their iframes.

Bootstrap-Flask seem to treat captcha fields as regular fields, this it adds the `form-control` class to it. (see.: https://github.com/helloflask/bootstrap-flask/blob/15d29fdb5783fe4226008f8288ed9767e6a3d0c8/flask_bootstrap/templates/bootstrap5/form.html#L236-L242). This causes the class required by captcha above not to be added.

Since the class is not present, h-captcha does not work.

Now one way to "fix" this is to add `class="h-captcha"` to all templates, but that's not always possible, especially when templates are coming from a third party library. Also I don't think that's very elegant either, having to put functionality related code to templates.

How Bootstrap-Flask could fix the situation: Add special handling to fields with the type of `RecaptchaField` (as it is already done for other types like `SelectField`, `DecimalRangeField`, etc.) and does not pass any `class=` to it. This would allow the re-captcha field to use the configured value. And also not having form-control on the captcha field, removes the ugly border around it. (That wasn't present when the config would override all classes before)

## Reproduce

repro.py:
```python
from flask import Flask, render_template
from flask_bootstrap import Bootstrap5
from flask_wtf import RecaptchaField, FlaskForm

class CaptchaForm(FlaskForm):
captcha = RecaptchaField()

app = Flask(__name__)

app.config['SECRET_KEY'] = 'hunter2'
app.config['RECAPTCHA_PUBLIC_KEY'] = '00000000-0000-0000-0000-000000000000'
app.config['RECAPTCHA_PRIVATE_KEY'] = 'ES_000000000000000000000000000000000'
app.config['RECAPTCHA_DIV_CLASS'] = 'h-captcha'
app.config['RECAPTCHA_SCRIPT'] = "https://js.hcaptcha.com/1/api.js"
app.config['RECAPTCHA_VERIFY_SERVER'] = "https://api.hcaptcha.com/siteverify"

Bootstrap5(app)

@app.route("/")
def captcha():
form = CaptchaForm()
return render_template("repro.html.j2", form=form)

app.run(debug=True)
```

templates/repro.html.j2
```jinja2
{% from 'bootstrap5/form.html' import render_form %}


{{ bootstrap.load_css() }}

{{ render_form(form) }}
{{ bootstrap.load_js() }}

```

Result:
```html






```

As you can see, the `class="h-captcha"` is not added to the div.

Environment:

- Python version: 3.14
- Flask-WTF version: 1.3.0
- Flask version: 3.1.3
- Bootstrap-Flask version: 2.5.0

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in flask_bootstrap/templates/bootstrap5/form.html around lines 236-242, and compare its handling of SelectField and DecimalRangeField with Flask-WTF's RecaptchaField behavior. Use repro.py and templates/repro.html.j2 to verify that the captcha div keeps the configured h-captcha class and no longer receives form-control.

Written by the indexing model from the issue text.

Assessment

Tech stack
bootstrap, flask, python
Domain
frontend, web-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.