Skip to content

Commit a5c4243

Browse files
committed
offcanvas with diferent row types and a small example content
1 parent 756acce commit a5c4243

File tree

6 files changed

+147
-10
lines changed

6 files changed

+147
-10
lines changed

src/cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ class IRowTypeFieldsSchema(Interface):
4242
default=False,
4343
)
4444

45+
row_type_icon = schema.TextLine(
46+
title=_("Row type icon"),
47+
description=_("Icon for the row type"),
48+
required=True,
49+
default="bricks",
50+
)
51+
4552

4653
class IRowWidthSchema(Interface):
4754
row_width_label = schema.TextLine(
@@ -76,6 +83,7 @@ class IDynamicPagesControlPanel(Interface):
7683
"IExtraClass.extra_class",
7784
],
7885
"row_type_has_featured_add_button": False,
86+
"row_type_icon": "fonts",
7987
},
8088
{
8189
"row_type": "cs_dynamicpages-featured-view",
@@ -90,6 +98,7 @@ class IDynamicPagesControlPanel(Interface):
9098
"ILinkInfo.link_url",
9199
],
92100
"row_type_has_featured_add_button": False,
101+
"row_type_icon": "card-image",
93102
},
94103
{
95104
"row_type": "cs_dynamicpages-featured-overlay-view",
@@ -99,11 +108,11 @@ class IDynamicPagesControlPanel(Interface):
99108
"IRowWidth.width",
100109
"IExtraClass.extra_class",
101110
"IRelatedImage.related_image",
102-
"IRelatedImage.image_position",
103111
"ILinkInfo.link_text",
104112
"ILinkInfo.link_url",
105113
],
106114
"row_type_has_featured_add_button": False,
115+
"row_type_icon": "image-fill",
107116
},
108117
{
109118
"row_type": "cs_dynamicpages-horizontal-rule-view",
@@ -113,6 +122,7 @@ class IDynamicPagesControlPanel(Interface):
113122
"IExtraClass.extra_class",
114123
],
115124
"row_type_has_featured_add_button": False,
125+
"row_type_icon": "hr",
116126
},
117127
{
118128
"row_type": "cs_dynamicpages-spacer-view",
@@ -121,6 +131,7 @@ class IDynamicPagesControlPanel(Interface):
121131
"IExtraClass.extra_class",
122132
],
123133
"row_type_has_featured_add_button": False,
134+
"row_type_icon": "arrows-vertical",
124135
},
125136
{
126137
"row_type": "cs_dynamicpages-slider-view",
@@ -130,6 +141,7 @@ class IDynamicPagesControlPanel(Interface):
130141
"IExtraClass.extra_class",
131142
],
132143
"row_type_has_featured_add_button": True,
144+
"row_type_icon": "images",
133145
},
134146
{
135147
"row_type": "cs_dynamicpages-features-view",
@@ -139,6 +151,7 @@ class IDynamicPagesControlPanel(Interface):
139151
"IExtraClass.extra_class",
140152
],
141153
"row_type_has_featured_add_button": True,
154+
"row_type_icon": "grid",
142155
},
143156
{
144157
"row_type": "cs_dynamicpages-accordion-view",
@@ -148,6 +161,7 @@ class IDynamicPagesControlPanel(Interface):
148161
"IExtraClass.extra_class",
149162
],
150163
"row_type_has_featured_add_button": True,
164+
"row_type_icon": "chevron-double-down",
151165
},
152166
{
153167
"row_type": "cs_dynamicpages-query-columns-view",
@@ -163,6 +177,7 @@ class IDynamicPagesControlPanel(Interface):
163177
"IRowColumns.columns",
164178
],
165179
"row_type_has_featured_add_button": False,
180+
"row_type_icon": "funnel",
166181
},
167182
{
168183
"row_type": "cs_dynamicpages-text-view",
@@ -173,6 +188,7 @@ class IDynamicPagesControlPanel(Interface):
173188
"IRichTextBehavior-text",
174189
],
175190
"row_type_has_featured_add_button": False,
191+
"row_type_icon": "body-text",
176192
},
177193
],
178194
)

