Skip to content

Commit 7d0457e

Browse files
committed
- documentation updated
- use of a more generic name for the "invisible" widget
1 parent d6f8201 commit 7d0457e

File tree

4 files changed

+145
-23
lines changed

4 files changed

+145
-23
lines changed

README.md

+141-19
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
----
33

44
This integration app implements a recaptcha field for <a href="https://developers.google.com/recaptcha/intro">Google reCaptcha v2</a>
5-
with explicit rendering and multiple recaptcha support.
5+
with explicit rendering and multiple recaptcha support. The invisible version of the reCAPTCHA with the automatic render mode
6+
is now supported, please read the related documentation below.
67

78
----
89

@@ -33,7 +34,7 @@ RECAPTCHA_PUBLIC_KEY = 'your public key'
3334

3435
If you have to create the apikey for the domains managed by your django project, you can visit this <a href="https://www.google.com/recaptcha/admin">website</a>.
3536

36-
## Usage
37+
## "I'm not a robot" Usage
3738
### Form and Widget
3839
You can simply create a reCaptcha enabled form with the field provided by this app:
3940

@@ -47,7 +48,8 @@ class ExampleForm(forms.Form):
4748
[...]
4849
```
4950

50-
You can pass some parameters into the widget contructor:
51+
You can set the private key on the "private_key" argument of the field contructor and you can pass some
52+
parameters into the widget contructor:
5153

5254
```python
5355
class ReCaptchaWidget(Widget):
@@ -110,19 +112,8 @@ or
110112

111113
For language codes take a look to <a href="https://developers.google.com/recaptcha/docs/language">this page</a>.
112114

113-
### Test unit support
114-
You can't simulate api calls in your test, but you can disable the recaptcha field and let your test works.
115-
116-
Just set the RECAPTCHA_DISABLE env variable in your test:
117-
118-
```python
119-
os.environ['RECAPTCHA_DISABLE'] = 'True'
120-
```
121-
122-
Warning: you can use any word in place of "True", the clean function will check only if the variable exists.
123-
124-
## Samples
125-
### Simple render example
115+
### Samples
116+
#### Simple render example
126117

127118
Just create a form with the reCaptcha field and follow this template example:
128119

@@ -142,7 +133,7 @@ Just create a form with the reCaptcha field and follow this template example:
142133
</html>
143134
```
144135

145-
### Explicit render example
136+
#### Explicit render example
146137

147138
Create a form with explicit=True and write your template like this:
148139

@@ -163,7 +154,7 @@ Create a form with explicit=True and write your template like this:
163154
</html>
164155
```
165156

166-
### Multiple render example
157+
#### Multiple render example
167158

168159
You can render multiple reCaptcha using only forms with explicit=True:
169160

@@ -189,7 +180,7 @@ You can render multiple reCaptcha using only forms with explicit=True:
189180
</html>
190181
```
191182

192-
### Mix manual render with app support
183+
#### Mix manual render with app support
193184

194185
You can use the app explicit render support also is you implement reCaptcha in one of your form in the template:
195186

@@ -216,6 +207,137 @@ You can use the app explicit render support also is you implement reCaptcha in o
216207
</html>
217208
```
218209

