Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add extra parameters to HTML tag and convert data tags for bootstrap_… #436

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions bootstrap3/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from .components import render_icon
from .exceptions import BootstrapError
from .text import text_concat, text_value
from .utils import add_css_class, render_tag
from .utils import add_css_class, render_tag, convert_data_attrs

FORM_GROUP_CLASS = 'form-group'

Expand Down Expand Up @@ -69,7 +69,8 @@ def render_field(field, **kwargs):
return renderer_cls(field, **kwargs).render()


def render_label(content, label_for=None, label_class=None, label_title=''):
def render_label(content, label_for=None, label_class=None, label_title='',
**kwargs):
"""
Render a label with content
"""
Expand All @@ -80,12 +81,15 @@ def render_label(content, label_for=None, label_class=None, label_title=''):
attrs['class'] = label_class
if label_title:
attrs['title'] = label_title
# allow any other tag attributes to be specified as arguments to
# `bootstrap_label`
attrs.update(convert_data_attrs(kwargs))
return render_tag('label', attrs=attrs, content=content)


def render_button(
content, button_type=None, icon=None, button_class='btn-default', size='',
href='', name=None, value=None, title=None, extra_classes='', id=''):
href='', name=None, value=None, title=None, extra_classes='', id='', **kwargs):
"""
Render a button with content
"""
Expand Down Expand Up @@ -126,6 +130,9 @@ def render_button(
attrs['value'] = value
if title:
attrs['title'] = title
# allow any other tag attributes to be specified as arguments to
# `bootstrap_button`
attrs.update(convert_data_attrs(kwargs))
return render_tag(
tag,
attrs=attrs,
Expand Down
12 changes: 12 additions & 0 deletions bootstrap3/templatetags/bootstrap3.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,12 @@ def bootstrap_label(*args, **kwargs):
label_title
The value that will be in the ``title`` attribute of the rendered ``<label>``

\*\*kwargs
Additional attributes that will be set on the generated HTML tag.
Keys starting with ``"data_"`` will have *all* underscores
(``"_"``) replaced with hyphens (``"-"``) for compatibility with
data attributes.

**Usage**::

{% bootstrap_label content %}
Expand Down Expand Up @@ -606,6 +612,12 @@ def bootstrap_button(*args, **kwargs):
value
Value of the ``value`` attribute of the rendered element.

\*\*kwargs
Additional attributes that will be set on the generated HTML tag.
Keys starting with ``"data_"`` will have *all* underscores
(``"_"``) replaced with hyphens (``"-"``) for compatibility with
data attributes.

**Usage**::

{% bootstrap_button content %}
Expand Down
26 changes: 25 additions & 1 deletion bootstrap3/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from .bootstrap import DBS3_SET_REQUIRED_SET_DISABLED
from .exceptions import BootstrapError
from .text import text_value, text_concat
from .utils import add_css_class, render_tag
from .utils import add_css_class, render_tag, convert_data_attrs

try:
from html.parser import HTMLParser
Expand Down Expand Up @@ -574,6 +574,12 @@ def test_label(self):
res = render_template_with_form('{% bootstrap_label "foobar" label_for="subject" %}')
self.assertEqual('<label for="subject">foobar</label>', res)

def test_extra_label_attributes(self):
res = render_template_with_form('{% bootstrap_label "spam" data_attr_quest="to_seek_the_holy_grail" %}')
self.assertIn('data-attr-quest="to_seek_the_holy_grail"', res)
res = render_template_with_form('{% bootstrap_label "swallow" african_or_european="unknown" %}')
self.assertIn('african_or_european="unknown"', res)

def test_attributes_consistency(self):
form = TestForm()
attrs = form.fields['addon'].widget.attrs.copy()
Expand Down Expand Up @@ -744,6 +750,18 @@ def test_render_tag(self):
'<span bar="123">foo</span>'
)

def test_convert_data_attrs(self):
self.assertEqual(
convert_data_attrs({
"spam_eggs": "spam",
"data_camelot_place_type": "silly",
}),
{
"spam_eggs": "spam",
"data-camelot-place-type": "silly",
}
)


class ButtonTest(TestCase):
def test_button(self):
Expand All @@ -756,6 +774,12 @@ def test_button(self):
'<a class="btn btn-default btn-lg" href="#">button</a><a href="#" ' +
'class="btn btn-lg">button</a>')

def test_additional_attributes(self):
res = render_template_with_form("{% bootstrap_button 'button' 'submit' formaction='test_formaction' %}")
self.assertIn('formaction="test_formaction"', res.strip())
res = render_template_with_form("{% bootstrap_button 'button' data_attr_beast_location='caerbannog' %}")
self.assertIn('data-attr-beast-location="caerbannog"', res.strip())


class ShowLabelTest(TestCase):
def test_show_label(self):
Expand Down
17 changes: 17 additions & 0 deletions bootstrap3/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,23 @@ def render_template_file(template, context=None):
return template.render(context)


def _convert_data_attrs_key(key):
if key.startswith("data_"):
return key.replace("_", "-")
return key


def convert_data_attrs(attrs):
"""
Replace "_" with "-" for keys that start with "data_".
Used to allow passing HTML data attributes (that must contain a "-") as
templatetag parameters (that may not contain a "-").
"""
return {
_convert_data_attrs_key(k): v for k, v in attrs.items()
}


def url_replace_param(url, name, value):
"""
Replace a GET parameter in an URL
Expand Down