src/cs_dynamicpages/utils.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
from cs_dynamicpages import logger
22
from plone import api
3+
from zope.component import getSiteManager
4+
from zope.globalrequest import getRequest
5+
from zope.interface import Interface
6+
from cs_dynamicpages.content.dynamic_page_row import IDynamicPageRow
7+
from zope.interface import providedBy
8+
9+
VIEW_PREFIX = "cs_dynamicpages-"
310

411

512
def add_custom_view(view_name: str, shown_fields: list[str], has_button: bool = False):
@@ -48,3 +55,25 @@ def enable_behavior(behavior_dotted_name=str):
4855
print(
4956
f"Behavior '{behavior_dotted_name}' is already enabled on 'DynamicPageRow'."
5057
)
58+
59+
def get_available_views_for_row():
60+
items = []
61+
sm = getSiteManager()
62+
63+
available_views = sm.adapters.lookupAll(
64+
required=(IDynamicPageRow, providedBy(getRequest())),
65+
provided=Interface,
66+
)
67+
68+
values = api.portal.get_registry_record(
69+
"cs_dynamicpages.dynamic_pages_control_panel.row_type_fields", default=[]
70+
)
71+
72+
for item in available_views:
73+
if item[0].startswith(VIEW_PREFIX):
74+
for value in values:
75+
item_dict = {"row_type": item[0], "each_row_type_fields": [], "row_type_has_featured_add_button": False, "row_type_icon": "bricks"}
76+
if item[0] == value["row_type"] and value not in items:
77+
item_dict = value
78+
items.append(item_dict)
79+
return items

src/cs_dynamicpages/views/configure.zcml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828
title="Dynamic view"
2929
/>
3030

31+
<browser:page
32+
name="add-row-content"
33+
for="cs_dynamicpages.content.dynamic_page_folder.IDynamicPageFolder"
34+
class=".dynamic_page_folder_view.DynamicPageAddRowContentView"
35+
permission="cmf.AddPortalContent"
36+
layer="cs_dynamicpages.interfaces.IBrowserLayer"
37+
/>
38+
3139
<browser:page
3240
name="dynamic-view"
3341
for="plone.app.contenttypes.interfaces.IFolder"

src/cs_dynamicpages/views/dynamic_page_folder_view.py

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
from Products.Five.browser import BrowserView
33
from zope.interface import implementer
44
from zope.interface import Interface
5-
6-
5+
from plone import api
6+
from plone.protect.interfaces import IDisableCSRFProtection
7+
from uuid import uuid4
8+
from zope.interface import alsoProvides
79
# from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
8-
10+
from cs_dynamicpages.utils import get_available_views_for_row
11+
from cs_dynamicpages import _
912

1013
class IDynamicPageFolderView(Interface):
1114
"""Marker Interface for IDynamicPageFolderView"""
@@ -20,3 +23,57 @@ class DynamicPageFolderView(BrowserView):
2023
def __call__(self):
2124
# Implement your own actions:
2225
return self.index()
26+
27+
28+
@implementer(IDynamicPageFolderView)
29+
class DynamicPageAddRowContentView(BrowserView):
30+
# If you want to define a template here, please remove the template from
31+
# the configure.zcml registration of this view.
32+
# template = ViewPageTemplateFile('dynamic_page_folder_view.pt')
33+
34+
def __call__(self):
35+
# Implement your own actions:
36+
row_type = self.request.get("row_type")
37+
if row_type:
38+
random_id = uuid4()
39+
40+
alsoProvides(self.request, IDisableCSRFProtection)
41+
api.content.create(
42+
type="DynamicPageRow",
43+
container=self.context,
44+
row_type=row_type,
45+
title="New Row",
46+
id=str(random_id)
47+
)
48+
available_views = get_available_views_for_row()
49+
for view in available_views:
50+
if view["row_type"] == row_type:
51+
has_featured_button = view["row_type_has_featured_add_button"]
52+
if has_featured_button:
53+
created_elements_find = api.content.find(
54+
portal_type="DynamicPageRow",
55+
id=str(random_id)
56+
)
57+
created_element = created_elements_find[0].getObject()
58+
random_id_featured = uuid4()
59+
api.content.create(
60+
type="DynamicPageRowFeatured",
61+
container=created_element,
62+
title="New Featured",
63+
id=str(random_id_featured)
64+
)
65+
66+
random_id_featured_2 = uuid4()
67+
api.content.create(
68+
type="DynamicPageRowFeatured",
69+
container=created_element,
70+
title="New Featured 2",
71+
id=str(random_id_featured_2)
72+
)
73+
statusmessage = _("Row added successfully")
74+
api.portal.show_message(
75+
message=statusmessage,
76+
request=self.request,
77+
type="info"
78+
)
79+
return self.request.response.redirect(f"{self.context.absolute_url()}#{str(random_id)}")

