From 8b343315228cf7bef4ed087234b6d50e2744e178 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Fri, 23 Jul 2021 14:31:05 +0200
Subject: [PATCH 5/5] general: allow custom cell templates to define extra
 classes (#55792)

---
 combo/data/models.py | 14 +++++++++++++-
 tests/test_cells.py  |  9 ++++++++-
 tests/test_public.py | 18 +++++++++++-------
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/combo/data/models.py b/combo/data/models.py
index 7aa6a507..0864ac9f 100644
--- a/combo/data/models.py
+++ b/combo/data/models.py
@@ -772,7 +772,14 @@ class CellBase(six.with_metaclass(CellMeta, models.Model)):
 
     @property
     def css_class_names(self):
-        return ' '.join([self.class_name, self.legacy_class_name, self.extra_css_class])
+        return ' '.join(
+            [
+                self.class_name,
+                self.legacy_class_name,
+                self.get_template_extra_css_classes(),
+                self.extra_css_class,
+            ]
+        )
 
     @property
     def asset_css_classes(self):
@@ -1129,6 +1136,11 @@ class CellBase(six.with_metaclass(CellMeta, models.Model)):
         selected_template_infos = cell_templates.get(self.template_name) or {}
         return selected_template_infos.get('label')
 
+    def get_template_extra_css_classes(self):
+        cell_templates = settings.COMBO_CELL_TEMPLATES.get(self.get_cell_type_str()) or {}
+        selected_template_infos = cell_templates.get(self.template_name) or {}
+        return selected_template_infos.get('extra-css-classes') or ''
+
     def render(self, context):
         context.update(self.get_cell_extra_context(context))
         template_names = ['combo/' + self._meta.model_name + '.html']
diff --git a/tests/test_cells.py b/tests/test_cells.py
index 2b8827ee..cd1792d4 100644
--- a/tests/test_cells.py
+++ b/tests/test_cells.py
@@ -437,7 +437,13 @@ def test_extra_template():
     templates_settings[0]['DIRS'] = ['%s/templates-1' % os.path.abspath(os.path.dirname(__file__))]
     with override_settings(
         COMBO_CELL_TEMPLATES={
-            'data_textcell': {'extra': {'label': 'Extra', 'template': 'combo/cells/foobar/text-cell.html'}}
+            'data_textcell': {
+                'extra': {
+                    'label': 'Extra',
+                    'template': 'combo/cells/foobar/text-cell.html',
+                    'extra-css-classes': 'plop',
+                }
+            }
         },
         TEMPLATES=templates_settings,
     ):
@@ -445,6 +451,7 @@ def test_extra_template():
         cell.template_name = 'extra'
         cell.save()
         assert cell.render(ctx).strip() == '<div class="XXX"><p>foobar</p></div>'
+        assert 'plop' in cell.css_class_names
 
 
 def mocked_request(*args, **kwargs):
diff --git a/tests/test_public.py b/tests/test_public.py
index 2f4f9f0c..be5dd584 100644
--- a/tests/test_public.py
+++ b/tests/test_public.py
@@ -1185,19 +1185,21 @@ def test_cell_asset_css_classes(settings, app, admin_user):
     assert cell.asset_css_classes == ''
     # and test asset preload
     resp = app.get('/', status=200)
-    assert 'class="cell text-cell textcell   foo"' in resp.text
+    assert 'class="cell text-cell textcell foo"' in re.sub(r' +', ' ', resp.text)
 
     settings.COMBO_CELL_ASSET_SLOTS = {'data_textcell': {'picture': {'prefix': 'Picture'}}}
     cell = TextCell.objects.get(pk=cell.pk)
     assert cell.asset_css_classes == ''
     resp = app.get('/', status=200)
-    assert 'class="cell text-cell textcell   foo"' in resp.text
+    assert 'class="cell text-cell textcell foo"' in re.sub(r' +', ' ', resp.text)
 
     Asset.objects.create(key=cell.get_asset_slot_key('picture'), asset=File(StringIO('test'), 'test.png'))
     cell = TextCell.objects.get(pk=cell.pk)
     assert cell.asset_css_classes == 'has-asset-picture has-any-asset has-all-assets'
     resp = app.get('/', status=200)
-    assert 'class="cell text-cell textcell  has-asset-picture has-any-asset has-all-assets foo"' in resp.text
+    assert 'class="cell text-cell textcell has-asset-picture has-any-asset has-all-assets foo"' in re.sub(
+        r' +', ' ', resp.text
+    )
 
     settings.COMBO_CELL_ASSET_SLOTS = {
         'data_textcell': {'picture': {'prefix': 'Picture'}, 'foo': {'prefix': 'Foo'}}
@@ -1205,19 +1207,21 @@ def test_cell_asset_css_classes(settings, app, admin_user):
     cell = TextCell.objects.get(pk=cell.pk)
     assert cell.asset_css_classes == 'has-asset-picture has-any-asset'
     resp = app.get('/', status=200)
-    assert 'class="cell text-cell textcell  has-asset-picture has-any-asset foo"' in resp.text
+    assert 'class="cell text-cell textcell has-asset-picture has-any-asset foo"' in re.sub(
+        r' +', ' ', resp.text
+    )
 
     Asset.objects.create(key=cell.get_asset_slot_key('foo'), asset=File(StringIO('test'), 'test.png'))
     cell = TextCell.objects.get(pk=cell.pk)
     assert cell.asset_css_classes == 'has-asset-foo has-asset-picture has-any-asset has-all-assets'
     resp = app.get('/', status=200)
     assert (
-        'class="cell text-cell textcell  has-asset-foo has-asset-picture has-any-asset has-all-assets foo"'
-        in resp.text
+        'class="cell text-cell textcell has-asset-foo has-asset-picture has-any-asset has-all-assets foo"'
+        in re.sub(r' +', ' ', resp.text)
     )
 
     Asset.objects.all().delete()
     cell = TextCell.objects.get(pk=cell.pk)
     assert cell.asset_css_classes == ''
     resp = app.get('/', status=200)
-    assert 'class="cell text-cell textcell   foo"' in resp.text
+    assert 'class="cell text-cell textcell foo"' in re.sub(r' +', ' ', resp.text)
-- 
2.32.0