210+
## "Invisible" Usage
211+
The implementation and the usage of this kind of binding is simpler and you don't need to use the explicit
212+
rendering to add multiple instances of the reCAPTCHA.
213+
214+
### Form and Widget
215+
You can simply create a reCaptcha enabled form with the field provided by this app:
216+
217+
```python
218+
from snowpenguin.django.recaptcha2.fields import ReCaptchaField
219+
from snowpenguin.django.recaptcha2.widgets import ReCaptchaHiddenInput
220+
221+
class ExampleForm(forms.Form):
222+
[...]
223+
captcha = ReCaptchaField(widget=ReCaptchaHiddenInput())
224+
[...]
225+
```
226+
227+
You can set the private key on the "private_key" argument of the field contructor.
228+
229+
### Templating
230+
You just need to add the "recaptcha_init" tag on the head of your page and to place the invisible reCAPTCHA
231+
submit button inside your form:
232+
233+
```django
234+
<form id='myform1' action="?" method="POST">
235+
{% csrf_token %}
236+
{{ form }}
237+
{% recaptcha_invisible_button submit_label='Submit' %}
238+
</form>
239+
```
240+
241+
You can customize the button with the parameters included in its definition:
242+
243+
```python
244+
def recaptcha_invisible_button(public_key=None, submit_label=None, extra_css_classes=None,
245+
form_id=None, custom_callback=None):
246+
```
247+
248+
You can override the reCAPTCHA public key, change the label of the button, apply extra css classes, force
249+
the button to submit a form identified by id or provide the name of a custom callback. Please check the samples
250+
to understand how it works.
251+
252+
### Samples
253+
#### Simple usage
254+
255+
```django
256+
{% load recaptcha2 %}
257+
<html>
258+
<head>
259+
{% recaptcha_init %}
260+
</head>
261+
<body>
262+
<form action="?" method="POST">
263+
{% csrf_token %}
264+
{{ form }}
265+
{% recaptcha_invisible_button submit_label='Submit' %}
266+
</form>
267+
</body>
268+
</html>
269+
```
270+
271+
**Note:** The button will looking for the first "form" element using che "Element.closest" function. IE
272+
doesn't support it, so please use a polyfill (for example https://polyfill.io). If you don't want to
273+
add extra javascript libraries, please use the form id or a custom callback.
274+
275+
#### Form id
276+
277+
```django
278+
{% load recaptcha2 %}
279+
<html>
280+
<head>
281+
{% recaptcha_init %}
282+
</head>
283+
<body>
284+
<form id='myform' action="?" method="POST">
285+
{% csrf_token %}
286+
{{ form }}
287+
{% recaptcha_invisible_button submit_label='Submit' form_id='myform' %}
288+
</form>
289+
</body>
290+
</html>
291+
```
292+
293+
#### Custom callback
294+
295+
```django
296+
{% load recaptcha2 %}
297+
<html>
298+
<head>
299+
{% recaptcha_init %}
300+
</head>
301+
<body>
302+
<form id='myform' action="?" method="POST">
303+
{% csrf_token %}
304+
{{ form }}
305+
{% recaptcha_invisible_button submit_label='Submit' custom_callback='mycallback' %}
306+
<script>
307+
function mycallback(token) {
308+
someFunction();
309+
document.getElementById("myform").submit();
310+
}
311+
</script>
312+
</form>
313+
</body>
314+
</html>
315+
```
316+
317+
### TODO/ISSUES
318+
319+
- Only the automatic binding is supported, but you can add the dummy widget inside your form and the required
320+
javascript code in your template in order to use the programmatically bind and invoke.
321+
322+
- You can only configure one reCAPTCHA key in the configuration. This isn't a real problem because if you want
323+
to use the invisible reCAPTCHA you don't need to use the "old one" anymore. If you need to use both implementations you
324+
can still set the public and private keys in the fields, tags and widgets constructors.
325+
326+
- ReCaptchaHiddenInput could be the starting point for the creation of some "I'm not a robot" reCAPTCHA template
327+
tags to use in place of the ReCaptchaWidget (maybe in a future release)
328+
329+
## Testing
330+
### Test unit support
331+
You can't simulate api calls in your test, but you can disable the recaptcha field and let your test works.
332+
333+
Just set the RECAPTCHA_DISABLE env variable in your test:
334+
335+
```python
336+
os.environ['RECAPTCHA_DISABLE'] = 'True'
337+
```
338+
339+
Warning: you can use any word in place of "True", the clean function will check only if the variable exists.
340+
219341
### Test unit with recaptcha2 disabled
220342
```python
221343
import os

samples/invisible_recaptcha.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{% recaptcha_init %}
55
</head>
66
<body>
7-
<form id='myform' action="?" method="POST">
7+
<form id='myform1' action="?" method="POST">
88
{% csrf_token %}
99
{{ form }}
1010
{% recaptcha_invisible_button submit_label='Submit' %}

snowpenguin/django/recaptcha2/tests.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
from django.test import TestCase
55

66
from snowpenguin.django.recaptcha2.fields import ReCaptchaField
7-
from snowpenguin.django.recaptcha2.widgets import ReCaptchaWidget, ReCaptchaInvisibleWidget
7+
from snowpenguin.django.recaptcha2.widgets import ReCaptchaWidget, ReCaptchaHiddenInput
88

99

1010
class RecaptchaTestForm(Form):
1111
recaptcha = ReCaptchaField(widget=ReCaptchaWidget())
1212

1313

1414
class RecaptchaInvisibleTestForm(Form):
15-
recaptcha = ReCaptchaField(widget=ReCaptchaInvisibleWidget())
15+
recaptcha = ReCaptchaField(widget=ReCaptchaHiddenInput())
1616

1717

1818
class TestRecaptchaForm(TestCase):

snowpenguin/django/recaptcha2/widgets.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def value_from_datadict(self, data, files, name):
4848
return [data.get('g-recaptcha-response', None)]
4949

5050

51-
class ReCaptchaInvisibleWidget(Input):
51+
class ReCaptchaHiddenInput(Input):
5252
input_type = 'hidden'
5353

5454
def render(self, name, value, attrs=None, renderer=None):

0 commit comments

Comments
 (0)