src/cs_dynamicpages/views/dynamic_view.pt

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@
306306
tal:condition="view/dynamic_page_folder_element_url"
307307
>
308308
<a class="btn btn-primary btn-lg"
309-
href="${view/dynamic_page_folder_element_url}/++add++DynamicPageRow"
309+
data-bs-toggle="offcanvas" data-bs-target="#addrow-offcanvasRight" aria-controls="offcanvasRight"
310310
title="Add row"
311311
i18n:attributes="title"
312312
><svg xmlns="http://www.w3.org/2000/svg"
@@ -321,6 +321,24 @@
321321
></path>
322322
</svg></a>
323323
</div>
324+
<div tal:define="available_views_for_row view/available_views_for_row"
325+
class="offcanvas offcanvas-end" tabindex="-1" id="addrow-offcanvasRight" aria-labelledby="offcanvasRightLabel">
326+
<div class="offcanvas-header">
327+
<h5 class="offcanvas-title" id="offcanvasRightLabel">Add new row</h5>
328+
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
329+
</div>
330+
<div class="offcanvas-body">
331+
<ul class="list-unstyled row">
332+
<li tal:repeat="item available_views_for_row" class="col-6 mb-2">
333+
<div class="p-5 bg-light rounded h-100 d-flex justify-content-center align-items-center">
334+
<a data-bs-toggle="tooltip" data-bs-title="${item/row_type}" href="${view/dynamic_page_folder_element_url}/add-row-content?row_type=${item/row_type}">
335+
<span tal:replace="structure python:icons.tag(item['row_type_icon'], tag_class='fs-1')"></span>
336+
</a>
337+
</div>
338+
</li>
339+
</ul>
340+
</div>
341+
</div>
324342
</tal:condition>
325343
<!-- Delete Confirmation Modal -->
326344
<div class="modal fade"
@@ -361,9 +379,17 @@
361379
</div>
362380
</div>
363381
</div>
382+
<script>
383+
// Selecciona todos los elementos con el atributo data-bs-toggle="tooltip"
384+
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
385+
386+
// Crea una instancia de tooltip para cada elemento encontrado
387+
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl));
388+
</script>
364389
</tal:condition-configuration>
365390
</main>
366391
</metal:main>
367-
</body>
392+
393+
</body>
368394

369395
</html>

src/cs_dynamicpages/views/dynamic_view.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
from zope.interface import alsoProvides
66
from zope.interface import implementer
77
from zope.interface import Interface
8-
9-
10-
# from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
11-
8+
from cs_dynamicpages.utils import get_available_views_for_row
9+
from cs_dynamicpages.utils import VIEW_PREFIX
1210

1311
class IDynamicView(Interface):
1412
"""Marker Interface for IDynamicView"""
@@ -61,3 +59,6 @@ def dynamic_page_folder_element_url(self):
6159

6260
def can_edit(self):
6361
return api.user.has_permission("Modify portal content", obj=self.context)
62+
63+
def available_views_for_row(self):
64+
return get_available_views_for_row()

0 commit comments

Comments
 (0)