Размер: 2076
Комментарий:
|
← Версия 16 от 2010-06-13 19:31:48 ⇥
Размер: 21073
Комментарий:
|
Удаления помечены так. | Добавления помечены так. |
Строка 7: | Строка 7: |
This is the second part of the tutorial. In the first part, you learned about project directory structure, Buildout configuration, content components and using the form library. Content components are objects with a user visible view. A view could be a browser view (HTML/JS/CSS) or JSON or XMLRPC or any other view. To explain the idea of content components, the ticket collector project started in the first part of tutorial will be expanded with additional functionality. In fact, the collector object created in the last chapter is a content component. In this chapter, you will create new content objects like tickets and comments. Another thing that should be noted is that every content component, including container components, has well defined interfaces. This chapter explores content components in more detail. After completing this chapter, you should be able to: Define schema for content components Create container objects Use ZCML to configure various components Before proceeding further, here is an overview of what we will cover: Adding tickets – In this section you will create a ticket object. We provide a detailed overview of creating content objects and demonstrate with a simple example. Listing tickets – Next you will see how to display tickets from the main collector page. Adding comments – Here you will learn how to add content objects inside other container objects. Ticket objects will be transformed to container objects. Listing comments – In this section you will develop a comment object and write the code needed to display comments on the ticket page. Note The examples in this documentation can be downloaded from here: http://download.zope.org/bluebream/examples/ticketcollector-1.0.0.tar.bz2 The source code is available in different stages corresponding to sections. Stage 1 : Section 5.2 to 5.7 Stage 2 : Section 5.8 Stage 3 : Section 5.9 Stage 4 : Section 6.2 Stage 5 : Section 6.3 Stage 6 : Section 6.4 & 6.5 |
Это вторая часть учебника. В первой части вы узначли о структуре папок проекта, настройке Buildout, компонентах содержимого, и использовании библиотеки форм. Компоненты содержимого - объекты с видимым для пользователя видом. Вид может быть браузерным (HTML/JS/CSS), JSON, XMLRPC или любым другим. Чтобы обяснить идею контент компонентов, проект, который был начат в первой части учебника, будет расширен путем добавления новых функций. По сути объект коллектор, который был создан в последнем разделе - контент компонент. В этом разделе, вы создадите и другие контент объекты, такие как заявки и комментарии. Также следует упомянуть, что каждый контент компонент, включая контейнеры, имеет хорошо определенные интерфейсы. Этот раздел исследует контент компоненты более детально. После окончания раздела, вы будете уметь: * Определять схему контент компонентов * Создавать контейнеры * Использовать ZCML для настройки компонентов Перед продолжением, вот обзор того, что рассматривается: * '''Добавление заявок''' – В этой части вы создадите объект заявки. Мы обеспечим подробный обзор создания контент объектов и покажем их использование на простом примере. * '''Списки заявок''' – Дальше вы увидите, как отобразить список заявок на главной странице коллектора. * '''Добавление комментариев''' – В этой части вы научитесь добавлять контент объекты внутрь контейнеров. Объекти заявки будут превращены в контейнеры. * '''Списки комментариев''' – В этой части вы создадите объект комментарий и напишете код для отображения комментариев на странице заявки. {{{#!wiki note Примеры для этой документации могут быть загружены отсюда: http://download.zope.org/bluebream/examples/ticketcollector- 1.0.0.tar.bz2. Исходники доступны на разных этапах соответственно разделам: * Этап 1 : От раздела 5.2 до 5.7 * Этап 2 : Раздел 5.8 * Этап 3 : Раздел 5.9 * Этап 4 : Раздел 6.2 * Этап 5 : Раздел 6.3 * Этап 6 : Раздел 6.4 и 6.5 }}} == Добавление заявок == === Определение схемы === В этом разделе вы научитесь добавлять заявки в коллектор. Для того, чтобы использовать объекты заявки, вам нужно создать интерфейс заявки. Обновите ''src/tc/collector/interfaces.py'', добавив туда интерфейс заявки: {{{#!highlight python from zope.container.interfaces import IContainer class ITicket(IContainer): """Ticket - the ticket content component""" number = TextLine( title=u"Number", description=u"Ticket number", default=u"", required=True) summary = Text( title=u"Summary", description=u"Ticket summary", default=u"", required=True) }}} '''!TextLine''' и '''Text''' должны быть проимпортированы, если нет - проимпортируйте их: {{{#!highlight python from zope.schema import TextLine from zope.schema import Text }}} Будет очень хорошо, если вы установите предусловие для ограничения на типы объектов, добавляемых в коллектор. Если вы знаеие, что в объект коллектор можно добавлять только объекты заявки, добавьте предусловие для того, чтобы удостоверится, что в коллектор будут добавлять только заявки. Для того, чтобы сделать это, вам нужно добавить метод '''_ _setitem_ _''' интерфейса ICollector в определение интерфейса ( '''_ _setitem_ _''' - часть API интерфейсв IContainer). Ниже нужно добавить атрибут предусловия, который является экземпляром класса '''!ItemTypePrecondition'''. Вы можете передать в класс temTypePrecondition интерфейсы в качестве аргументов. В примере ниже передается тольео один интерфейс - '''ITicket'''. Таким образом, только объекты заявки можно добавлять в коллектор. Вам нужно переместить определение интерфейса '''ITicket''' выше определения '''IContainer''', поскольку '''ITicket''' используется им. Добавьте следующее определение метода в класс '''ICollector''': {{{#!highlight python from zope.container.constraints import ItemTypePrecondition def _ _setitem_ _(name, object): """Add an ICollector object.""" _ _setitem_ _.precondition = ItemTypePrecondition(ITicket) }}} Класс !ItemTypePrecondition предоставляет ограничения на типы объектов, которые могут быть добавлены внутрь контейнера. Вы также определяете объекты заявки, которые могут быть добавлены в коллектор. Для того, чтобы сделать это, вы должны создать другой интерфейс, который наследуется от '''zope.container.interfaces.IContained'''. {{{#!highlight python from zope.schema import Field from zope.container.interfaces import IContained from zope.container.constraints import ContainerTypesConstraint class ITicketContained(IContained): """Interface that specifies the type of objects that can contain tickets. So a ticket can only contain in a collector.""" _ _parent_ _ = Field( constraint = ContainerTypesConstraint(ICollector)) }}} Тут вы добавили ограничение на поле '''_ _parent_ _''', используя класс '''!ContainerTypesConstraint'''. === Реализация === Дальше вам необходимо реализовать интефейс внутри ''src/tc/collector/ticket.py'': {{{#!highlight python from zope.interface import implements from zope.container.contained import Contained from zope.container.btree import BTreeContainer from tc.collector.interfaces import ITicket from tc.collector.interfaces import ITicketContained class Ticket(BTreeContainer, Contained): implements(ITicket, ITicketContained) number = u"" summary = u"" }}} === Конфигурация === Теперь необоходимо зарегистрировать интерфейс и класс. Откройте ''src/tc/collector/configure.zcml'' и добавьте следующее: {{{#!highlight xml <interface interface="tc.collector.interfaces.ITicket" type="zope.app.content.interfaces.IContentType" /> <class class="tc.collector.ticket.Ticket"> <implements interface="zope.annotation.interfaces.IAttributeAnnotatable" /> <implements interface="zope.container.interfaces.IContentContainer" /> <require permission="zope.Public" interface="tc.collector.interfaces.ITicket" /> <require permission="zope.Public" set_schema="tc.collector.interfaces.ITicket" /> </class> }}} Теперь вы можете добавить ссылку на '''@@add_ticket''' в ''src/tc/collector/collectormain.pt''. Теперь шаблон будет выглядеть вот так: {{{#!highlight html <html> <head> <title>Welcome to ticket collector</title> </head> <body> Welcome to ticket collector! <br/> <br/> <a href="@@add_ticket">Add Ticket</a> </body> </html> }}} Когда вы перейдете по ссылке, ожидается получение вида. Вы можете создать '''AddForm''' в ''src/tc/collector/views.py'': {{{#!highlight python from tc.collector.interfaces import ITicket from tc.collector.ticket import Ticket class AddTicket(form.AddForm): form_fields = form.Fields(ITicket) def createAndAdd(self, data): number = data['number'] summary = data['summary'] ticket = Ticket() ticket.number = number ticket.summary = summary self.context[number] = ticket self.request.response.redirect('.') }}} Вы можете зарегистрировать вид ''src/tc/collector/configure.zcml'': {{{#!highlight xml <browser:page for="tc.collector.interfaces.ICollector" name="add_ticket" permission="zope.Public" class="tc.collector.views.AddTicket" /> }}} Вы можете добавить заявку перейдя по ссылке: http://localhost:8080/mycollector/@@add_ticket, вы можете передать номер заявки, например, '1' и добавить 'Test Summary' в качестве '''summary'''. Вы можете проверить объект через отладочную оболочку: {{{#!highlight bash jack@computer:/projects/ticketcollector$ ./bin/paster shell debug.ini ... Welcome to the interactive debug prompt. The 'root' variable contains the ZODB root folder. The 'app' variable contains the Debugger, 'app.publish(path)' simulates a request. >>> root['mycollector'] <tc.collector.ticketcollector.Collector object at 0xa5fc96c> >>> root['mycollector']['1'] <tc.collector.ticket.Ticket object at 0xa5ffecc> }}} === Страница по умолчанию для заявки === У нас еще нет страницы по умолчанию для заявки. Если вы попытаетесь получить доступ к заявке по ссылке http://localhost:8080/mycollector/1, то получите ошибку '''!NotFound''': {{{ URL: http://localhost:8080/mycollector/1 ... NotFound: Object: <tc.collector.ticketcollector.Ticket object at 0x8fe74ac>, name: u'@@index' }}} Эта ошибка возникает, потому что для интерфейса ITicket нет зарегистрированного вида с именем '''index'''. Этот раздел покажет, как создать вид по усолчанию для интерфейса ITicket. Как вы уже видели в разделе "Первые шаги", вы можете создать простой вид и зарегистрировать его в ZCML. Добавьте в ''src/tc/collector/views.py'' новый вид: {{{#!highlight python class TicketMainView(form.DisplayForm): form_fields = form.Fields(ITicket) template = ViewPageTemplateFile("ticketmain.pt") }}} Вы можете создать файл с шаблоном ''src/tc/collector/ticketmain.pt'' со следующем содержанием: {{{#!highlight xml <html> <head> <title>Welcome to ticket collector!</title> </head> <body> You are looking at ticket number: <b tal:content="context/number">number</b> <h3>Summary</h3> <p tal:content="context/summary">Summary goes here</p> </body> </html> }}} Потом в ''src/tc/collector/configure.zcml'': {{{#!highlight xml <browser:page for="tc.collector.interfaces.ITicket" name="index" permission="zope.Public" class="tc.collector.views.TicketMainView" /> }}} Теперь вы можете перейти к http://localhost:8080/mycollector/1/@@index. По этому адресу вы должны увидеть номер заявки и ее краткое описание. Если вы просмотрите исходник страницы в HTML через браузер, он будет выглядеть следующим образом: {{{#!highlight html <html> <head> <title>Welcome to ticket collector!</title> </head> <body> You are looking at ticket number: <b>1</b> <h3>Summary</h3> <p>Test Summary</p> </body> </html> }}} == Создание списка заявок == Этот раздел объясняет как создать список заявок на главной странице коллектора с тем, чтобы получить возможность навигации по заявкам. Для того, чтобы вивести список заявок на главной странице коллектора, вам необходимо можифицировать ''src/tc/collector/collectormain.pt'': {{{#!highlight xml <html> <head> <title>Welcome to ticket collector!</title> </head> <body> Welcome to ticket collector! <br/> <br/> <a href="@@add_ticket">Add Ticket</a> <br/> <br/> <ol> <li tal:repeat="ticket view/getTickets"> <a href="" tal:attributes="href ticket/url" tal:content="ticket/summary">Ticket Summary</a> </li> </ol> </body> </html> }}} Вам необходимо изменить '''!TicketCollectorMainView''', который определен в файле ''src/tc/collector/views.py'': {{{#!highlight python class TicketCollectorMainView(form.DisplayForm): form_fields = form.Fields(ICollector) template = ViewPageTemplateFile("collectormain.pt") def getTickets(self): tickets = [] for ticket in self.context.values(): tickets.append({'url': ticket.number+"/@@index", 'summary': ticket.summary}) return tickets }}} == Добавление комментариев == {{{#!wiki warning Эта глава не завершена }}} В этом разделе вы создадите объекты комментариев, которые могут быть добавлены к заявкам. В качестве первого шага вам необходимо определить интерфейс комментария. Добавьте определение интерфейса в ''src/tc/collector/interfaces.py'': {{{#!highlight python from zope.interface import Interface class IComment(Interface): """Comment for Ticket""" body = Text( title=u"Additional Comment", description=u"Body of the Comment.", default=u"", required=True) class ICommentContained(IContained): """Interface that specifies the type of objects that can contain comments. A comment can only contain in a ticket.""" __parent__ = Field( constraint = ContainerTypesConstraint(ITicket)) }}} Для реализации комментария вы можете создать файл ''src/tc/collector/comment.py'': {{{#!highlight python from zope.interface import implements from tc.collector.interfaces import IComment from tc.collector.interfaces import ICommentContained from zope.container.contained import Contained class Comment(Contained): implements(IComment, ICommentContained) body = u"" }}} После этого зарегистрируйте интерфейс и класс, для этого обновите файл ''src/tc/collector/configure.zcml'': {{{#!highlight xml <interface interface="tc.collector.interfaces.IComment" type="zope.app.content.interfaces.IContentType" /> <class class="tc.collector.comment.Comment"> <implements interface="zope.annotation.interfaces.IAttributeAnnotatable" /> <require permission="zope.Public" interface="tc.collector.interfaces.IComment" /> <require permission="zope.Public" set_schema="tc.collector.interfaces.IComment" /> </class> }}} Вам также следует добавить '''!ItemTypePrecondition''' к '''ITicket'''. Откройте ''src/tc/collector/interfaces.py'' и обновите определение интерфейса: {{{#!highlight python class ITicket(IContainer): """Ticket - the ticket content component""" number = TextLine( title=u"Number", description=u"Ticket number", default=u"", required=True) summary = Text( title=u"Summary", description=u"Ticket summary", default=u"", required=True) def __setitem__(name, object): """Add an ICollector object.""" __setitem__.precondition = ItemTypePrecondition(IComment) }}} Вы можете обновить файл с шаблоном ''src/tc/collector/ticketmain.pt'', добавив туда новое содержимое: {{{#!highlight xml <html> <head> <title>Welcome to ticket collector!</title> </head> <body> You are looking at ticket number: <b tal:content="context/number">number</b> <h3>Summary</h3> <p tal:content="context/summary">Summary goes here</p> <a href="@@add_comment">Add Comment</a> </body> </html> }}} Вы можете создать форму добавления (!AddForm) как показано ниже. Откройте файл ''src/tc/collector/views.py'' и добавьте в него '''!AddComment''', как показано ниже: {{{#!highlight python from zope.container.interfaces import INameChooser from tc.collector.interfaces import IComment from tc.collector.comment import Comment class AddComment(form.AddForm): form_fields = form.Fields(IComment) def createAndAdd(self, data): body = data['body'] comment = Comment() comment.body = body namechooser = INameChooser(self.context) number = namechooser.chooseName('c', comment) self.context[number] = comment self.request.response.redirect('.') }}} Вы можете зарегистрировать вид в файле ''src/tc/collector/configure.zcml'': {{{#!highlight xml <browser:page for="tc.collector.interfaces.ITicket" name="add_comment" permission="zope.Public" class="tc.collector.views.AddComment" /> }}} == Создание списка комментариев == Этот раздел рассказывает о том, как создать список комментариев на странице заявки, и, таким образом, пользователь сможет увидеть комментарии, которые приаязаны к конкретной заявке. Для того, чтобы составить список комментариев на странице заявки, вам нужно модифицировать шаблон ''src/tc/collector/ticketmain.pt'': {{{#!highlight xml <html> <head> <title>Welcome to ticket collector!</title> </head> <body> You are looking at ticket number: <b tal:content="context/number">number</b> <h3>Summary</h3> <p tal:content="context/summary">Summary goes here</p> <a href="@@add_comment">Add Comment</a> <p tal:repeat="ticket context/values"> <span tal:content="ticket/body">Comment goes here</span> </p> </body> </html> }}} == Выводы == В этом разделе мы рассмотрели создания контент компонентов. Вы можете узнать больше о !BlueBream из руководства. '''Перевод: Ростислав Дзинько''' |
Учебник - часть 2
Содержание
Введение
Это вторая часть учебника. В первой части вы узначли о структуре папок проекта, настройке Buildout, компонентах содержимого, и использовании библиотеки форм. Компоненты содержимого - объекты с видимым для пользователя видом. Вид может быть браузерным (HTML/JS/CSS), JSON, XMLRPC или любым другим. Чтобы обяснить идею контент компонентов, проект, который был начат в первой части учебника, будет расширен путем добавления новых функций. По сути объект коллектор, который был создан в последнем разделе - контент компонент. В этом разделе, вы создадите и другие контент объекты, такие как заявки и комментарии. Также следует упомянуть, что каждый контент компонент, включая контейнеры, имеет хорошо определенные интерфейсы.
Этот раздел исследует контент компоненты более детально. После окончания раздела, вы будете уметь:
- Определять схему контент компонентов
- Создавать контейнеры
- Использовать ZCML для настройки компонентов
Перед продолжением, вот обзор того, что рассматривается:
Добавление заявок – В этой части вы создадите объект заявки. Мы обеспечим подробный обзор создания контент объектов и покажем их использование на простом примере.
Списки заявок – Дальше вы увидите, как отобразить список заявок на главной странице коллектора.
Добавление комментариев – В этой части вы научитесь добавлять контент объекты внутрь контейнеров. Объекти заявки будут превращены в контейнеры.
Списки комментариев – В этой части вы создадите объект комментарий и напишете код для отображения комментариев на странице заявки.
Примеры для этой документации могут быть загружены отсюда: http://download.zope.org/bluebream/examples/ticketcollector- 1.0.0.tar.bz2.
Исходники доступны на разных этапах соответственно разделам:
- Этап 1 : От раздела 5.2 до 5.7
- Этап 2 : Раздел 5.8
- Этап 3 : Раздел 5.9
- Этап 4 : Раздел 6.2
- Этап 5 : Раздел 6.3
- Этап 6 : Раздел 6.4 и 6.5
Добавление заявок
Определение схемы
В этом разделе вы научитесь добавлять заявки в коллектор. Для того, чтобы использовать объекты заявки, вам нужно создать интерфейс заявки. Обновите src/tc/collector/interfaces.py, добавив туда интерфейс заявки:
1 from zope.container.interfaces import IContainer
2
3 class ITicket(IContainer):
4 """Ticket - the ticket content component"""
5
6 number = TextLine(
7 title=u"Number",
8 description=u"Ticket number",
9 default=u"",
10 required=True)
11
12 summary = Text(
13 title=u"Summary",
14 description=u"Ticket summary",
15 default=u"",
16 required=True)
TextLine и Text должны быть проимпортированы, если нет - проимпортируйте их:
Будет очень хорошо, если вы установите предусловие для ограничения на типы объектов, добавляемых в коллектор. Если вы знаеие, что в объект коллектор можно добавлять только объекты заявки, добавьте предусловие для того, чтобы удостоверится, что в коллектор будут добавлять только заявки. Для того, чтобы сделать это, вам нужно добавить метод _ _setitem_ _ интерфейса ICollector в определение интерфейса ( _ _setitem_ _ - часть API интерфейсв IContainer). Ниже нужно добавить атрибут предусловия, который является экземпляром класса ItemTypePrecondition. Вы можете передать в класс temTypePrecondition интерфейсы в качестве аргументов. В примере ниже передается тольео один интерфейс - ITicket. Таким образом, только объекты заявки можно добавлять в коллектор. Вам нужно переместить определение интерфейса ITicket выше определения IContainer, поскольку ITicket используется им. Добавьте следующее определение метода в класс ICollector:
Класс ItemTypePrecondition предоставляет ограничения на типы объектов, которые могут быть добавлены внутрь контейнера. Вы также определяете объекты заявки, которые могут быть добавлены в коллектор. Для того, чтобы сделать это, вы должны создать другой интерфейс, который наследуется от zope.container.interfaces.IContained.
1 from zope.schema import Field
2 from zope.container.interfaces import IContained
3 from zope.container.constraints import ContainerTypesConstraint
4
5 class ITicketContained(IContained):
6 """Interface that specifies the type of objects that can contain
7 tickets. So a ticket can only contain in a collector."""
8
9 _ _parent_ _ = Field(
10 constraint = ContainerTypesConstraint(ICollector))
Тут вы добавили ограничение на поле _ _parent_ _, используя класс ContainerTypesConstraint.
Реализация
Дальше вам необходимо реализовать интефейс внутри src/tc/collector/ticket.py:
1 from zope.interface import implements
2 from zope.container.contained import Contained
3 from zope.container.btree import BTreeContainer
4
5 from tc.collector.interfaces import ITicket
6 from tc.collector.interfaces import ITicketContained
7
8
9 class Ticket(BTreeContainer, Contained):
10
11 implements(ITicket, ITicketContained)
12
13 number = u""
14 summary = u""
Конфигурация
Теперь необоходимо зарегистрировать интерфейс и класс. Откройте src/tc/collector/configure.zcml и добавьте следующее:
1 <interface
2 interface="tc.collector.interfaces.ITicket"
3 type="zope.app.content.interfaces.IContentType"
4 />
5
6 <class class="tc.collector.ticket.Ticket">
7 <implements
8 interface="zope.annotation.interfaces.IAttributeAnnotatable"
9 />
10 <implements
11 interface="zope.container.interfaces.IContentContainer"
12 />
13 <require
14 permission="zope.Public"
15 interface="tc.collector.interfaces.ITicket"
16 />
17 <require
18 permission="zope.Public"
19 set_schema="tc.collector.interfaces.ITicket"
20 />
21 </class>
Теперь вы можете добавить ссылку на @@add_ticket в src/tc/collector/collectormain.pt. Теперь шаблон будет выглядеть вот так:
Когда вы перейдете по ссылке, ожидается получение вида. Вы можете создать AddForm в src/tc/collector/views.py:
1 from tc.collector.interfaces import ITicket
2
3 from tc.collector.ticket import Ticket
4
5 class AddTicket(form.AddForm):
6
7 form_fields = form.Fields(ITicket)
8
9 def createAndAdd(self, data):
10 number = data['number']
11 summary = data['summary']
12 ticket = Ticket()
13 ticket.number = number
14 ticket.summary = summary
15 self.context[number] = ticket
16 self.request.response.redirect('.')
Вы можете зарегистрировать вид src/tc/collector/configure.zcml:
Вы можете добавить заявку перейдя по ссылке: http://localhost:8080/mycollector/@@add_ticket, вы можете передать номер заявки, например, '1' и добавить 'Test Summary' в качестве summary.
Вы можете проверить объект через отладочную оболочку:
1 jack@computer:/projects/ticketcollector$ ./bin/paster shell debug.ini
2 ...
3 Welcome to the interactive debug prompt.
4 The 'root' variable contains the ZODB root folder.
5 The 'app' variable contains the Debugger, 'app.publish(path)' simulates a request.
6 >>> root['mycollector']
7 <tc.collector.ticketcollector.Collector object at 0xa5fc96c>
8 >>> root['mycollector']['1']
9 <tc.collector.ticket.Ticket object at 0xa5ffecc>
Страница по умолчанию для заявки
У нас еще нет страницы по умолчанию для заявки. Если вы попытаетесь получить доступ к заявке по ссылке http://localhost:8080/mycollector/1, то получите ошибку NotFound:
URL: http://localhost:8080/mycollector/1 ... NotFound: Object: <tc.collector.ticketcollector.Ticket object at 0x8fe74ac>, name: u'@@index'
Эта ошибка возникает, потому что для интерфейса ITicket нет зарегистрированного вида с именем index. Этот раздел покажет, как создать вид по усолчанию для интерфейса ITicket.
Как вы уже видели в разделе "Первые шаги", вы можете создать простой вид и зарегистрировать его в ZCML.
Добавьте в src/tc/collector/views.py новый вид:
Вы можете создать файл с шаблоном src/tc/collector/ticketmain.pt со следующем содержанием:
Потом в src/tc/collector/configure.zcml:
Теперь вы можете перейти к http://localhost:8080/mycollector/1/@@index. По этому адресу вы должны увидеть номер заявки и ее краткое описание. Если вы просмотрите исходник страницы в HTML через браузер, он будет выглядеть следующим образом:
Создание списка заявок
Этот раздел объясняет как создать список заявок на главной странице коллектора с тем, чтобы получить возможность навигации по заявкам.
Для того, чтобы вивести список заявок на главной странице коллектора, вам необходимо можифицировать src/tc/collector/collectormain.pt:
1 <html>
2 <head>
3 <title>Welcome to ticket collector!</title>
4 </head>
5 <body>
6
7 Welcome to ticket collector! <br/> <br/>
8
9 <a href="@@add_ticket">Add Ticket</a> <br/> <br/>
10
11 <ol>
12 <li tal:repeat="ticket view/getTickets">
13 <a href=""
14 tal:attributes="href ticket/url"
15 tal:content="ticket/summary">Ticket Summary</a>
16 </li>
17 </ol>
18
19 </body>
20 </html>
Вам необходимо изменить TicketCollectorMainView, который определен в файле src/tc/collector/views.py:
1 class TicketCollectorMainView(form.DisplayForm):
2
3 form_fields = form.Fields(ICollector)
4
5 template = ViewPageTemplateFile("collectormain.pt")
6
7 def getTickets(self):
8 tickets = []
9 for ticket in self.context.values():
10 tickets.append({'url': ticket.number+"/@@index",
11 'summary': ticket.summary})
12 return tickets
Добавление комментариев
Эта глава не завершена
В этом разделе вы создадите объекты комментариев, которые могут быть добавлены к заявкам. В качестве первого шага вам необходимо определить интерфейс комментария. Добавьте определение интерфейса в src/tc/collector/interfaces.py:
1 from zope.interface import Interface
2
3 class IComment(Interface):
4 """Comment for Ticket"""
5
6 body = Text(
7 title=u"Additional Comment",
8 description=u"Body of the Comment.",
9 default=u"",
10 required=True)
11
12 class ICommentContained(IContained):
13 """Interface that specifies the type of objects that can contain
14 comments. A comment can only contain in a ticket."""
15
16 __parent__ = Field(
17 constraint = ContainerTypesConstraint(ITicket))
Для реализации комментария вы можете создать файл src/tc/collector/comment.py:
После этого зарегистрируйте интерфейс и класс, для этого обновите файл src/tc/collector/configure.zcml:
1 <interface
2 interface="tc.collector.interfaces.IComment"
3 type="zope.app.content.interfaces.IContentType"
4 />
5
6 <class class="tc.collector.comment.Comment">
7 <implements
8 interface="zope.annotation.interfaces.IAttributeAnnotatable"
9 />
10 <require
11 permission="zope.Public"
12 interface="tc.collector.interfaces.IComment"
13 />
14 <require
15 permission="zope.Public"
16 set_schema="tc.collector.interfaces.IComment"
17 />
18 </class>
Вам также следует добавить ItemTypePrecondition к ITicket. Откройте src/tc/collector/interfaces.py и обновите определение интерфейса:
1 class ITicket(IContainer):
2 """Ticket - the ticket content component"""
3
4 number = TextLine(
5 title=u"Number",
6 description=u"Ticket number",
7 default=u"",
8 required=True)
9
10 summary = Text(
11 title=u"Summary",
12 description=u"Ticket summary",
13 default=u"",
14 required=True)
15
16 def __setitem__(name, object):
17 """Add an ICollector object."""
18
19 __setitem__.precondition = ItemTypePrecondition(IComment)
Вы можете обновить файл с шаблоном src/tc/collector/ticketmain.pt, добавив туда новое содержимое:
1 <html>
2 <head>
3 <title>Welcome to ticket collector!</title>
4 </head>
5 <body>
6
7 You are looking at ticket number:
8 <b tal:content="context/number">number</b>
9
10 <h3>Summary</h3>
11
12 <p tal:content="context/summary">Summary goes here</p>
13
14 <a href="@@add_comment">Add Comment</a>
15
16 </body>
17 </html>
Вы можете создать форму добавления (AddForm) как показано ниже. Откройте файл src/tc/collector/views.py и добавьте в него AddComment, как показано ниже:
1 from zope.container.interfaces import INameChooser
2 from tc.collector.interfaces import IComment
3 from tc.collector.comment import Comment
4
5 class AddComment(form.AddForm):
6
7 form_fields = form.Fields(IComment)
8
9 def createAndAdd(self, data):
10 body = data['body']
11 comment = Comment()
12 comment.body = body
13 namechooser = INameChooser(self.context)
14 number = namechooser.chooseName('c', comment)
15 self.context[number] = comment
16 self.request.response.redirect('.')
Вы можете зарегистрировать вид в файле src/tc/collector/configure.zcml:
Создание списка комментариев
Этот раздел рассказывает о том, как создать список комментариев на странице заявки, и, таким образом, пользователь сможет увидеть комментарии, которые приаязаны к конкретной заявке.
Для того, чтобы составить список комментариев на странице заявки, вам нужно модифицировать шаблон src/tc/collector/ticketmain.pt:
1 <html>
2 <head>
3 <title>Welcome to ticket collector!</title>
4 </head>
5 <body>
6
7 You are looking at ticket number:
8 <b tal:content="context/number">number</b>
9
10 <h3>Summary</h3>
11
12 <p tal:content="context/summary">Summary goes here</p>
13
14 <a href="@@add_comment">Add Comment</a>
15
16 <p tal:repeat="ticket context/values">
17 <span tal:content="ticket/body">Comment goes here</span>
18 </p>
19
20 </body>
21 </html>
Выводы
В этом разделе мы рассмотрели создания контент компонентов. Вы можете узнать больше о BlueBream из руководства.
Перевод: Ростислав Дзинько