29. Turning Talks into Events¶
We forgot something: A list of talks is great especially if you can sort it by your preferences. But if a visitor decides he wants to actually go to see a talk he needs to know when it will take place.
We need a schedule and for this we need to store the information when a talk will happen.
Luckily the default type Event is based on reusable behaviors from the package plone.app.event.
In this chapter we will
- enable this behavior for talks
- display the date in the talkview and talklistview
First we enable the behavior IEventBasic
for talks in profiles/default/types/talk.xml
1 2 3 4 5 6 7 | <property name="behaviors">
<element value="plone.app.dexterity.behaviors.metadata.IDublinCore"/>
<element value="plone.app.content.interfaces.INameFromTitle"/>
<element value="ploneconf.site.behavior.social.ISocial"/>
<element value="ploneconf.site.interfaces.ITalk"/>
<element value="plone.app.event.dx.behaviors.IEventBasic"/>
</property>
|
After we activate the behavior by hand or reinstalled the add-on we will now have some additional fields for start
and end
.
To display the new field we reuse a default event summary view as documented in http://ploneappevent.readthedocs.io/en/latest/development.html#reusing-the-event-summary-view-to-list-basic-event-information
Edit browser/templates/talkview.pt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
metal:use-macro="context/main_template/macros/master"
i18n:domain="ploneconf.site">
<body>
<metal:content-core fill-slot="content-core" tal:define="widgets view/w">
<tal:eventsummary replace="structure context/@@event_summary"/>
<p>
<span tal:content="context/type_of_talk">
Talk
</span>
suitable for
<span tal:replace="structure widgets/audience/render">
Audience
</span>
</p>
<div tal:content="structure widgets/details/render">
Details
</div>
<div class="newsImageContainer">
<img tal:condition="python:getattr(context, 'image', None)"
tal:attributes="src string:${context/absolute_url}/@@images/image/thumb" />
</div>
<div>
<a class="email-link" tal:attributes="href string:mailto:${context/email}">
<strong tal:content="context/speaker">
Jane Doe
</strong>
</a>
<div tal:content="structure widgets/speaker_biography/render">
Biography
</div>
</div>
</metal:content-core>
</body>
</html>
|
Similar to the field room the problem now appears that speakers submitting their talks should not be able to set a time and day for their talks. Sadly it is not easy to modify permissions of fields provided by behaviors (unless we write the bahvior ourselves). At least in this case we can take the easy way out since the field does not contain secret information: We will simply hide the fields from contributors using css and show them for reviewers. We will do so in chapter Resources when we add some css-files.
Modify browser/static/ploneconf.css
and add:
body.userrole-contributor #formfield-form-widgets-IEventBasic-start,
body.userrole-contributor #formfield-form-widgets-IEventBasic-end > *,
body.userrole-contributor #formfield-form-widgets-IEventBasic-whole_day,
body.userrole-contributor #formfield-form-widgets-IEventBasic-open_end {
display: none;
}
body.userrole-reviewer #formfield-form-widgets-IEventBasic-start,
body.userrole-reviewer #formfield-form-widgets-IEventBasic-end > *,
body.userrole-reviewer #formfield-form-widgets-IEventBasic-whole_day,
body.userrole-reviewer #formfield-form-widgets-IEventBasic-open_end {
display: block;
}
You should also display the start-date of a talk in the talklist.
Modify browser/templates/talklistview.pt
1 2 3 4 5 6 7 8 9 10 11 12 13 | [...]
<td tal:content="python:talk['audience']">
Advanced
</td>
<td class="pat-moment"
data-pat-moment="format:calendar"
tal:content="python:talk['start']">
Time
</td>
<td tal:content="python:talk['room']">
101
</td>
[...]
|
Exercise 1¶
Find out where event_summary
comes from and describe how you could override it.
Solution
Use your editor or grep to search all zcml-files in the folder packages
for the string name="event_summary"
$ grep -sirn --include \*.zcml 'name="event_summary"' ./packages
./packages/plone/app/event/browser/configure.zcml:66: name="event_summary"
./packages/plone/app/event/browser/configure.zcml:75: name="event_summary"
The relevant registration is:
<browser:page
for="plone.event.interfaces.IEvent"
name="event_summary"
class=".event_summary.EventSummaryView"
template="event_summary.pt"
permission="zope2.View"
layer="..interfaces.IBrowserLayer"
/>
So there is a class plone.app.event.browser.event_summary.EventSummaryView
and a template event_summary.pt
that could be overridden with z3c.jbot
by copying it as plone.app.event.browser.event_summary.pt
in browser/overrides
.
Exercise 2¶
Find out where the event behavior is defined and which fields it offers.
Solution
The id with which the behavior is registered in Talk.xml
is a Python path. So plone.app.event.dx.behaviors.IEventBasic
can be found in packages/plone.app.event/plone/app/event/dx/behaviors.py
class IEventBasic(model.Schema, IDXEvent):
""" Basic event schema.
"""
start = schema.Datetime(
title=_(
u'label_event_start',
default=u'Event Starts'
),
description=_(
u'help_event_start',
default=u'Date and Time, when the event begins.'
),
required=True,
defaultFactory=default_start
)
end = schema.Datetime(
title=_(
u'label_event_end',
default=u'Event Ends'
),
description=_(
u'help_event_end',
default=u'Date and Time, when the event ends.'
),
required=True,
defaultFactory=default_end
)
whole_day = schema.Bool(
title=_(
u'label_event_whole_day',
default=u'Whole Day'
),
description=_(
u'help_event_whole_day',
default=u'Event lasts whole day.'
),
required=False,
default=False
)
open_end = schema.Bool(
title=_(
u'label_event_open_end',
default=u'Open End'
),
description=_(
u'help_event_open_end',
default=u"This event is open ended."
),
required=False,
default=False
)
Note how it uses defaultFactory
to set an initial value.