Skip to content

Commit afa9d65

Browse files
committed
Merge branch 'release/5.2.0'
2 parents 2494cf3 + 75860da commit afa9d65

File tree

12 files changed

+126
-67
lines changed

12 files changed

+126
-67
lines changed

AUTHORS.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Authors
33
=======
44

5+
This application is developed and maintained by `Zostera <https://zostera.nl>`_.
6+
57
Development Lead
68
----------------
79

HISTORY.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@ History
44
-------
55

66

7+
5.2.0 (2015-03-20)
8+
++++++++++++++++++
9+
10+
* Various bug fixes and improvements
11+
12+
13+
5.2.0 (2015-03-25)
14+
++++++++++++++++++
15+
16+
* Upgrade to Bootstrap 3.3.4
17+
* Fix required bug for checkboxes
18+
* Various bug fixes
19+
20+
721
5.1.1 (2015-01-22)
822
++++++++++++++++++
923

README.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,10 @@ You can use this under Apache 2.0. See `LICENSE
8787
Author
8888
------
8989

90-
My name is Dylan Verheul, you can reach me at [email protected] or follow me on Twitter (http://twitter.com/dyve). If you like this project, you can `support me on GitTip <https://www.gittip.com/dyve/>`_.
90+
Developed and maintained by `Zostera <https://zostera.nl/>`_.
91+
92+
Original author & Development lead: `Dylan Verheul <https://github.com/dyve>`_.
93+
94+
Thanks to everybody that has contributed pull requests, ideas, issues, comments and kind words.
95+
96+
Please see AUTHORS.rst for a list of contributors.

bootstrap3/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# -*- coding: utf-8 -*-
22

3-
__version__ = '5.1.1'
3+
__version__ = '5.2.0'

bootstrap3/bootstrap.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
from __future__ import unicode_literals
33

44
from django.conf import settings
5-
from django.utils.importlib import import_module
5+
try:
6+
from django.utils.importlib import import_module
7+
except ImportError:
8+
from importlib import import_module
69

710

811
# Default settings
912
BOOTSTRAP3_DEFAULTS = {
1013
'jquery_url': '//code.jquery.com/jquery.min.js',
11-
'base_url': '//netdna.bootstrapcdn.com/bootstrap/3.3.2/',
14+
'base_url': '//netdna.bootstrapcdn.com/bootstrap/3.3.4/',
1215
'css_url': None,
1316
'theme_url': None,
1417
'javascript_url': None,

bootstrap3/forms.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
from django.contrib.admin.widgets import AdminFileWidget
55
from django.forms import (
6-
HiddenInput, FileInput, CheckboxSelectMultiple, Textarea, TextInput
6+
HiddenInput, FileInput, CheckboxSelectMultiple, Textarea, TextInput,
7+
PasswordInput
78
)
9+
from django.forms.widgets import CheckboxInput
810

911
from .bootstrap import (
1012
get_bootstrap_setting, get_form_renderer, get_field_renderer,
@@ -75,7 +77,7 @@ def render_label(content, label_for=None, label_class=None, label_title=''):
7577

7678
def render_button(
7779
content, button_type=None, icon=None, button_class='', size='',
78-
href=''):
80+
href='', name=None):
7981
"""
8082
Render a button with content
8183
"""
@@ -109,6 +111,8 @@ def render_button(
109111
tag = 'a'
110112
else:
111113
tag = 'button'
114+
if name:
115+
attrs['name'] = name
112116
return render_tag(
113117
tag, attrs=attrs, content=text_concat(
114118
icon_content, content, separator=' '))
@@ -159,7 +163,7 @@ def is_widget_required_attribute(widget):
159163
if isinstance(
160164
widget, (
161165
AdminFileWidget, HiddenInput, FileInput,
162-
CheckboxSelectMultiple)):
166+
CheckboxInput, CheckboxSelectMultiple)):
163167
return False
164168
return True
165169

