Nachdem die Artikeltypen mit ihrem jeweiligen Schema erstellt wurden, gehen wir
nun zum User-Interface über, dessen Code sich im browser
-Paket befindet.
Für jeden Artikeltyp wird ein eigenes Icon definiert in
browser/configure.zcml
, in unserem Fall:
<browser:resource
name="registration_icon.gif"
image="registration_icon.gif"
/>
Dieses Icon kann referenziert werden mit ++resource++registration_icon.gif
.
Um das Icon innerhalb eines Page Templates aufzurufen, können Sie folgendes
angeben:
<img tal:attributes="src context/++resource++registration_icon.gif" />
Dem Icon analog lässt sich auch ein Stylesheet-Dokument hinzufügen mit:
<browser:resource
name="registration.css"
file="registration.css"
/>
Diese Datei können Sie mit folgendem Code in ein Page Template einfügen:
<metal:css fill-slot="css_slot">
<style type="text/css" media="all"
tal:content="string: @import url(${context/++resource++registration.css});"></style>
</metal:css>
Auch die Views werden in browser/configure.zcml
registriert:
<browser:page
for="..interfaces.IRegistration"
name="view"
class=".registration.RegistrationView"
permission="zope2.View"
/>
Üblicherweise wird die Standardansicht eines Artikeltyps mit @@view
aufgerufen.
Sollen Autoren zwischen verschiedenen Ansichten eines Artikeltyps in Plones
Ansicht-Menü wählen können, müssen diese Ansichten einerseits in einer Liste im
GenericSetup-Profil angegeben werden, andererseits jedoch auch in
browser/configure.zcml
registriert werden:
<include package="plone.app.contentmenu" />
...
<browser:menuItem
for="..interfaces.IRegistration"
menu="plone_displayviews"
title="Registration view"
action="@@view"
description="Default view of a registration"
/>
action
verweist auf den Namen der Ansicht, wobei der Menüeintrag nur für das
IRegistration
-Interface angezeigt wird.
Die View-Klasse selbst enthält die Methoden name
und details
:
from Products.Five import BrowserView
class RegistrationView(BrowserView):
"""A view of a Registration object"""
def name(self):
return self.context.Title()
def details(self):
return self.context.Description()
Der Decorator @memoize
stellt sicher, dass der Aufruf in einer Instanz nur einmal ausgeführt wird – und der zurückgegebene Wert gespeichert wird. Wenn Templates eine Methode mehrfach aufrufen, kann so die Performance deutlich gesteigert werden (s.a. Memoize). Das Template registration.pt
sieht dann so aus:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
lang="en"
metal:use-macro="context/main_template/macros/master"
i18n:domain="vs.registration">
<body>
<metal:main fill-slot="main">
<tal:main-macro metal:define-macro="main"
tal:define="text context/text;">
<div tal:replace="structure provider:plone.abovecontenttitle" />
<h1 class="documentFirstHeading">
<span metal:use-macro="python:context.widget('title', mode='view')" />
</h1>
<div tal:replace="structure provider:plone.belowcontenttitle" />
<div class="documentDescription">
<span metal:use-macro="python:context.widget('description', mode='view')" />
</div>
<div tal:replace="structure provider:plone.abovecontentbody" />
<p tal:condition="python: not text and is_editable"
i18n:translate="no_body_text"
class="discreet">
This item does not have any body text, click the edit tab to change it.
</p>
<div tal:condition="text" metal:use-macro="python:context.widget('text', mode='view')" />
<form action="createObject">
<input name="type_name"
type="hidden"
value="Registrant"
/>
<input class="standalone"
value="Registration"
type="submit"
i18n:attributes="value"
/>
</form>
<tal:registrants condition="view/have_registrants">
<h2 i18n:translate="title_registration_contents">Registrants</h2>
<dl>
<tal:block repeat="registrant view/registrants">
<dt>
<a tal:attributes="href registrant/url"
tal:content="registrant/title" />
</dt>
<dd tal:content="registrant/address" />
</tal:block>
</dl>
</tal:registrants>
<div metal:use-macro="context/document_relateditems/macros/relatedItems">
show related items if they exist
</div>
<div tal:replace="structure provider:plone.belowcontentbody" />
</tal:main-macro>
</metal:main>
</body>
</html>
Das Template entspricht weitgehend Plones document_view.pt
.
Beachten Sie, dass verschiedene Viewlet-Manager angegeben wurden, wie z.B.:
<div tal:replace="structure provider:plone.abovecontenttitle" />
Im Kapitel Viewlets wird ausführlich auf diese Zope3-Komponenten eingegangen.
In diesem Template wurde auch das Inline-Editing mit Kinetic Style Sheets ermöglicht, z.B. mit:
<span metal:use-macro="python:context.widget('title', mode='view')" />
Soll ein Feld nicht direkt editiert werden können, genügt ein einfacheres Konstrukt:
<span tal:content="context/title" />
Mehr über das JavaScript-Framework erfahren Sie im Kapitel Kinetic Style Sheets.