diff --git a/bootstrap3/__init__.py b/bootstrap3/__init__.py
deleted file mode 100644
index c2f508106..000000000
--- a/bootstrap3/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# -*- coding: utf-8 -*-
-
-__version__ = '5.1.1'
diff --git a/bootstrap3/bootstrap.py b/bootstrap3/bootstrap.py
deleted file mode 100644
index cae8e496a..000000000
--- a/bootstrap3/bootstrap.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.conf import settings
-from django.utils.importlib import import_module
-
-
-# Default settings
-BOOTSTRAP3_DEFAULTS = {
- 'jquery_url': '//code.jquery.com/jquery.min.js',
- 'base_url': '//netdna.bootstrapcdn.com/bootstrap/3.3.2/',
- 'css_url': None,
- 'theme_url': None,
- 'javascript_url': None,
- 'javascript_in_head': False,
- 'include_jquery': False,
- 'horizontal_label_class': 'col-md-2',
- 'horizontal_field_class': 'col-md-4',
- 'set_required': True,
- 'set_placeholder': True,
- 'required_css_class': '',
- 'error_css_class': 'has-error',
- 'success_css_class': 'has-success',
- 'formset_renderers': {
- 'default': 'bootstrap3.renderers.FormsetRenderer',
- },
- 'form_renderers': {
- 'default': 'bootstrap3.renderers.FormRenderer',
- },
- 'field_renderers': {
- 'default': 'bootstrap3.renderers.FieldRenderer',
- 'inline': 'bootstrap3.renderers.InlineFieldRenderer',
- },
-}
-
-# Start with a copy of default settings
-BOOTSTRAP3 = BOOTSTRAP3_DEFAULTS.copy()
-
-# Override with user settings from settings.py
-BOOTSTRAP3.update(getattr(settings, 'BOOTSTRAP3', {}))
-
-
-def get_bootstrap_setting(setting, default=None):
- """
- Read a setting
- """
- return BOOTSTRAP3.get(setting, default)
-
-
-def bootstrap_url(postfix):
- """
- Prefix a relative url with the bootstrap base url
- """
- return get_bootstrap_setting('base_url') + postfix
-
-
-def jquery_url():
- """
- Return the full url to jQuery file to use
- """
- return get_bootstrap_setting('jquery_url')
-
-
-def javascript_url():
- """
- Return the full url to the Bootstrap JavaScript file
- """
- return get_bootstrap_setting('javascript_url') or \
- bootstrap_url('js/bootstrap.min.js')
-
-
-def css_url():
- """
- Return the full url to the Bootstrap CSS file
- """
- return get_bootstrap_setting('css_url') or \
- bootstrap_url('css/bootstrap.min.css')
-
-
-def theme_url():
- """
- Return the full url to the theme CSS file
- """
- return get_bootstrap_setting('theme_url')
-
-
-def get_renderer(renderers, **kwargs):
- layout = kwargs.get('layout', '')
- path = renderers.get(layout, renderers['default'])
- mod, cls = path.rsplit(".", 1)
- return getattr(import_module(mod), cls)
-
-
-def get_formset_renderer(**kwargs):
- renderers = get_bootstrap_setting('formset_renderers')
- return get_renderer(renderers, **kwargs)
-
-
-def get_form_renderer(**kwargs):
- renderers = get_bootstrap_setting('form_renderers')
- return get_renderer(renderers, **kwargs)
-
-
-def get_field_renderer(**kwargs):
- renderers = get_bootstrap_setting('field_renderers')
- return get_renderer(renderers, **kwargs)
diff --git a/bootstrap3/components.py b/bootstrap3/components.py
deleted file mode 100644
index 403203b0a..000000000
--- a/bootstrap3/components.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.forms.widgets import flatatt
-
-from .text import text_value
-
-
-def render_icon(icon, title=''):
- """
- Render a Bootstrap glyphicon icon
- """
- attrs = {
- 'class': 'glyphicon glyphicon-{icon}'.format(icon=icon),
- }
- if title:
- attrs['title'] = title
- return ''.format(attrs=flatatt(attrs))
-
-
-def render_alert(content, alert_type=None, dismissable=True):
- """
- Render a Bootstrap alert
- """
- button = ''
- if not alert_type:
- alert_type = 'info'
- css_classes = ['alert', 'alert-' + text_value(alert_type)]
- if dismissable:
- css_classes.append('alert-dismissable')
- button = ''
- return '
{button}{content}
'.format(
- css_classes=' '.join(css_classes),
- button=button,
- content=text_value(content),
- )
diff --git a/bootstrap3/exceptions.py b/bootstrap3/exceptions.py
deleted file mode 100644
index 0dcf9acb6..000000000
--- a/bootstrap3/exceptions.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-
-class BootstrapException(Exception):
- """
- Any exception from this package
- """
- pass
-
-
-class BootstrapError(BootstrapException):
- """
- Any exception that is an error
- """
- pass
diff --git a/bootstrap3/forms.py b/bootstrap3/forms.py
deleted file mode 100644
index a9c78f95d..000000000
--- a/bootstrap3/forms.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.contrib.admin.widgets import AdminFileWidget
-from django.forms import (
- HiddenInput, FileInput, CheckboxSelectMultiple, Textarea, TextInput
-)
-
-from .bootstrap import (
- get_bootstrap_setting, get_form_renderer, get_field_renderer,
- get_formset_renderer
-)
-from .text import text_concat, text_value
-from .exceptions import BootstrapError
-from .utils import add_css_class, render_tag
-from .components import render_icon
-
-
-FORM_GROUP_CLASS = 'form-group'
-
-
-def render_formset(formset, **kwargs):
- """
- Render a formset to a Bootstrap layout
- """
- renderer_cls = get_formset_renderer(**kwargs)
- return renderer_cls(formset, **kwargs).render()
-
-
-def render_formset_errors(form, **kwargs):
- """
- Render formset errors to a Bootstrap layout
- """
- renderer_cls = get_formset_renderer(**kwargs)
- return renderer_cls(form, **kwargs).render_errors()
-
-
-def render_form(form, **kwargs):
- """
- Render a formset to a Bootstrap layout
- """
- renderer_cls = get_form_renderer(**kwargs)
- return renderer_cls(form, **kwargs).render()
-
-
-def render_form_errors(form, type='all', **kwargs):
- """
- Render form errors to a Bootstrap layout
- """
- renderer_cls = get_form_renderer(**kwargs)
- return renderer_cls(form, **kwargs).render_errors(type)
-
-
-def render_field(field, **kwargs):
- """
- Render a formset to a Bootstrap layout
- """
- renderer_cls = get_field_renderer(**kwargs)
- return renderer_cls(field, **kwargs).render()
-
-
-def render_label(content, label_for=None, label_class=None, label_title=''):
- """
- Render a label with content
- """
- attrs = {}
- if label_for:
- attrs['for'] = label_for
- if label_class:
- attrs['class'] = label_class
- if label_title:
- attrs['title'] = label_title
- return render_tag('label', attrs=attrs, content=content)
-
-
-def render_button(
- content, button_type=None, icon=None, button_class='', size='',
- href=''):
- """
- Render a button with content
- """
- attrs = {}
- classes = add_css_class('btn', button_class)
- size = text_value(size).lower().strip()
- if size == 'xs':
- classes = add_css_class(classes, 'btn-xs')
- elif size == 'sm' or size == 'small':
- classes = add_css_class(classes, 'btn-sm')
- elif size == 'lg' or size == 'large':
- classes = add_css_class(classes, 'btn-lg')
- elif size == 'md' or size == 'medium':
- pass
- elif size:
- raise BootstrapError(
- 'Parameter "size" should be "xs", "sm", "lg" or ' +
- 'empty ("{}" given).'.format(size))
- if button_type:
- if button_type == 'submit':
- classes = add_css_class(classes, 'btn-primary')
- elif button_type not in ('reset', 'button', 'link'):
- raise BootstrapError(
- 'Parameter "button_type" should be "submit", "reset", ' +
- '"button", "link" or empty ("{}" given).'.format(button_type))
- attrs['type'] = button_type
- attrs['class'] = classes
- icon_content = render_icon(icon) if icon else ''
- if href:
- attrs['href'] = href
- tag = 'a'
- else:
- tag = 'button'
- return render_tag(
- tag, attrs=attrs, content=text_concat(
- icon_content, content, separator=' '))
-
-
-def render_field_and_label(
- field, label, field_class='', label_for=None, label_class='',
- layout='', **kwargs):
- """
- Render a field with its label
- """
- if layout == 'horizontal':
- if not label_class:
- label_class = get_bootstrap_setting('horizontal_label_class')
- if not field_class:
- field_class = get_bootstrap_setting('horizontal_field_class')
- if not label:
- label = ' '
- label_class = add_css_class(label_class, 'control-label')
- html = field
- if field_class:
- html = '{html}
'.format(
- klass=field_class, html=html)
- if label:
- html = render_label(
- label, label_for=label_for, label_class=label_class) + html
- return html
-
-
-def render_form_group(content, css_class=FORM_GROUP_CLASS):
- """
- Render a Bootstrap form group
- """
- return '{content}
'.format(
- klass=css_class,
- content=content,
- )
-
-
-def is_widget_required_attribute(widget):
- """
- Is this widget required?
- """
- if not get_bootstrap_setting('set_required'):
- return False
- if not widget.is_required:
- return False
- if isinstance(
- widget, (
- AdminFileWidget, HiddenInput, FileInput,
- CheckboxSelectMultiple)):
- return False
- return True
-
-
-def is_widget_with_placeholder(widget):
- """
- Is this a widget that should have a placeholder?
- Only text, search, url, tel, e-mail, password, number have placeholders
- These are all derived form TextInput, except for Textarea
- """
- return isinstance(widget, (TextInput, Textarea))
diff --git a/bootstrap3/models.py b/bootstrap3/models.py
deleted file mode 100644
index 60b94b00d..000000000
--- a/bootstrap3/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Empty models.py, required file for Django tests
diff --git a/bootstrap3/renderers.py b/bootstrap3/renderers.py
deleted file mode 100644
index f383844c9..000000000
--- a/bootstrap3/renderers.py
+++ /dev/null
@@ -1,485 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-from django.contrib.auth.forms import ReadOnlyPasswordHashWidget
-
-from django.forms import (
- TextInput, DateInput, FileInput, CheckboxInput,
- ClearableFileInput, Select, RadioSelect, CheckboxSelectMultiple
-)
-from django.forms.extras import SelectDateWidget
-from django.forms.forms import BaseForm, BoundField
-from django.forms.formsets import BaseFormSet
-from django.utils.html import conditional_escape, strip_tags
-from django.template import Context
-from django.template.loader import get_template
-from django.utils.safestring import mark_safe
-
-from .bootstrap import get_bootstrap_setting
-from .text import text_value
-from .exceptions import BootstrapError
-from .utils import add_css_class
-from .forms import (
- render_form, render_field, render_label, render_form_group,
- is_widget_with_placeholder, is_widget_required_attribute, FORM_GROUP_CLASS
-)
-
-
-class BaseRenderer(object):
- def __init__(self, *args, **kwargs):
- self.layout = kwargs.get('layout', '')
- self.form_group_class = kwargs.get(
- 'form_group_class', FORM_GROUP_CLASS)
- self.field_class = kwargs.get('field_class', '')
- self.label_class = kwargs.get('label_class', '')
- self.show_help = kwargs.get('show_help', True)
- self.show_label = kwargs.get('show_label', True)
- self.exclude = kwargs.get('exclude', '')
- self.set_required = kwargs.get('set_required', True)
- self.size = self.parse_size(kwargs.get('size', ''))
- self.horizontal_label_class = kwargs.get(
- 'horizontal_label_class',
- get_bootstrap_setting('horizontal_label_class')
- )
- self.horizontal_field_class = kwargs.get(
- 'horizontal_field_class',
- get_bootstrap_setting('horizontal_field_class')
- )
-
- def parse_size(self, size):
- size = text_value(size).lower().strip()
- if size in ('sm', 'small'):
- return 'small'
- if size in ('lg', 'large'):
- return 'large'
- if size in ('md', 'medium', ''):
- return 'medium'
- raise BootstrapError('Invalid value "%s" for parameter "size" (expected "sm", "md", "lg" or "").' % size)
-
- def get_size_class(self, prefix='input'):
- if self.size == 'small':
- return prefix + '-sm'
- if self.size == 'large':
- return prefix + '-lg'
- return ''
-
-
-class FormsetRenderer(BaseRenderer):
- """
- Default formset renderer
- """
-
- def __init__(self, formset, *args, **kwargs):
- if not isinstance(formset, BaseFormSet):
- raise BootstrapError(
- 'Parameter "formset" should contain a valid Django Formset.')
- self.formset = formset
- super(FormsetRenderer, self).__init__(*args, **kwargs)
-
- def render_management_form(self):
- return text_value(self.formset.management_form)
-
- def render_form(self, form, **kwargs):
- return render_form(form, **kwargs)
-
- def render_forms(self):
- rendered_forms = []
- for form in self.formset.forms:
- rendered_forms.append(self.render_form(
- form,
- layout=self.layout,
- form_group_class=self.form_group_class,
- field_class=self.field_class,
- label_class=self.label_class,
- show_help=self.show_help,
- exclude=self.exclude,
- set_required=self.set_required,
- size=self.size,
- horizontal_label_class=self.horizontal_label_class,
- horizontal_field_class=self.horizontal_field_class,
- ))
- return '\n'.join(rendered_forms)
-
- def get_formset_errors(self):
- return self.formset.non_form_errors()
-
- def render_errors(self):
- formset_errors = self.get_formset_errors()
- if formset_errors:
- return get_template(
- 'bootstrap3/form_errors.html').render(
- Context({
- 'errors': formset_errors,
- 'form': self.formset,
- 'layout': self.layout,
- })
- )
- return ''
-
- def render(self):
- return self.render_errors() + self.render_management_form() + \
- self.render_forms()
-
-
-class FormRenderer(BaseRenderer):
- """
- Default form renderer
- """
-
- def __init__(self, form, *args, **kwargs):
- if not isinstance(form, BaseForm):
- raise BootstrapError(
- 'Parameter "form" should contain a valid Django Form.')
- self.form = form
- super(FormRenderer, self).__init__(*args, **kwargs)
- # Handle form.empty_permitted
- if self.form.empty_permitted:
- self.set_required = False
-
- def render_fields(self):
- rendered_fields = []
- for field in self.form:
- rendered_fields.append(render_field(
- field,
- layout=self.layout,
- form_group_class=self.form_group_class,
- field_class=self.field_class,
- label_class=self.label_class,
- show_help=self.show_help,
- exclude=self.exclude,
- set_required=self.set_required,
- size=self.size,
- horizontal_label_class=self.horizontal_label_class,
- horizontal_field_class=self.horizontal_field_class,
- ))
- return '\n'.join(rendered_fields)
-
- def get_fields_errors(self):
- form_errors = []
- for field in self.form:
- if field.is_hidden and field.errors:
- form_errors += field.errors
- return form_errors
-
- def render_errors(self, type='all'):
- form_errors = None
- if type == 'all':
- form_errors = self.get_fields_errors() + \
- self.form.non_field_errors()
- elif type == 'fields':
- form_errors = self.get_fields_errors()
- elif type == 'non_fields':
- form_errors = self.form.non_field_errors()
-
- if form_errors:
- return get_template(
- 'bootstrap3/form_errors.html').render(
- Context({
- 'errors': form_errors,
- 'form': self.form,
- 'layout': self.layout,
- })
- )
- return ''
-
- def render(self):
- return self.render_errors() + self.render_fields()
-
-
-class FieldRenderer(BaseRenderer):
- """
- Default field renderer
- """
-
- def __init__(self, field, *args, **kwargs):
- if not isinstance(field, BoundField):
- raise BootstrapError(
- 'Parameter "field" should contain a valid Django BoundField.')
- self.field = field
- super(FieldRenderer, self).__init__(*args, **kwargs)
-
- self.widget = field.field.widget
- self.initial_attrs = self.widget.attrs.copy()
- self.field_help = text_value(mark_safe(field.help_text)) \
- if self.show_help and field.help_text else ''
- self.field_errors = [conditional_escape(text_value(error))
- for error in field.errors]
-
- if get_bootstrap_setting('set_placeholder'):
- self.placeholder = field.label
- else:
- self.placeholder = ''
-
- self.addon_before = kwargs.get('addon_before', self.initial_attrs.pop('addon_before', ''))
- self.addon_after = kwargs.get('addon_after', self.initial_attrs.pop('addon_after', ''))
-
- # These are set in Django or in the global BOOTSTRAP3 settings, and
- # they can be overwritten in the template
- error_css_class = kwargs.get('error_css_class', '')
- required_css_class = kwargs.get('required_css_class', '')
- bound_css_class = kwargs.get('bound_css_class', '')
- if error_css_class:
- self.error_css_class = error_css_class
- else:
- self.error_css_class = getattr(
- field.form, 'error_css_class',
- get_bootstrap_setting('error_css_class'))
- if required_css_class:
- self.required_css_class = required_css_class
- else:
- self.required_css_class = getattr(
- field.form, 'required_css_class',
- get_bootstrap_setting('required_css_class'))
- if bound_css_class:
- self.success_css_class = bound_css_class
- else:
- self.success_css_class = getattr(
- field.form, 'bound_css_class',
- get_bootstrap_setting('success_css_class'))
-
- # Handle form.empty_permitted
- if self.field.form.empty_permitted:
- self.set_required = False
- self.required_css_class = ''
-
- def restore_widget_attrs(self):
- self.widget.attrs = self.initial_attrs
-
- def add_class_attrs(self):
- classes = self.widget.attrs.get('class', '')
- if isinstance(self.widget, ReadOnlyPasswordHashWidget):
- classes = add_css_class(
- classes, 'form-control-static', prepend=True)
- elif not isinstance(self.widget, (CheckboxInput,
- RadioSelect,
- CheckboxSelectMultiple,
- FileInput)):
- classes = add_css_class(classes, 'form-control', prepend=True)
- # For these widget types, add the size class here
- classes = add_css_class(classes, self.get_size_class())
- self.widget.attrs['class'] = classes
-
- def add_placeholder_attrs(self):
- placeholder = self.widget.attrs.get('placeholder', self.placeholder)
- if placeholder and is_widget_with_placeholder(self.widget):
- self.widget.attrs['placeholder'] = placeholder
-
- def add_help_attrs(self):
- if not isinstance(self.widget, CheckboxInput):
- self.widget.attrs['title'] = self.widget.attrs.get(
- 'title', strip_tags(self.field_help))
-
- def add_required_attrs(self):
- if self.set_required and is_widget_required_attribute(self.widget):
- self.widget.attrs['required'] = 'required'
-
- def add_widget_attrs(self):
- self.add_class_attrs()
- self.add_placeholder_attrs()
- self.add_help_attrs()
- self.add_required_attrs()
-
- def list_to_class(self, html, klass):
- classes = add_css_class(klass, self.get_size_class())
- mapping = [
- ('