wagtail-django-recaptcha icon indicating copy to clipboard operation
wagtail-django-recaptcha copied to clipboard

How to change the language of the recaptcha?

Open Ratatam123 opened this issue 6 years ago • 7 comments

Hello,

is there a simple way to change the language of the recaptcha? (My case: My contactform-model so far simply inherits from WagtailCaptchaEmailForm)

Ratatam123 avatar Nov 15 '19 09:11 Ratatam123

Hello @loicteixeira and @benoitvogel is there a way to fix issue? I want to force the language of the recaptcha widget to be equal to my {{ request.LANGUAGE_CODE }}. Will it work if I override the https://github.com/praekelt/django-recaptcha/blob/develop/captcha/templates/captcha/includes/js_v2_checkbox.html file so as to just pass the correct lang parameter to /recaptcha/api.js ?

spapas avatar Feb 17 '20 17:02 spapas

Since the original authors are unresponsive I'll provide a hacky solution ; I couldn't make this work otherwise:

First of all, copy the files templates/captcha/widget_v2_checkbox.html and templates/captcha/includes/js_v2_checkbox.html from django-recaptcha to the templates directory of one of your apps. You can then remove the captcha app from your settings APPLICATIONS list.

Now, you should properly override the js_v2_checkbox.html template so as to include the hl={{ LANGUAGE_CODE }} parameter. The problem is that for whatever reason the your context processors aren't working there so {{ LANGUAGE_CODE }} is empty!

To resolve that, I'm adding the following in my form_page before rendering the form:

<script>
    window.g_lang = '{{ LANGUAGE_CODE }}';
</script>

then, in the js_v2_checkbox.html I'll do some dynamic-js-loading trickery to properly include the file. Here's my js_v2_checkbox.html:

{# The provided implementation caters for only one reCAPTCHA on a page. Override this template and its logic as needed. #}

<script>
    var url = 'https://{{ recaptcha_domain }}/recaptcha/api.js?hl='+window.g_lang;
    var script = document.createElement("script");  // create a script DOM node
    script.src = url;  // set its src to the provided URL

    document.head.appendChild(script);
</script>
{% comment %}
<script src="https://{{ recaptcha_domain }}/recaptcha/api.js{% if api_params %}?{{ api_params }}{% endif %}" + window.g_lang></script>
{% endcomment %}
<script type="text/javascript">
    // Submit function to be called, after reCAPTCHA was successful.
    var onSubmit_{{ widget_uuid }} = function(token) {
        console.log("reCAPTCHA validated for 'data-widget-uuid=\"{{ widget_uuid }}\"'")
    };
</script>

This works fine and when I change the language it will display the proper messages from google. Notice that I don't pass the {{ api_params }} because they are empty anyway.

spapas avatar Feb 18 '20 09:02 spapas

Sorry for the late reply, I do not work at Springload anymore and therefore I wasn't paying much attention to this repository.

While I cannot guarantee it would be merged, I'd advise you to propose a pull request so it can be fixed on the package directly.

loicteixeira avatar Feb 26 '20 17:02 loicteixeira

@spapas Great, thank you!

Ratatam123 avatar Feb 27 '20 08:02 Ratatam123

@Ratatam123 you're welcome!

@loicteixeira no problem! I don't like to create a PR for these changes because they are hacky; I think the correct way to implement that is to somehow allow defining the api_params dict that will be passed to the ReCaptchaV2Checkbox as described in the django-recaptcha docs. I'm not really sure what's the best way to implement this and it's not easy for me to research it right now because of too little time.

However I guess the hacky solution could be used for now by any people that need this functionality until it's impmented properly!

spapas avatar Feb 27 '20 14:02 spapas

I had this same issue and solved it in the following way.

If you have a class for the form that inherits from WagtailCaptchaEmailForm eg

class FormPage(WagtailCaptchaEmailForm):
    pass

Then firstly create a custom formbuilder which inherits from WagtailCaptchaFormBuilder, and override the formfields method.

(this is reimplementing this method https://github.com/springload/wagtail-django-recaptcha/blob/da39697d16499658f2ef954bfb98baae34df119b/wagtailcaptcha/forms.py#L16 but we are setting api_params from https://github.com/praekelt/django-recaptcha/blob/97467c22f2d64025184b79f9714ad2f5002164f0/captcha/widgets.py#L25 which is then used in get_context to the template)

class TranslationWagtailCaptchaFormBuilder(WagtailCaptchaFormBuilder):
    @property
    def formfields(self):
        fields = super(WagtailCaptchaFormBuilder, self).formfields

        field = ReCaptchaField(label='')
        field.widget.api_params["hl"] = translation.get_language()
        fields[self.CAPTCHA_FIELD_NAME] = field

        return fields

Then in your original form simply override the form builder.

class FormPage(WagtailCaptchaEmailForm):
    form_builder = TranslationWagtailCaptchaFormBuilder

There may be a better way of doing this, but this didn't seem overly hacky :-)

ahayzen avatar Jul 27 '20 19:07 ahayzen

Old issue, but you can supply the language code to the api_params keyword in the django_recaptcha widget.

Eg:

fields[self.CAPTCHA_FIELD_NAME] = ReCaptchaField(
    widget=ReCaptchaV3(api_params={'hl': Locale.get_active().language_code})
)

I've raised a suggestion (#54) to improve the flexibility and make widget config a lot easier. I'll make a PR if there's interest.

enzedonline avatar Nov 20 '23 01:11 enzedonline