Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
dyve committed Mar 24, 2021
1 parent 3a173e1 commit 89445be
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 30 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
.PHONY: test tox reformat lint docs porcelain branch build publish
.PHONY: test tox reformat lint docs porcelain branch build publish example

PROJECT_DIR=src/django_bootstrap5
PYTHON_SOURCES=${PROJECT_DIR} tests example *.py

example:
cd example && python manage.py runserver

test:
coverage run manage.py test
coverage report
Expand Down
5 changes: 4 additions & 1 deletion example/templates/app/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
<form method="post">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons submit='OK' reset="Cancel" %}{% endbuttons %}

{% bootstrap_button button_type="submit" content="OK" %}
{% bootstrap_button button_type="reset" content="Cancel" %}

</form>

{% endblock %}
27 changes: 27 additions & 0 deletions src/django_bootstrap5/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

from django.conf import settings

from django_bootstrap5.exceptions import BootstrapError
from django_bootstrap5.text import text_value

SIZE_XS = "xs"
SIZE_SM = "sm"
SIZE_MD = "md"
SIZE_LG = "lg"
SIZES = [SIZE_SM, SIZE_MD, SIZE_LG]
DEFAULT_SIZE = SIZE_MD

BOOTSTRAP5_DEFAULTS = {
"css_url": {
"url": "https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css",
Expand Down Expand Up @@ -84,3 +94,20 @@ def get_form_renderer(**kwargs):
def get_field_renderer(**kwargs):
renderers = get_bootstrap_setting("field_renderers")
return get_renderer(renderers, **kwargs)


def parse_size(value, default=None):
"""Return size if it is valid, default size if size is empty, or throws exception."""
size = text_value(value or default)
if size not in SIZES:
valid_sizes = ", ".join(SIZES)
raise BootstrapError(f'Invalid value "{size}" for parameter "size" (valid values are {valid_sizes}).')
return size


def get_size_class(size, prefix, *, default=None, skip=None):
"""Return CSS class for size with given prefix, unless size needs to be skipped."""
size = parse_size(size, default=default)
if skip and size in list(skip):
return ""
return f"{prefix}{size}"
26 changes: 12 additions & 14 deletions src/django_bootstrap5/forms.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
from django.forms import EmailInput, NumberInput, PasswordInput, Textarea, TextInput, URLInput
from django.utils.safestring import mark_safe

from .core import get_bootstrap_setting, get_field_renderer, get_form_renderer, get_formset_renderer
from .core import (
DEFAULT_SIZE,
SIZE_MD,
get_bootstrap_setting,
get_field_renderer,
get_form_renderer,
get_formset_renderer,
get_size_class,
)
from .css import merge_css_classes
from .exceptions import BootstrapError
from .html import render_tag
from .text import text_value

WRAPPER_CLASS = ""
WRAPPER_TAG = "div"
Expand Down Expand Up @@ -57,6 +64,7 @@ def render_button(
content,
button_type=None,
button_class="btn-primary",
button_outline=False,
size="",
href="",
name=None,
Expand All @@ -67,18 +75,8 @@ def render_button(
):
"""Render a button with content."""
attrs = {}
classes = merge_css_classes("btn", button_class)
size = text_value(size).lower().strip()
if size == "xs":
classes = merge_css_classes(classes, "btn-xs")
elif size == "sm" or size == "small":
classes = merge_css_classes(classes, "btn-sm")
elif size == "lg" or size == "large":
classes = merge_css_classes(classes, "btn-lg")
elif size == "md" or size == "medium":
pass
elif size:
raise BootstrapError('Parameter "size" should be "xs", "sm", "lg" or empty ("{size}" given).'.format(size=size))
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"):
Expand Down
21 changes: 7 additions & 14 deletions src/django_bootstrap5/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from django.utils.html import conditional_escape, format_html, strip_tags
from django.utils.safestring import mark_safe

from .core import get_bootstrap_setting
from .core import DEFAULT_SIZE, SIZE_MD, SIZE_XS, get_bootstrap_setting, get_size_class, parse_size
from .css import merge_css_classes
from .exceptions import BootstrapError
from .forms import WRAPPER_CLASS, WRAPPER_TAG, is_widget_with_placeholder, render_field, render_form, render_label
Expand All @@ -38,12 +38,6 @@
class BaseRenderer(object):
"""A content renderer."""

SIZE_SM = "sm"
SIZE_MD = "md"
SIZE_LG = "lg"
DEFAULT_SIZE = SIZE_MD
SIZES = [SIZE_SM, SIZE_MD, SIZE_LG]

def __init__(self, *args, **kwargs):
self.layout = kwargs.get("layout", "")
self.wrapper_class = kwargs.get("wrapper_class", WRAPPER_CLASS)
Expand All @@ -54,7 +48,7 @@ def __init__(self, *args, **kwargs):
self.exclude = kwargs.get("exclude", "")

self.set_placeholder = kwargs.get("set_placeholder", True)
self.size = self.parse_size(kwargs.get("size", ""))
self.size = parse_size(kwargs.get("size", ""), default=SIZE_MD)
self.horizontal_label_class = kwargs.get(
"horizontal_label_class", get_bootstrap_setting("horizontal_label_class")
)
Expand All @@ -80,15 +74,14 @@ def is_inline(self):

def parse_size(self, size):
"""Return size if it is valid, default size if size is empty, or throws exception."""
size = text_value(size) or self.DEFAULT_SIZE
if size not in self.SIZES:
valid_sizes = ", ".join(self.SIZES)
raise BootstrapError(f'Invalid value "{size}" for parameter "size" (valid values are {valid_sizes}).')
size = parse_size(size, default=DEFAULT_SIZE)
if size == SIZE_XS:
raise BootstrapError(f'Size "xs" is not valid for form controls.')
return size

def get_size_class(self, prefix):
"""Return size class for given prefix."""
return f"{prefix}-{self.size}" if self.size in ["sm", "lg"] else ""
return get_size_class(self.size, prefix=prefix) if self.size in ["sm", "lg"] else ""

def get_context_data(self):
"""Return context data for rendering."""
Expand Down Expand Up @@ -345,7 +338,7 @@ def add_widget_class_attrs(self, widget=None):
elif isinstance(widget, CheckboxInput):
classes = merge_css_classes("form-check-input", classes)
if size_prefix:
classes = merge_css_classes(classes, self.get_size_class(prefix=size_prefix))
classes = merge_css_classes(classes, get_size_class(self.size, prefix=size_prefix, skip=["xs", "md"]))

if self.field.errors:
if self.error_css_class:
Expand Down

0 comments on commit 89445be

Please sign in to comment.