Skip to content

Commit

Permalink
Add keywords arguments to bootstrap_button tag (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
dyve authored May 3, 2021
1 parent 2f21319 commit b2b93bb
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 74 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
## In development

- Add size parameter to example forms.
- Add keyword arguments to `bootstrap_button` tag.
- Do not apply `mark_safe` to content for `bootstrap_button`.

## [1.0.0] - 2021-04-30

- Set PyPI classifier for Development Status to Production/Stable.
- Set PyPI classifier "Development Status :: 5 - Production/Stable".
- Support addons for `form-control` widgets.

## [0.6.0] - 2021-04-26
Expand Down
43 changes: 43 additions & 0 deletions src/django_bootstrap5/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
from django.utils.translation import gettext as _

from .css import merge_css_classes
from .exceptions import BootstrapError
from .html import render_tag
from .size import DEFAULT_SIZE, SIZE_MD, get_size_class

ALERT_TYPES = ["primary", "secondary", "success", "danger", "warning", "info", "light", "dark"]

Expand All @@ -18,9 +20,50 @@ def render_alert(content, alert_type="info", dismissible=True, extra_classes="")
css_classes.append("alert-dismissible fade show")
close = capfirst(_("close"))
button = f'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{close}"></button>'
# TODO: use extra_classes
css_classes = merge_css_classes(*css_classes)
return render_tag(
"div",
attrs={"class": css_classes, "role": "alert"},
content=format_html("{content}" + button, content=content),
)


def render_button(
content,
button_type=None,
button_class="btn-primary",
size="",
href="",
extra_classes="",
**kwargs,
):
"""Render a button with content."""
attrs = {}
attrs.update(kwargs)
size_class = get_size_class(size, prefix="btn", skip=SIZE_MD, default=DEFAULT_SIZE)
classes = merge_css_classes("btn", button_class, size_class)
tag = "button"

if button_type:
if button_type not in ("submit", "reset", "button", "link"):
raise BootstrapError(
(
'Parameter "button_type" should be "submit", "reset", "button", "link" or empty '
f'("{button_type}" given).'
).format(button_type=button_type)
)
if button_type != "link":
attrs["type"] = button_type

if href:
if button_type and button_type != "link":
raise BootstrapError(f'Button of type "{button_type}" is not allowed a "href" parameter.')
tag = "a"
attrs["href"] = href
attrs.setdefault("role", "button")

classes = merge_css_classes(classes, extra_classes)
attrs["class"] = classes

return render_tag(tag, attrs=attrs, content=content)
60 changes: 0 additions & 60 deletions src/django_bootstrap5/forms.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
from django.utils.safestring import mark_safe

from .core import get_field_renderer, get_form_renderer, get_formset_renderer
from .css import merge_css_classes
from .exceptions import BootstrapError
from .html import render_tag
from .size import DEFAULT_SIZE, SIZE_MD, get_size_class

WRAPPER_CLASS = ""
WRAPPER_TAG = "div"
Expand Down Expand Up @@ -50,58 +45,3 @@ def render_label(content, label_for=None, label_class=None, label_title=""):
if label_title:
attrs["title"] = label_title
return render_tag("label", attrs=attrs, content=content)


def render_button(
content,
button_type=None,
button_class="btn-primary",
button_outline=False,
size="",
href="",
name=None,
value=None,
title=None,
extra_classes="",
id="",
):
"""Render a button with content."""
attrs = {}
size_class = get_size_class(size, prefix="btn", skip=SIZE_MD, default=DEFAULT_SIZE)
classes = merge_css_classes("btn", button_class, size_class)

if button_type:
if button_type not in ("submit", "reset", "button", "link"):
raise BootstrapError(
(
'Parameter "button_type" should be "submit", "reset", "button", "link" or empty '
'("{button_type}" given).'
).format(button_type=button_type)
)
if button_type != "link":
attrs["type"] = button_type

classes = merge_css_classes(classes, extra_classes)
attrs["class"] = classes

if href:
tag = "a"
if button_type and button_type != "link":
raise BootstrapError(
'Button of type "{button_type}" is not allowed a "href" parameter.'.format(button_type=button_type)
)
attrs["href"] = href
# Specify role for link with button appearance
attrs.setdefault("role", "button")
else:
tag = "button"

if id:
attrs["id"] = id
if name:
attrs["name"] = name
if value:
attrs["value"] = value
if title:
attrs["title"] = title
return render_tag(tag, attrs=attrs, content=mark_safe(content))
16 changes: 5 additions & 11 deletions src/django_bootstrap5/templatetags/django_bootstrap5.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,9 @@
from django.utils.http import urlencode
from django.utils.safestring import mark_safe

from ..components import render_alert
from ..components import render_alert, render_button
from ..core import css_url, get_bootstrap_setting, javascript_url, theme_url
from ..forms import (
render_button,
render_field,
render_form,
render_form_errors,
render_formset,
render_formset_errors,
render_label,
)
from ..forms import render_field, render_form, render_form_errors, render_formset, render_formset_errors, render_label
from ..html import render_link_tag, render_script_tag
from ..size import get_size_class
from ..utils import render_template_file, url_replace_param
Expand Down Expand Up @@ -544,7 +536,6 @@ def bootstrap_button(*args, **kwargs):
* ``'lg'``
* ``'large'``
href
Render the button as an ``<a>`` element. The ``href`` attribute is set with this value.
If a ``button_type`` other than ``link`` is defined, specifying a ``href`` will throw a
Expand All @@ -556,6 +547,9 @@ def bootstrap_button(*args, **kwargs):
value
Value of the ``value`` attribute of the rendered element.
**kwargs
All other keywords arguments will be passed on as HTML attributes.
**Usage**::
{% bootstrap_button content %}
Expand Down
25 changes: 25 additions & 0 deletions tests/test_bootstrap_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,31 @@ def test_button(self):
'<button class="btn btn-primary" title="foo">button</button>',
)

self.assertHTMLEqual(
self.render("{% bootstrap_button 'button' formaction='/somewhere/else' %}"),
'<button class="btn btn-primary" formaction="/somewhere/else">button</button>',
)

def test_button_classes(self):
self.assertHTMLEqual(
self.render("{% bootstrap_button 'button' button_class='btn-outline-primary' %}"),
'<button class="btn btn-outline-primary">button</button>',
)

def test_button_content(self):
self.assertHTMLEqual(
self.render("{% bootstrap_button '<i>button</i>' %}"),
'<button class="btn btn-primary"><i>button</i></button>',
)
self.assertHTMLEqual(
self.render("{% bootstrap_button content %}", {"content": "<i>button</i>"}),
'<button class="btn btn-primary">&lt;i&gt;button&lt;/i&gt;</button>',
)
self.assertHTMLEqual(
self.render("{% bootstrap_button content|safe %}", {"content": "<i>button</i>"}),
'<button class="btn btn-primary"><i>button</i></button>',
)

def test_button_type_link(self):
link_button = '<a class="btn btn-primary btn-lg" href="#" role="button">button</a>'
self.assertHTMLEqual(
Expand Down
3 changes: 1 addition & 2 deletions tests/test_components.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from django.test import TestCase
from django.utils.safestring import mark_safe

from django_bootstrap5.components import render_alert
from django_bootstrap5.components import render_alert, render_button
from django_bootstrap5.exceptions import BootstrapError
from django_bootstrap5.forms import render_button


class AlertsTestCase(TestCase):
Expand Down

0 comments on commit b2b93bb

Please sign in to comment.