@@ -170,4 +174,6 @@ def is_widget_with_placeholder(widget):
170174
Only text, search, url, tel, e-mail, password, number have placeholders
171175
These are all derived form TextInput, except for Textarea
172176
"""
173-
return isinstance(widget, (TextInput, Textarea))
177+
# PasswordInput inherits from Input in Django 1.4.
178+
# It was changed to inherit from TextInput in 1.5.
179+
return isinstance(widget, (TextInput, Textarea, PasswordInput))

bootstrap3/renderers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ def render_forms(self):
9090
form_group_class=self.form_group_class,
9191
field_class=self.field_class,
9292
label_class=self.label_class,
93+
show_label=self.show_label,
9394
show_help=self.show_help,
9495
exclude=self.exclude,
9596
set_required=self.set_required,
@@ -144,6 +145,7 @@ def render_fields(self):
144145
form_group_class=self.form_group_class,
145146
field_class=self.field_class,
146147
label_class=self.label_class,
148+
show_label=self.show_label,
147149
show_help=self.show_help,
148150
exclude=self.exclude,
149151
set_required=self.set_required,

bootstrap3/templates.py

Lines changed: 0 additions & 56 deletions
This file was deleted.

bootstrap3/templatetags/bootstrap3.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
render_label, render_form_errors, render_formset_errors
1919
)
2020
from ..components import render_icon, render_alert
21-
from ..templates import handle_var, parse_token_contents
21+
from ..utils import handle_var, parse_token_contents
2222
from ..text import force_text
2323

2424

bootstrap3/tests.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from django.test import TestCase
77

88
from django import forms
9+
from django.forms.formsets import formset_factory
910
from django.template import Template, Context
1011

1112
from .text import text_value, text_concat
@@ -44,6 +45,7 @@ class TestForm(forms.Form):
4445
required=True,
4546
widget=forms.TextInput(attrs={'placeholder': 'placeholdertest'}),
4647
)
48+
password = forms.CharField(widget=forms.PasswordInput)
4749
message = forms.CharField(required=False, help_text='<i>my_help_text</i>')
4850
sender = forms.EmailField(label='Sender © unicode')
4951
secret = forms.CharField(initial=42, widget=forms.HiddenInput)
@@ -266,6 +268,11 @@ def test_subject(self):
266268
self.assertIn('type="text"', res)
267269
self.assertIn('placeholder="placeholdertest"', res)
268270

271+
def test_password(self):
272+
res = render_form_field('password')
273+
self.assertIn('type="password"', res)
274+
self.assertIn('placeholder="Password"', res)
275+
269276
def test_required_field(self):
270277
required_field = render_form_field('subject')
271278
self.assertIn('required', required_field)
@@ -445,3 +452,22 @@ def test_button(self):
445452
res.strip(),
446453
'<a class="btn btn-lg" href="#">button</a><a href="#" ' +
447454
'class="btn btn-lg">button</a>')
455+
456+
457+
class ShowLabelTest(TestCase):
458+
def test_show_label(self):
459+
form = TestForm()
460+
res = render_template(
461+
'{% bootstrap_form form show_label=False %}',
462+
form=form
463+
)
464+
self.assertIn('sr-only', res)
465+
466+
def test_for_formset(self):
467+
TestFormSet = formset_factory(TestForm, extra=1)
468+
test_formset = TestFormSet()
469+
res = render_template(
470+
'{% bootstrap_formset formset show_label=False %}',
471+
formset=test_formset
472+
)
473+
self.assertIn('sr-only', res)

bootstrap3/utils.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,68 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import unicode_literals
33

4+
import re
5+
46
from django.forms.widgets import flatatt
7+
from django.template import Variable, VariableDoesNotExist
8+
from django.template.base import FilterExpression, kwarg_re, TemplateSyntaxError
9+
510

611
from .text import text_value
712

813

9-
# Handle HTML and CSS manipulation
14+
# RegEx for quoted string
15+
QUOTED_STRING = re.compile(r'^["\'](?P<noquotes>.+)["\']$')
16+
17+
18+
def handle_var(value, context):
19+
"""
20+
Handle template tag variable
21+
"""
22+
# Resolve FilterExpression and Variable immediately
23+
if isinstance(value, FilterExpression) or isinstance(value, Variable):
24+
return value.resolve(context)
25+
# Return quoted strings unquoted
26+
# http://djangosnippets.org/snippets/886
27+
stringval = QUOTED_STRING.search(value)
28+
if stringval:
29+
return stringval.group('noquotes')
30+
# Resolve variable or return string value
31+
try:
32+
return Variable(value).resolve(context)
33+
except VariableDoesNotExist:
34+
return value
35+
36+
37+
def parse_token_contents(parser, token):
38+
"""
39+
Parse template tag contents
40+
"""
41+
bits = token.split_contents()
42+
tag = bits.pop(0)
43+
args = []
44+
kwargs = {}
45+
asvar = None
46+
if len(bits) >= 2 and bits[-2] == 'as':
47+
asvar = bits[-1]
48+
bits = bits[:-2]
49+
if len(bits):
50+
for bit in bits:
51+
match = kwarg_re.match(bit)
52+
if not match:
53+
raise TemplateSyntaxError(
54+
'Malformed arguments to tag "{}"'.format(tag))
55+
name, value = match.groups()
56+
if name:
57+
kwargs[name] = parser.compile_filter(value)
58+
else:
59+
args.append(parser.compile_filter(value))
60+
return {
61+
'tag': tag,
62+
'args': args,
63+
'kwargs': kwargs,
64+
'asvar': asvar,
65+
}
1066

1167

1268
def split_css_classes(css_classes):

docs/settings.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ The ``BOOTSTRAP3`` dict variable is contains these settings and defaults:
1818
'jquery_url': '//code.jquery.com/jquery.min.js',
1919
2020
# The Bootstrap base URL
21-
'base_url': '//netdna.bootstrapcdn.com/bootstrap/3.3.1/',
21+
'base_url': '//netdna.bootstrapcdn.com/bootstrap/3.3.4/',
2222
2323
# The complete URL to the Bootstrap CSS file (None means derive it from base_url)
2424
'css_url': None,

0 commit comments

Comments
 (0)