diff --git a/djangocms_bootstrap4/constants.py b/djangocms_bootstrap4/constants.py
index 05b56d8a..019ae157 100644
--- a/djangocms_bootstrap4/constants.py
+++ b/djangocms_bootstrap4/constants.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
DEVICE_CHOICES = (
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_alerts/cms_plugins.py b/djangocms_bootstrap4/contrib/bootstrap4_alerts/cms_plugins.py
index adcf8699..3db756e9 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_alerts/cms_plugins.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_alerts/cms_plugins.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_alerts/migrations/0002_alter_bootstrap4alerts_cmsplugin_ptr.py b/djangocms_bootstrap4/contrib/bootstrap4_alerts/migrations/0002_alter_bootstrap4alerts_cmsplugin_ptr.py
new file mode 100644
index 00000000..1c083884
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_alerts/migrations/0002_alter_bootstrap4alerts_cmsplugin_ptr.py
@@ -0,0 +1,28 @@
+# Generated by Django 4.2.4 on 2023-08-20 15:56
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("cms", "0022_auto_20180620_1551"),
+ ("bootstrap4_alerts", "0001_initial"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="bootstrap4alerts",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_alerts/models.py b/djangocms_bootstrap4/contrib/bootstrap4_alerts/models.py
index fe5fee24..62b95219 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_alerts/models.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_alerts/models.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.models import CMSPlugin
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_badge/cms_plugins.py b/djangocms_bootstrap4/contrib/bootstrap4_badge/cms_plugins.py
index 4478c741..eda1a942 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_badge/cms_plugins.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_badge/cms_plugins.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_badge/migrations/0002_alter_bootstrap4badge_cmsplugin_ptr.py b/djangocms_bootstrap4/contrib/bootstrap4_badge/migrations/0002_alter_bootstrap4badge_cmsplugin_ptr.py
new file mode 100644
index 00000000..104fdd7f
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_badge/migrations/0002_alter_bootstrap4badge_cmsplugin_ptr.py
@@ -0,0 +1,28 @@
+# Generated by Django 4.2.4 on 2023-08-20 15:56
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("cms", "0022_auto_20180620_1551"),
+ ("bootstrap4_badge", "0001_initial"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="bootstrap4badge",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_badge/models.py b/djangocms_bootstrap4/contrib/bootstrap4_badge/models.py
index eee5c8f8..09e22e99 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_badge/models.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_badge/models.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.models import CMSPlugin
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_card/cms_plugins.py b/djangocms_bootstrap4/contrib/bootstrap4_card/cms_plugins.py
index 81f3b13c..104b78bb 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_card/cms_plugins.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_card/cms_plugins.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_card/constants.py b/djangocms_bootstrap4/contrib/bootstrap4_card/constants.py
index 5f61bf5b..a3bca5d3 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_card/constants.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_card/constants.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
CARD_TYPE_CHOICES = (
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_card/migrations/0002_alter_bootstrap4card_cmsplugin_ptr_and_more.py b/djangocms_bootstrap4/contrib/bootstrap4_card/migrations/0002_alter_bootstrap4card_cmsplugin_ptr_and_more.py
new file mode 100644
index 00000000..aa18236a
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_card/migrations/0002_alter_bootstrap4card_cmsplugin_ptr_and_more.py
@@ -0,0 +1,41 @@
+# Generated by Django 4.2.4 on 2023-08-20 15:56
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("cms", "0022_auto_20180620_1551"),
+ ("bootstrap4_card", "0001_initial"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="bootstrap4card",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="bootstrap4cardinner",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_card/models.py b/djangocms_bootstrap4/contrib/bootstrap4_card/models.py
index bd36bee9..f727ecad 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_card/models.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_card/models.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.models import CMSPlugin
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_carousel/cms_plugins.py b/djangocms_bootstrap4/contrib/bootstrap4_carousel/cms_plugins.py
index fc649589..c3166bae 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_carousel/cms_plugins.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_carousel/cms_plugins.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_carousel/constants.py b/djangocms_bootstrap4/contrib/bootstrap4_carousel/constants.py
index d76c1f62..fbb78f85 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_carousel/constants.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_carousel/constants.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
CAROUSEL_PAUSE_CHOICES = (
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_carousel/models.py b/djangocms_bootstrap4/contrib/bootstrap4_carousel/models.py
index 595472cb..30ca77fe 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_carousel/models.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_carousel/models.py
@@ -5,7 +5,7 @@
from django.db import models
from django.utils.html import strip_tags
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.models import CMSPlugin
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_collapse/cms_plugins.py b/djangocms_bootstrap4/contrib/bootstrap4_collapse/cms_plugins.py
index 41ea6b0e..fa29f654 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_collapse/cms_plugins.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_collapse/cms_plugins.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_collapse/migrations/0002_alter_bootstrap4collapse_cmsplugin_ptr_and_more.py b/djangocms_bootstrap4/contrib/bootstrap4_collapse/migrations/0002_alter_bootstrap4collapse_cmsplugin_ptr_and_more.py
new file mode 100644
index 00000000..211c1633
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_collapse/migrations/0002_alter_bootstrap4collapse_cmsplugin_ptr_and_more.py
@@ -0,0 +1,54 @@
+# Generated by Django 4.2.4 on 2023-08-20 15:56
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("cms", "0022_auto_20180620_1551"),
+ ("bootstrap4_collapse", "0001_initial"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="bootstrap4collapse",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="bootstrap4collapsecontainer",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="bootstrap4collapsetrigger",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_collapse/models.py b/djangocms_bootstrap4/contrib/bootstrap4_collapse/models.py
index 14d42853..94b76f04 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_collapse/models.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_collapse/models.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.models import CMSPlugin
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_content/cms_plugins.py b/djangocms_bootstrap4/contrib/bootstrap4_content/cms_plugins.py
index 589d0c9e..ef4ff791 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_content/cms_plugins.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_content/cms_plugins.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_content/constants.py b/djangocms_bootstrap4/contrib/bootstrap4_content/constants.py
index 326c9144..08672e18 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_content/constants.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_content/constants.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
CODE_TYPE_CHOICES = (
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_content/migrations/0003_add_field_origin_subtext.py b/djangocms_bootstrap4/contrib/bootstrap4_content/migrations/0003_add_field_origin_subtext.py
new file mode 100644
index 00000000..aabfe28d
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_content/migrations/0003_add_field_origin_subtext.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.4 on 2021-01-07 23:05
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_content', '0002_added_figure'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='bootstrap4blockquote',
+ name='quote_origin_subtext',
+ field=models.CharField(blank=True, max_length=256, verbose_name='Cite subtext'),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_content/migrations/0004_alter_bootstrap4blockquote_cmsplugin_ptr_and_more.py b/djangocms_bootstrap4/contrib/bootstrap4_content/migrations/0004_alter_bootstrap4blockquote_cmsplugin_ptr_and_more.py
new file mode 100644
index 00000000..681d5c65
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_content/migrations/0004_alter_bootstrap4blockquote_cmsplugin_ptr_and_more.py
@@ -0,0 +1,54 @@
+# Generated by Django 4.2.4 on 2023-08-20 15:56
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("cms", "0022_auto_20180620_1551"),
+ ("bootstrap4_content", "0003_add_field_origin_subtext"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="bootstrap4blockquote",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="bootstrap4code",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="bootstrap4figure",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_content/models.py b/djangocms_bootstrap4/contrib/bootstrap4_content/models.py
index c44db684..812efc27 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_content/models.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_content/models.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from cms.models import CMSPlugin
@@ -51,6 +51,11 @@ class Bootstrap4Blockquote(CMSPlugin):
verbose_name=_('Cite'),
blank=True,
)
+ quote_origin_subtext = models.CharField(
+ verbose_name=_('Cite subtext'),
+ blank=True,
+ max_length=256,
+ )
quote_alignment = models.CharField(
verbose_name=_('Alignment'),
choices=ALIGN_CHOICES,
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/cms_plugins.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/cms_plugins.py
index 40ba4504..ca1daa2f 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_grid/cms_plugins.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/cms_plugins.py
@@ -1,12 +1,15 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils.translation import ugettext_lazy as _
+from cms.models import CMSPlugin
+from cms.utils.plugins import get_plugin_model
+from django.utils.translation import gettext_lazy as _
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from djangocms_bootstrap4.constants import DEVICE_SIZES
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_CONTAINER_FIELDSETS
from djangocms_bootstrap4.helpers import concat_classes
from .forms import Bootstrap4GridColumnForm, Bootstrap4GridRowForm
@@ -25,32 +28,30 @@ class Bootstrap4GridContainerPlugin(CMSPluginBase):
module = _('Bootstrap 4')
render_template = 'djangocms_bootstrap4/grid_container.html'
allow_children = True
+ css_class = 'container-plugin'
+ fieldsets = GRID_CONTAINER_FIELDSETS
- fieldsets = [
- (None, {
- 'fields': (
- 'container_type',
- )
- }),
- (_('Advanced settings'), {
- 'classes': ('collapse',),
- 'fields': (
- 'tag_type',
- 'attributes',
- )
- }),
- ]
-
- def render(self, context, instance, placeholder):
+ def render(self, context, instance: Bootstrap4GridContainer, placeholder):
classes = concat_classes([
- instance.container_type,
+ self.css_class,
+ 'container-fluid',
instance.attributes.get('class'),
])
instance.attributes['class'] = classes
- return super(Bootstrap4GridContainerPlugin, self).render(
- context, instance, placeholder
- )
+ instance.attributes['data-width'] = instance.width.value
+ instance.attributes['data-spacing-vertical-external'] = instance.spacing_vertical_external.value
+ instance.attributes['data-spacing-vertical-internal'] = instance.spacing_vertical_internal.value
+ instance.attributes['data-spacing-horizontal'] = instance.spacing_horizontal.value
+ instance.attributes['data-background'] = instance.background.value
+
+ return super().render(context, instance, placeholder)
+
+ @classmethod
+ def get_child_ckeditor_body_css_class(cls, plugin: CMSPlugin) -> str:
+ plugin_model = get_plugin_model(plugin.plugin_type)
+ instance: Bootstrap4GridContainer = plugin_model.objects.get(pk=plugin.pk)
+ return f'{cls.css_class} {cls.css_class}--{instance.background.value}'
class Bootstrap4GridRowPlugin(CMSPluginBase):
@@ -66,12 +67,14 @@ class Bootstrap4GridRowPlugin(CMSPluginBase):
render_template = 'djangocms_bootstrap4/grid_row.html'
allow_children = True
child_classes = ['Bootstrap4GridColumnPlugin']
+ css_class = 'row-plugin'
fieldsets = [
(None, {
'fields': (
'create',
('vertical_alignment', 'horizontal_alignment'),
+ 'gutters_vertical',
)
}),
(_('Advanced settings'), {
@@ -102,10 +105,11 @@ def save_model(self, request, obj, form, change):
)
obj.add_child(instance=col)
- def render(self, context, instance, placeholder):
+ def render(self, context, instance: Bootstrap4GridRow, placeholder):
gutter = 'no-gutters' if instance.gutters else ''
classes = concat_classes([
'row',
+ f'{self.css_class}--gutters-vertical-{instance.gutters_vertical.value}',
instance.vertical_alignment,
instance.horizontal_alignment,
gutter,
@@ -137,9 +141,11 @@ class Bootstrap4GridColumnPlugin(CMSPluginBase):
fieldsets = [
(None, {
- 'fields': (
- ('column_type', 'column_alignment'),
- )
+ 'fields': [
+ 'column_type',
+ 'column_alignment',
+ 'horizontal_alignment',
+ ],
}),
(_('Responsive settings'), {
'fields': (
@@ -170,6 +176,7 @@ def render(self, context, instance, placeholder):
instance.column_type,
column,
instance.column_alignment,
+ instance.horizontal_alignment,
instance.attributes.get('class'),
])
instance.attributes['class'] = attr_classes
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/constants.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/constants.py
index 11220f58..c3ec699b 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_grid/constants.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/constants.py
@@ -2,7 +2,8 @@
from __future__ import unicode_literals
from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
+from enumfields import Enum
# The default grid size for Bootstrap 4 is 12. You can change this setting
@@ -14,17 +15,91 @@
12,
)
-# Bootstrap 4 provides 2 container types, .container and .container-fluid
-# https://getbootstrap.com/docs/4.0/layout/grid/#no-gutters
-GRID_CONTAINER_CHOICES = getattr(
+
+class GridContainerType(Enum):
+ DYNAMIC_WIDTH = 'container'
+ FULL_WIDTH = 'container-fluid'
+
+
+GRID_CONTAINER_TYPE: GridContainerType = getattr(
settings,
- 'DJANGOCMS_BOOTSTRAP4_GRID_CONTAINERS',
- (
- ('container', _('Container')),
- ('container-fluid', _('Fluid container')),
- ),
+ 'DJANGOCMS_BOOTSTRAP4_GRID_CONTAINER_TYPE',
+ GridContainerType,
+)
+
+
+container_fieldsets_default = [
+ (None, {
+ 'fields': (
+ 'name',
+ 'width',
+ 'background',
+ ('spacing_vertical_external', 'spacing_vertical_internal'),
+ 'spacing_horizontal',
+ ),
+ }),
+ (_('Advanced settings'), {
+ 'classes': ['collapse'],
+ 'fields': (
+ 'tag_type',
+ 'attributes',
+ ),
+ }),
+]
+
+GRID_CONTAINER_FIELDSETS = getattr(
+ settings,
+ 'DJANGOCMS_BOOTSTRAP4_GRID_CONTAINER_FIELDSETS',
+ container_fieldsets_default,
)
+
+class GridContainerWidthInternal(Enum):
+ FULL_WIDTH = 'full-width'
+
+
+GRID_CONTAINER_WIDTH_INTERNAL: GridContainerWidthInternal = getattr(
+ settings,
+ 'DJANGOCMS_BOOTSTRAP4_GRID_CONTAINER_WIDTH_INTERNAL',
+ GridContainerWidthInternal,
+)
+
+
+class GridContainerBackground(Enum):
+ NONE = 'background-none'
+
+
+GRID_CONTAINER_BACKGROUND: GridContainerBackground = getattr(
+ settings,
+ 'DJANGOCMS_BOOTSTRAP4_GRID_CONTAINER_BACKGROUND',
+ GridContainerBackground,
+)
+
+
+class GridContainerVerticalSpacingInternal(Enum):
+ NONE = 'none'
+
+
+GRID_CONTAINER_VERTICAL_SPACING_INTERNAL: GridContainerVerticalSpacingInternal = getattr(
+ settings,
+ 'DJANGOCMS_BOOTSTRAP4_GRID_CONTAINER_VERTICAL_SPACING_INTERNAL',
+ GridContainerVerticalSpacingInternal,
+)
+
+
+GRID_CONTAINER_VERTICAL_SPACING_EXTERNAL: GridContainerVerticalSpacingInternal = getattr(
+ settings,
+ 'DJANGOCMS_BOOTSTRAP4_GRID_CONTAINER_VERTICAL_SPACING_EXTERNAL',
+ GridContainerVerticalSpacingInternal,
+)
+
+GRID_CONTAINER_HORIZONTAL_SPACING: GridContainerVerticalSpacingInternal = getattr(
+ settings,
+ 'DJANGOCMS_BOOTSTRAP4_GRID_CONTAINER_HORIZONTAL_SPACING',
+ GridContainerVerticalSpacingInternal,
+)
+
+
# Options for flexbox on the alignment of the grid
# https://flexbox.webflow.com/
GRID_ROW_VERTICAL_ALIGNMENT_CHOICES = (
@@ -47,6 +122,13 @@
('align-self-end', _('Align self end')),
)
+GRID_COLUMN_HORIZONTAL_ALIGNMENT_CHOICES = (
+ ('align-items-start', _('Align items start')),
+ ('align-items-center', _('Align items center')),
+ ('align-items-end', _('Align items end')),
+ ('align-items-stretch', _('Align items stretch')),
+)
+
GRID_COLUMN_CHOICES = getattr(
settings,
'DJANGOCMS_BOOTSTRAP4_GRID_COLUMN_CHOICES',
@@ -56,3 +138,14 @@
('', _('Empty'))
),
)
+
+
+# deprecated, left only for migrations
+GRID_CONTAINER_CHOICES = getattr(
+ settings,
+ 'DJANGOCMS_BOOTSTRAP4_GRID_CONTAINERS',
+ (
+ ('container', _('Container')),
+ ('container-fluid', _('Fluid container')),
+ ),
+)
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/forms.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/forms.py
index 481dfb50..bcc95c7f 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_grid/forms.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/forms.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
from django.forms import BooleanField, IntegerField, models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from djangocms_bootstrap4.constants import DEVICE_SIZES
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0005_add_name_field_and_use_enum_for_type.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0005_add_name_field_and_use_enum_for_type.py
new file mode 100644
index 00000000..1b9c26ae
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0005_add_name_field_and_use_enum_for_type.py
@@ -0,0 +1,25 @@
+# Generated by Django 2.2.12 on 2020-05-24 02:55
+
+from django.db import migrations, models
+import djangocms_bootstrap4.contrib.bootstrap4_grid.constants
+import enumfields.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0004_remove_bootstrap4gridcolumn_column_size'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='bootstrap4gridcontainer',
+ name='name',
+ field=models.CharField(blank=True, help_text='Shown only to the admins in the structure mode for better orientation', max_length=1024, null=True),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='container_type',
+ field=enumfields.fields.EnumField(default='container', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerType, max_length=255, verbose_name='Container type'),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0006_add_fields_background_and_spacing.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0006_add_fields_background_and_spacing.py
new file mode 100644
index 00000000..884870cd
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0006_add_fields_background_and_spacing.py
@@ -0,0 +1,25 @@
+# Generated by Django 2.2.12 on 2020-05-30 13:23
+
+from django.db import migrations
+import djangocms_bootstrap4.contrib.bootstrap4_grid.constants
+import enumfields.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0005_add_name_field_and_use_enum_for_type'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='bootstrap4gridcontainer',
+ name='background',
+ field=enumfields.fields.EnumField(default='background-none', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerBackground, max_length=255, verbose_name='Background'),
+ ),
+ migrations.AddField(
+ model_name='bootstrap4gridcontainer',
+ name='spacing',
+ field=enumfields.fields.EnumField(default='none', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerVerticalSpacingInternal, max_length=255, verbose_name='Spacing'),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0007_add_field_spacing_vertical_type.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0007_add_field_spacing_vertical_type.py
new file mode 100644
index 00000000..f222a081
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0007_add_field_spacing_vertical_type.py
@@ -0,0 +1,43 @@
+from django.db import migrations
+import djangocms_bootstrap4.contrib.bootstrap4_grid.models
+import djangocms_bootstrap4.contrib.bootstrap4_grid.constants
+import enumfields.fields
+from enumfields import Enum
+
+
+class SpacingVerticalType(Enum):
+ """
+ for backward migration compatibility
+ """
+ MARGIN = 'margin'
+ PADDING = 'padding'
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0006_add_fields_background_and_spacing'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='bootstrap4gridcontainer',
+ name='spacing_vertical_type',
+ field=enumfields.fields.EnumField(default='margin', enum=SpacingVerticalType, max_length=255, verbose_name='Vertical spacing type'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='background',
+ field=enumfields.fields.EnumField(default='background-none', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerBackground, max_length=255, verbose_name='Background'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='container_type',
+ field=enumfields.fields.EnumField(default='container', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerType, max_length=255, verbose_name='Container width'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='spacing',
+ field=enumfields.fields.EnumField(default='none', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerVerticalSpacingInternal, max_length=255, verbose_name='Vertical spacing'),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0008_rename_spacing_to_spacing_vertical.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0008_rename_spacing_to_spacing_vertical.py
new file mode 100644
index 00000000..5d88a808
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0008_rename_spacing_to_spacing_vertical.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.13 on 2020-06-10 11:29
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0007_add_field_spacing_vertical_type'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='bootstrap4gridcontainer',
+ old_name='spacing',
+ new_name='spacing_vertical',
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0009_add_fields_gutters.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0009_add_fields_gutters.py
new file mode 100644
index 00000000..a3c34c47
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0009_add_fields_gutters.py
@@ -0,0 +1,23 @@
+from django.db import migrations
+import djangocms_bootstrap4.contrib.bootstrap4_grid.models
+import enumfields.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0008_rename_spacing_to_spacing_vertical'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='bootstrap4gridrow',
+ name='gutters_horizontal',
+ field=enumfields.fields.EnumField(default='normal', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.models.GuttersHorizontal, max_length=32),
+ ),
+ migrations.AddField(
+ model_name='bootstrap4gridrow',
+ name='gutters_vertical',
+ field=enumfields.fields.EnumField(default='none', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.models.GuttersVertical, max_length=32),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0010_drop_field_spacing_vertical_type.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0010_drop_field_spacing_vertical_type.py
new file mode 100644
index 00000000..e75bb55b
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0010_drop_field_spacing_vertical_type.py
@@ -0,0 +1,15 @@
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0009_add_fields_gutters'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='bootstrap4gridcontainer',
+ name='spacing_vertical_type',
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0011_drop_field_spacing_horizontal.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0011_drop_field_spacing_horizontal.py
new file mode 100644
index 00000000..540e971f
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0011_drop_field_spacing_horizontal.py
@@ -0,0 +1,20 @@
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0010_drop_field_spacing_vertical_type'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='bootstrap4gridrow',
+ name='gutters_horizontal',
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridrow',
+ name='gutters',
+ field=models.BooleanField(default=False, help_text='Removes the horizontal spacing between the columns.', verbose_name='Remove gutters'),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0012_add_field_width_internal.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0012_add_field_width_internal.py
new file mode 100644
index 00000000..2cb999d7
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0012_add_field_width_internal.py
@@ -0,0 +1,36 @@
+# Generated by Django 2.2.13 on 2020-06-15 18:29
+
+from django.db import migrations
+import djangocms_bootstrap4.contrib.bootstrap4_grid.constants
+import djangocms_bootstrap4.contrib.bootstrap4_grid.models
+import enumfields.fields
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ('bootstrap4_grid', '0011_drop_field_spacing_horizontal'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='bootstrap4gridcontainer',
+ name='width_internal',
+ field=enumfields.fields.EnumField(
+ default='full-width',
+ enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerWidthInternal,
+ help_text='You can change it eg if you want to have a full-width gray background, but a limited content width within that background',
+ max_length=255,
+ verbose_name='Internal width',
+ ),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='container_type',
+ field=enumfields.fields.EnumField(
+ default='container',
+ enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerType,
+ max_length=255,
+ verbose_name='External width',
+ ),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0013_alter_field_container_type_with_new_default.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0013_alter_field_container_type_with_new_default.py
new file mode 100644
index 00000000..faea907c
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0013_alter_field_container_type_with_new_default.py
@@ -0,0 +1,19 @@
+from django.db import migrations
+import djangocms_bootstrap4.contrib.bootstrap4_grid.models
+import djangocms_bootstrap4.contrib.bootstrap4_grid.constants
+import enumfields.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0012_add_field_width_internal'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='container_type',
+ field=enumfields.fields.EnumField(default='container-fluid', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerType, max_length=255, verbose_name='External width'),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0014_add_field_horizontal_alignment_to_column.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0014_add_field_horizontal_alignment_to_column.py
new file mode 100644
index 00000000..f5c2a2b7
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0014_add_field_horizontal_alignment_to_column.py
@@ -0,0 +1,37 @@
+# Generated by Django 2.2.14 on 2020-08-02 09:11
+
+from django.db import migrations, models
+import djangocms_bootstrap4.contrib.bootstrap4_grid.models
+import enumfields.fields
+import djangocms_bootstrap4.contrib.bootstrap4_grid.constants
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0013_alter_field_container_type_with_new_default'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='bootstrap4gridcolumn',
+ name='horizontal_alignment',
+ field=models.CharField(choices=[('align-items-start', 'Align items start'), ('align-items-center', 'Align items center'), ('align-items-end', 'Align items end'), ('align-items-stretch', 'Align items stretch')], default='align-items-start', help_text='Read more in the documentation.', max_length=255, verbose_name='Horizontal alignment'),
+ preserve_default=False,
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='spacing_vertical',
+ field=enumfields.fields.EnumField(default='none', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerVerticalSpacingInternal, max_length=255, verbose_name='Vertical spacing'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='width_internal',
+ field=enumfields.fields.EnumField(default='full-width', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerWidthInternal, max_length=255, verbose_name='Internal content width'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridrow',
+ name='gutters_vertical',
+ field=enumfields.fields.EnumField(default='none', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.models.GuttersVertical, help_text='Vertical spacing between the columns inside', max_length=32),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0015_alter_metadata.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0015_alter_metadata.py
new file mode 100644
index 00000000..c3ca7c47
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0015_alter_metadata.py
@@ -0,0 +1,23 @@
+# Generated by Django 2.2.14 on 2020-08-02 09:15
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0014_add_field_horizontal_alignment_to_column'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='bootstrap4gridcolumn',
+ name='column_alignment',
+ field=models.CharField(blank=True, choices=[('align-self-start', 'Align self start'), ('align-self-center', 'Align self center'), ('align-self-end', 'Align self end')], max_length=255, verbose_name='Vertical alignment'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcolumn',
+ name='horizontal_alignment',
+ field=models.CharField(choices=[('align-items-start', 'Align items start'), ('align-items-center', 'Align items center'), ('align-items-end', 'Align items end'), ('align-items-stretch', 'Align items stretch')], max_length=255, verbose_name='Horizontal alignment'),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0016_rename_fields_spacing_vertical_and_width_internal.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0016_rename_fields_spacing_vertical_and_width_internal.py
new file mode 100644
index 00000000..cdd61cdb
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0016_rename_fields_spacing_vertical_and_width_internal.py
@@ -0,0 +1,25 @@
+# Generated by Django 3.1.4 on 2021-01-20 20:58
+
+from django.db import migrations
+import djangocms_bootstrap4.contrib.bootstrap4_grid.constants
+import enumfields.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0015_alter_metadata'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='bootstrap4gridcontainer',
+ old_name='spacing_vertical',
+ new_name='spacing_vertical_external',
+ ),
+ migrations.RenameField(
+ model_name='bootstrap4gridcontainer',
+ old_name='width_internal',
+ new_name='width',
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0017_add_fields_for_spacing.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0017_add_fields_for_spacing.py
new file mode 100644
index 00000000..e8ea5bd2
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0017_add_fields_for_spacing.py
@@ -0,0 +1,35 @@
+# Generated by Django 3.1.4 on 2021-01-20 21:08
+
+from django.db import migrations
+import djangocms_bootstrap4.contrib.bootstrap4_grid.constants
+import enumfields.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0016_rename_fields_spacing_vertical_and_width_internal'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='bootstrap4gridcontainer',
+ name='spacing_horizontal',
+ field=enumfields.fields.EnumField(default='none', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerVerticalSpacingInternal, max_length=255, verbose_name='Horizontal spacing (padding)'),
+ ),
+ migrations.AddField(
+ model_name='bootstrap4gridcontainer',
+ name='spacing_vertical_internal',
+ field=enumfields.fields.EnumField(default='none', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerVerticalSpacingInternal, max_length=255, verbose_name='Vertical internal spacing'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='spacing_vertical_external',
+ field=enumfields.fields.EnumField(default='none', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerVerticalSpacingInternal, max_length=255, verbose_name='Vertical external spacing'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='width',
+ field=enumfields.fields.EnumField(default='full-width', enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerWidthInternal, max_length=255, verbose_name='Width'),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0018_auto_20210719_2034.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0018_auto_20210719_2034.py
new file mode 100644
index 00000000..e3c4bc32
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0018_auto_20210719_2034.py
@@ -0,0 +1,45 @@
+# Generated by Django 3.1.4 on 2021-07-19 18:34
+
+import backend.settings
+from django.db import migrations, models
+import enumfields.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bootstrap4_grid', '0017_add_fields_for_spacing'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='bootstrap4gridcolumn',
+ name='horizontal_alignment',
+ field=models.CharField(choices=[('align-items-start', 'Align items start'), ('align-items-center', 'Align items center'), ('align-items-end', 'Align items end'), ('align-items-stretch', 'Align items stretch')], default='align-items-start', max_length=255, verbose_name='Horizontal alignment'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='background',
+ field=enumfields.fields.EnumField(default='background-none', enum=backend.settings.GridContainerBackground, max_length=255, verbose_name='Background'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='container_type',
+ field=enumfields.fields.EnumField(default='container-fluid', enum=backend.settings.GridContainerType, max_length=255, verbose_name='External width'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='spacing_vertical_external',
+ field=enumfields.fields.EnumField(default='spacing-none', enum=backend.settings.GridContainerSpacing, max_length=255, verbose_name='Vertical external spacing'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='spacing_vertical_internal',
+ field=enumfields.fields.EnumField(default='none', enum=backend.settings.GridVerticalContainerSpacing, max_length=255, verbose_name='Vertical internal spacing'),
+ ),
+ migrations.AlterField(
+ model_name='bootstrap4gridcontainer',
+ name='width',
+ field=enumfields.fields.EnumField(default='full-width', enum=backend.settings.GridContainerWidthInternal, max_length=255, verbose_name='Width'),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0019_alter_bootstrap4gridcolumn_cmsplugin_ptr_and_more.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0019_alter_bootstrap4gridcolumn_cmsplugin_ptr_and_more.py
new file mode 100644
index 00000000..1c72c986
--- /dev/null
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/migrations/0019_alter_bootstrap4gridcolumn_cmsplugin_ptr_and_more.py
@@ -0,0 +1,96 @@
+# Generated by Django 4.2.4 on 2023-08-20 15:56
+
+from django.db import migrations, models
+import django.db.models.deletion
+import djangocms_bootstrap4.contrib.bootstrap4_grid.constants
+import enumfields.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("cms", "0022_auto_20180620_1551"),
+ ("bootstrap4_grid", "0018_auto_20210719_2034"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="bootstrap4gridcolumn",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="bootstrap4gridcontainer",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="bootstrap4gridcontainer",
+ name="container_type",
+ field=enumfields.fields.EnumField(
+ default="container-fluid",
+ enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerType,
+ max_length=255,
+ verbose_name="External width",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="bootstrap4gridcontainer",
+ name="spacing_vertical_external",
+ field=enumfields.fields.EnumField(
+ default="none",
+ enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerVerticalSpacingInternal,
+ max_length=255,
+ verbose_name="Vertical external spacing",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="bootstrap4gridcontainer",
+ name="spacing_vertical_internal",
+ field=enumfields.fields.EnumField(
+ default="none",
+ enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerVerticalSpacingInternal,
+ max_length=255,
+ verbose_name="Vertical internal spacing",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="bootstrap4gridcontainer",
+ name="width",
+ field=enumfields.fields.EnumField(
+ default="full-width",
+ enum=djangocms_bootstrap4.contrib.bootstrap4_grid.constants.GridContainerWidthInternal,
+ max_length=255,
+ verbose_name="Width",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="bootstrap4gridrow",
+ name="cmsplugin_ptr",
+ field=models.OneToOneField(
+ auto_created=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True,
+ primary_key=True,
+ related_name="%(app_label)s_%(class)s",
+ serialize=False,
+ to="cms.cmsplugin",
+ ),
+ ),
+ ]
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/models.py b/djangocms_bootstrap4/contrib/bootstrap4_grid/models.py
index 57fd6366..b34e740a 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_grid/models.py
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/models.py
@@ -1,27 +1,30 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
from functools import partial
-from django.db import models
-from django.utils.translation import ugettext_lazy as _
-from django.utils.translation import ungettext
-
from cms.models import CMSPlugin
-
+from django.db import models
+from django.utils.translation import gettext_lazy as _
+from django.utils.translation import gettext
+from enumfields import Enum
+from enumfields import EnumField
from six import python_2_unicode_compatible
from djangocms_bootstrap4.constants import DEVICE_SIZES
-from djangocms_bootstrap4.fields import (
- AttributesField, IntegerRangeField, TagTypeField,
-)
+from djangocms_bootstrap4.fields import AttributesField
+from djangocms_bootstrap4.fields import IntegerRangeField
+from djangocms_bootstrap4.fields import TagTypeField
from djangocms_bootstrap4.helpers import mark_safe_lazy
-
-from .constants import (
- GRID_COLUMN_ALIGNMENT_CHOICES, GRID_COLUMN_CHOICES, GRID_CONTAINER_CHOICES,
- GRID_ROW_HORIZONTAL_ALIGNMENT_CHOICES, GRID_ROW_VERTICAL_ALIGNMENT_CHOICES,
- GRID_SIZE,
-)
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_COLUMN_HORIZONTAL_ALIGNMENT_CHOICES
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_COLUMN_ALIGNMENT_CHOICES
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_COLUMN_CHOICES
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_CONTAINER_BACKGROUND
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_CONTAINER_HORIZONTAL_SPACING
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_CONTAINER_VERTICAL_SPACING_INTERNAL
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_CONTAINER_VERTICAL_SPACING_EXTERNAL
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_CONTAINER_TYPE
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_CONTAINER_WIDTH_INTERNAL
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_ROW_HORIZONTAL_ALIGNMENT_CHOICES
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_ROW_VERTICAL_ALIGNMENT_CHOICES
+from djangocms_bootstrap4.contrib.bootstrap4_grid.constants import GRID_SIZE
@python_2_unicode_compatible
@@ -30,31 +33,89 @@ class Bootstrap4GridContainer(CMSPlugin):
Layout > Grid: "Container" Plugin
https://getbootstrap.com/docs/4.0/layout/grid/
"""
- container_type = models.CharField(
- verbose_name=_('Container type'),
- choices=GRID_CONTAINER_CHOICES,
- default=GRID_CONTAINER_CHOICES[0][0],
+ name = models.CharField(
+ max_length=1024,
+ null=True, blank=True,
+ help_text=_('Shown only to the admins in the structure mode for better orientation'),
+ )
+ container_type = EnumField(
+ GRID_CONTAINER_TYPE,
+ default=GRID_CONTAINER_TYPE.FULL_WIDTH,
+ verbose_name=_('External width'),
+ max_length=255,
+ )
+ width = EnumField(
+ GRID_CONTAINER_WIDTH_INTERNAL,
+ default=GRID_CONTAINER_WIDTH_INTERNAL.FULL_WIDTH,
+ verbose_name=_('Width'),
+ max_length=255,
+ )
+ background = EnumField(
+ GRID_CONTAINER_BACKGROUND,
+ default=GRID_CONTAINER_BACKGROUND.NONE,
+ verbose_name=_('Background'),
+ max_length=255,
+ )
+ spacing_vertical_external = EnumField(
+ GRID_CONTAINER_VERTICAL_SPACING_EXTERNAL,
+ default=GRID_CONTAINER_VERTICAL_SPACING_EXTERNAL.NONE,
+ verbose_name=_('Vertical external spacing'),
+ max_length=255,
+ )
+ spacing_vertical_internal = EnumField(
+ GRID_CONTAINER_VERTICAL_SPACING_INTERNAL,
+ default=GRID_CONTAINER_VERTICAL_SPACING_INTERNAL.NONE,
+ verbose_name=_('Vertical internal spacing'),
+ max_length=255,
+ )
+ spacing_horizontal = EnumField(
+ GRID_CONTAINER_HORIZONTAL_SPACING,
+ default=GRID_CONTAINER_HORIZONTAL_SPACING.NONE,
+ verbose_name=_('Horizontal spacing (padding)'),
max_length=255,
- help_text=mark_safe_lazy(_(
- 'Defines if the grid should use fixed width (.container) '
- 'or fluid width (.container-fluid).'
- )),
)
tag_type = TagTypeField()
attributes = AttributesField()
- def __str__(self):
+ def __str__(self) -> str:
return str(self.pk)
- def get_short_description(self):
- text = ''
- for item in GRID_CONTAINER_CHOICES:
- if item[0] == self.container_type:
- text = item[1]
- return '({})'.format(text)
+ def get_short_description(self) -> str:
+ desc: str = ''
+ if self.name:
+ desc += f'{self.name} '
+
+ is_width_selected = self.width != self._meta.get_field('width').get_default()
+ is_background_selected = self.background != self._meta.get_field('background').get_default()
+ if is_background_selected or is_width_selected:
+ desc += '['
+ if is_background_selected and is_width_selected:
+ desc += f'{self.background}, {self.width}'
+ elif is_background_selected:
+ desc += str(self.background)
+ elif is_width_selected:
+ desc += str(self.width)
+ desc += ']'
+
+ return desc
+
+
+class GuttersVertical(Enum):
+ NONE = 'none'
+ SMALL = 'small'
+ NORMAL = 'normal'
+ LARGE = 'large'
+ EXTRA_LARGE = 'extra_large'
+
+
+class GuttersHorizontal(Enum):
+ NONE = 'none'
+ SMALL = 'small'
+ NORMAL = 'normal'
+ LARGE = 'large'
+ EXTRA_LARGE = 'extra_large'
-@python_2_unicode_compatible
class Bootstrap4GridRow(CMSPlugin):
"""
Layout > Grid: "Row" Plugin
@@ -80,10 +141,16 @@ class Bootstrap4GridRow(CMSPlugin):
.format(link='https://getbootstrap.com/docs/4.0/layout/grid/#horizontal-alignment')
),
)
+ gutters_vertical = EnumField(
+ GuttersVertical,
+ default=GuttersVertical.NONE,
+ max_length=32,
+ help_text=_("Vertical spacing between the columns inside"),
+ )
gutters = models.BooleanField(
verbose_name=_('Remove gutters'),
default=False,
- help_text=_('Removes the marginal gutters from the grid.'),
+ help_text=_('Removes the horizontal spacing between the columns.'),
)
tag_type = TagTypeField()
attributes = AttributesField()
@@ -93,7 +160,7 @@ def __str__(self):
def get_short_description(self):
column_count = len(self.child_plugin_instances or [])
- column_count_str = ungettext(
+ column_count_str = gettext(
'(1 column)',
'(%(count)i columns)',
column_count
@@ -116,11 +183,17 @@ class Bootstrap4GridColumn(CMSPlugin):
max_length=255,
)
column_alignment = models.CharField(
- verbose_name=_('Alignment'),
+ verbose_name=_('Vertical alignment'),
choices=GRID_COLUMN_ALIGNMENT_CHOICES,
blank=True,
max_length=255,
)
+ horizontal_alignment = models.CharField(
+ verbose_name=_('Horizontal alignment'),
+ choices=GRID_COLUMN_HORIZONTAL_ALIGNMENT_CHOICES,
+ default=GRID_COLUMN_HORIZONTAL_ALIGNMENT_CHOICES[0][0],
+ max_length=255,
+ )
tag_type = TagTypeField()
attributes = AttributesField()
diff --git a/djangocms_bootstrap4/contrib/bootstrap4_grid/templates/djangocms_bootstrap4/grid_container.html b/djangocms_bootstrap4/contrib/bootstrap4_grid/templates/djangocms_bootstrap4/grid_container.html
index a490dfc9..0abd2f09 100644
--- a/djangocms_bootstrap4/contrib/bootstrap4_grid/templates/djangocms_bootstrap4/grid_container.html
+++ b/djangocms_bootstrap4/contrib/bootstrap4_grid/templates/djangocms_bootstrap4/grid_container.html
@@ -1,7 +1,9 @@
{% load cms_tags %}
<{{ instance.tag_type }} {{ instance.attributes_str }}>
- {% for plugin in instance.child_plugin_instances %}
- {% with forloop as parentloop %}{% render_plugin plugin %}{% endwith %}
- {% endfor %}
+
=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-i-u-a-.5))||0),u}function getWidthOrHeight(e,t,n){var r=pe(e),o=!y.boxSizingReliable()||n,i=o&&"border-box"===T.css(e,"boxSizing",!1,r),s=i,a=curCSS(e,t,r),u="offset"+t[0].toUpperCase()+t.slice(1);if(fe.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||"auto"===a||!parseFloat(a)&&"inline"===T.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===T.css(e,"boxSizing",!1,r),(s=u in e)&&(a=e[u])),(a=parseFloat(a)||0)+boxModelAdjustment(e,t,n||(i?"border":"content"),s,r,a)+"px"}function Tween(e,t,n,r,o){return new Tween.prototype.init(e,t,n,r,o)}function schedule(){Te&&(!1===a.hidden&&n.requestAnimationFrame?n.requestAnimationFrame(schedule):n.setTimeout(schedule,T.fx.interval),T.fx.tick())}function createFxNow(){return n.setTimeout(function(){we=void 0}),we=Date.now()}function genFx(e,t){var n,r=0,o={height:e};for(t=t?1:0;r<4;r+=2-t)n=V[r],o["margin"+n]=o["padding"+n]=e;return t&&(o.opacity=o.width=e),o}function createTween(e,t,n){for(var r,o=(Animation.tweeners[t]||[]).concat(Animation.tweeners["*"]),i=0,s=o.length;i=0&&n","
"],col:[2,"
"],tr:[2,"","
"],td:[3,"
"],_default:[0,"",""]};ne.optgroup=ne.option,ne.tbody=ne.tfoot=ne.colgroup=ne.caption=ne.thead,ne.th=ne.td;var re=/<|?\w+;/;!function(){var e=a.createDocumentFragment(),t=e.appendChild(a.createElement("div")),n=a.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),y.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="",y.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var oe=/^key/,ie=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,se=/^([^.]*)(?:\.(.+)|)/;T.event={global:{},add:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,d,h,v,g=R.get(e);if(g)for(n.handler&&(i=n,n=i.handler,o=i.selector),o&&T.find.matchesSelector(U,o),n.guid||(n.guid=T.guid++),(u=g.events)||(u=g.events={}),(s=g.handle)||(s=g.handle=function(t){return void 0!==T&&T.event.triggered!==t.type?T.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(P)||[""],c=t.length;c--;)a=se.exec(t[c])||[],d=v=a[1],h=(a[2]||"").split(".").sort(),d&&(f=T.event.special[d]||{},d=(o?f.delegateType:f.bindType)||d,f=T.event.special[d]||{},l=T.extend({type:d,origType:v,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&T.expr.match.needsContext.test(o),namespace:h.join(".")},i),(p=u[d])||(p=u[d]=[],p.delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,s)||e.addEventListener&&e.addEventListener(d,s)),f.add&&(f.add.call(e,l),l.handler.guid||(l.handler.guid=n.guid)),o?p.splice(p.delegateCount++,0,l):p.push(l),T.event.global[d]=!0)},remove:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,d,h,v,g=R.hasData(e)&&R.get(e);if(g&&(u=g.events)){for(t=(t||"").match(P)||[""],c=t.length;c--;)if(a=se.exec(t[c])||[],d=v=a[1],h=(a[2]||"").split(".").sort(),d){for(f=T.event.special[d]||{},d=(r?f.delegateType:f.bindType)||d,p=u[d]||[],a=a[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=i=p.length;i--;)l=p[i],!o&&v!==l.origType||n&&n.guid!==l.guid||a&&!a.test(l.namespace)||r&&r!==l.selector&&("**"!==r||!l.selector)||(p.splice(i,1),l.selector&&p.delegateCount--,f.remove&&f.remove.call(e,l));s&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,g.handle)||T.removeEvent(e,d,g.handle),delete u[d])}else for(d in u)T.event.remove(e,d+t[c],n,r,!0);T.isEmptyObject(u)&&R.remove(e,"handle events")}},dispatch:function(e){var t,n,r,o,i,s,a=T.event.fix(e),u=new Array(arguments.length),c=(R.get(this,"events")||{})[a.type]||[],l=T.event.special[a.type]||{};for(u[0]=a,t=1;t","