File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 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 >
Original file line number Diff line number Diff line change 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" )
Original file line number Diff line number Diff line change 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 >
Original file line number Diff line number Diff line change 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 >
Original file line number Diff line number Diff line change 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
You can’t perform that action at this time.
0 commit comments