Skip to content

Commit 736857b

Browse files
committed
Add a view
1 parent d00683c commit 736857b

5 files changed

Lines changed: 133 additions & 4 deletions

File tree

src/experimental/doodle/browser/configure.zcml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,14 @@
2222
type="plone"
2323
/>
2424

25+
<browser:page
26+
name="doodle"
27+
for="experimental.doodle.interfaces.IExperimentalDoodleFolder"
28+
class=".doodle.DoodleView"
29+
template="templates/doodle.pt"
30+
permission="zope2.View"
31+
layer="experimental.doodle.interfaces.IBrowserLayer"
32+
/>
33+
34+
2535
</configure>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from datetime import date
2+
from Products.Five.browser import BrowserView
3+
4+
5+
class DoodleView(BrowserView):
6+
"""Render date options in a simple doodle-style table."""
7+
8+
def rows(self):
9+
items = [
10+
obj
11+
for obj in self.context.objectValues()
12+
if obj.portal_type == "experimental.doodle.date"
13+
]
14+
15+
def sort_key(item):
16+
value = getattr(item, "date", None)
17+
if isinstance(value, date):
18+
return value
19+
return date.max
20+
21+
rows = []
22+
for item in sorted(items, key=sort_key):
23+
when = getattr(item, "date", None)
24+
participants = sorted(getattr(item, "participants", set()) or set())
25+
rows.append(
26+
{
27+
"title": item.Title(),
28+
"date": when,
29+
"participants": participants,
30+
}
31+
)
32+
return rows
33+
34+
def date_label(self, value):
35+
if not isinstance(value, date):
36+
return "-"
37+
return value.strftime("%Y-%m-%d")
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<html xmlns="http://www.w3.org/1999/xhtml"
2+
xmlns:metal="http://xml.zope.org/namespaces/metal"
3+
xmlns:tal="http://xml.zope.org/namespaces/tal"
4+
lang="en"
5+
metal:use-macro="context/main_template/macros/master"
6+
>
7+
<body>
8+
<metal:content-core fill-slot="content-core">
9+
<h1>Doodle</h1>
10+
<table class="listing"
11+
tal:condition="view/rows"
12+
>
13+
<thead>
14+
<tr>
15+
<th>Date</th>
16+
<th>Option</th>
17+
<th>Participants</th>
18+
</tr>
19+
</thead>
20+
<tbody>
21+
<tr tal:repeat="row view/rows">
22+
<td tal:content="python:view.date_label(row['date'])">2026-01-01 10:00</td>
23+
<td tal:content="row/title">Date option</td>
24+
<td>
25+
<span tal:condition="python:not row['participants']">No participants yet</span>
26+
<span tal:repeat="member row/participants"
27+
tal:content="member"
28+
tal:attributes="
29+
class string:label;
30+
"
31+
>member</span>
32+
</td>
33+
</tr>
34+
</tbody>
35+
</table>
36+
<p tal:condition="python:not view.rows()">No date options yet.</p>
37+
</metal:content-core>
38+
</body>
39+
</html>

src/experimental/doodle/profiles/default/types/experimental.doodle.folder.xml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@
1414
<property name="factory">experimental.doodle.folder</property>
1515
<property name="add_view_expr">string:${folder_url}/++add++experimental.doodle.folder</property>
1616
<property name="link_target" />
17-
<property name="immediate_view">view</property>
17+
<property name="immediate_view">doodle</property>
1818
<property name="global_allow">True</property>
19-
<property name="filter_content_types">False</property>
20-
<property name="allowed_content_types" />
19+
<property name="filter_content_types">True</property>
20+
<property name="allowed_content_types">
21+
<element value="experimental.doodle.date" />
22+
</property>
2123
<property name="allow_discussion">False</property>
22-
<property name="default_view">view</property>
24+
<property name="default_view">doodle</property>
2325
<property name="view_methods">
2426
<element value="view" />
27+
<element value="doodle" />
2528
</property>
2629
<property name="default_view_fallback">False</property>
2730
<property name="add_permission">experimental.doodle.AddDoodleFolder</property>

tests/test_doodle_view.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from datetime import date
2+
3+
import plone.api
4+
5+
6+
class TestDoodleView:
7+
def test_doodle_view_lists_sorted_dates(self, portal, request):
8+
with plone.api.env.adopt_roles(["Manager"]):
9+
folder = plone.api.content.create(
10+
container=portal,
11+
type="experimental.doodle.folder",
12+
id="poll",
13+
title="Poll",
14+
)
15+
16+
plone.api.content.create(
17+
container=folder,
18+
type="experimental.doodle.date",
19+
id="late",
20+
title="Late option",
21+
date=date(2026, 6, 1),
22+
participants={"bob"},
23+
)
24+
plone.api.content.create(
25+
container=folder,
26+
type="experimental.doodle.date",
27+
id="early",
28+
title="Early option",
29+
date=date(2026, 5, 1),
30+
participants={"alice", "bob"},
31+
)
32+
33+
view = folder.restrictedTraverse("@@doodle")
34+
html = view()
35+
36+
assert "Early option" in html
37+
assert "Late option" in html
38+
assert html.index("Early option") < html.index("Late option")
39+
assert "alice" in html
40+
assert "bob" in html

0 commit comments

Comments
 (0)