helloflask / helloflask/bootstrap-flask
Consider adding special treatment for Recaptcha field used by Flask-WTF
- 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