[Zope3-checkins] CVS: Products3/demo/messageboard/step7/browser - __init__.py:1.1 add.pt:1.1 configure.zcml:1.1 details.pt:1.1 message.png:1.1 message.py:1.1 messageboard.png:1.1 messageboard.py:1.1 subscriptions.pt:1.1 subthread.pt:1.1 thread.pt:1.1 thread.py:1.1 widgets.py:1.1

Stephan Richter srichter@cosmos.phy.tufts.edu
Sat, 12 Jul 2003 12:43:27 -0400


Update of /cvs-repository/Products3/demo/messageboard/step7/browser
In directory cvs.zope.org:/tmp/cvs-serv29199/browser

Added Files:
	__init__.py add.pt configure.zcml details.pt message.png 
	message.py messageboard.png messageboard.py subscriptions.pt 
	subthread.pt thread.pt thread.py widgets.py 
Log Message:
Step 7 of the Content Components recipes. This recipe explains Events, 
Channels and Subscriptions.


=== Added File Products3/demo/messageboard/step7/browser/__init__.py ===


=== Added File Products3/demo/messageboard/step7/browser/add.pt ===
<html metal:use-macro="views/standard_macros/dialog">
<body>

<div metal:fill-slot="body">
<form action="action.html" method="POST" i18n:domain="messageboard">
<table class="TypeListing" cellpadding="3">

  <caption i18n:translate="">Add Content</caption>

    <tbody tal:repeat="info view/addingInfo">

    <tr>

      <td class="Selector">
        <input type="radio" name="type_name"
               tal:attributes="value info/action; id info/action" />
      </td>

      <td class="TypeName">
        <label style="font-weight: bold;"
               tal:attributes="for info/action">
          <span tal:replace="info/title" >Folder</span>
        </label>
        <div class="TypeDescription" tal:content="info/description">
          Folders are generic containers for content, including other
          folders.
        </div>
      </td>
    </tr>

  </tbody>

  <tbody tal:condition="nothing">

    <tr>

      <td class="Selector">
        <input type="radio" name="type_name" value="" />

      </td>

      <td class="TypeName">
        <img alt="Folder" src="../../ZMI/www/document_icon.gif" />
        Document
      </td>

    </tr>

    <tr>
      <td class="Selector"><br /></td>
      <td class="TypeDescription">
          Documents are simple textual content.
      </td>
    </tr>

  </tbody>

  <tr>
    <td><br/></td>
    <td>
        <input type="text" name="id"
               tal:condition="view/namesAccepted"
	       tal:attributes="value request/id | nothing"
        />
        <input type="submit" value=" Add " 
            i18n:attributes="value add-button"/>
    </td>
  </tr>

</table>
</form>
</div>
</body>
</html>



=== Added File Products3/demo/messageboard/step7/browser/configure.zcml ===
<zopeConfigure
   xmlns="http://namespaces.zope.org/zope"
   xmlns:browser="http://namespaces.zope.org/browser">

  <!-- IMessageBoard Views -->

  <browser:menu
       id="add_messageboard"
       title="Menu of objects to be added to Message Boards."/>

  <browser:view
      name="+"
      for="zopeproducts.messageboard.interfaces.IMessageBoard"
      class=".messageboard.MessageBoardAdding"
      permission="zopeproducts.messageboard.Add"
      allowed_attributes="addingInfo"
      menu="zmi_actions"
      title="Add"
      >
      <browser:page name="index.html"  template="add.pt" />
      <browser:page name="action.html" attribute="action" />
  </browser:view>

  <browser:addform
      label="Add Message Board"
      name="AddMessageBoard"
      schema="zopeproducts.messageboard.interfaces.IMessageBoard"
      content_factory="zopeproducts.messageboard.messageboard.MessageBoard"
      permission="zope.ManageContent"
      menu="add_content" title="Message Board"/>

  <browser:editform
      schema="zopeproducts.messageboard.interfaces.IMessageBoard"
      for="zopeproducts.messageboard.interfaces.IMessageBoard"
      label="Change Message Board"
      name="edit.html"
      permission="zopeproducts.messageboard.Edit"
      menu="zmi_views" title="Edit" />

  <browser:page
      name="thread.html"
      for="zopeproducts.messageboard.interfaces.IMessageBoard"
      class=".thread.Thread"
      template="thread.pt"
      permission="zopeproducts.messageboard.View"
      menu="zmi_views" title="Thread"/>

  <browser:page
      name="contents.html"
      for="zopeproducts.messageboard.interfaces.IMessageBoard"
      permission="zope.ManageContent"
      class="zope.app.browser.container.contents.Contents"
      attribute="contents"
      menu="zmi_views" title="Contents"/>

  <browser:defaultView
      for="zopeproducts.messageboard.interfaces.IMessageBoard"
      name="thread.html"/>

  <browser:icon
      name="zmi_icon"
      for="zopeproducts.messageboard.interfaces.IMessageBoard"
      file="messageboard.png" />

  <!-- IMessage Views -->

  <browser:menu
       id="add_message"
       title="Menu of objects to be added to Messages."/>

  <browser:view
      name="+"
      for="zopeproducts.messageboard.interfaces.IMessage"
      class=".message.MessageAdding"
      permission="zopeproducts.messageboard.Add"
      allowed_attributes="addingInfo"
      menu="zmi_actions"
      title="Add"
      >
      <browser:page name="index.html"  template="add.pt" />
      <browser:page name="action.html" attribute="action" />
  </browser:view>

  <browser:addform
      label="Add Message"
      name="AddMessage"
      schema="zopeproducts.messageboard.interfaces.IMessage"
      content_factory="zopeproducts.messageboard.message.Message"
      permission="zopeproducts.messageboard.Add"
      menu="add_messageboard" title="Message"/>

  <browser:editform
      schema="zopeproducts.messageboard.interfaces.IMessage"
      for="zopeproducts.messageboard.interfaces.IMessage"
      label="Change Message"
      name="edit.html"
      permission="zopeproducts.messageboard.Edit"
      menu="zmi_views" title="Edit" />

  <browser:page
      name="details.html"
      for="zopeproducts.messageboard.interfaces.IMessage"
      class=".message.MessageDetails"
      template="details.pt"
      permission="zopeproducts.messageboard.View"
      menu="zmi_views" title="Preview"/>

  <browser:page
      name="thread.html"
      for="zopeproducts.messageboard.interfaces.IMessage"
      class=".thread.Thread"
      template="thread.pt"
      permission="zopeproducts.messageboard.View"
      menu="zmi_views" title="Thread"/>

  <browser:pages
      for="zopeproducts.messageboard.interfaces.IMessage"
      class=".message.MailSubscriptions"
      permission="zopeproducts.messageboard.Edit">
      <browser:page name="subscriptions.html" template="subscriptions.pt"
          menu="zmi_views" title="Subscriptions" />
      <browser:page name="changeSubscriptions.html" attribute="change" />
  </browser:pages>

  <browser:menuItem
    menu="add_message"
    for="zope.app.interfaces.container.IAdding"
    action="AddMessage"
    title="Message"/>

  <browser:menuItem 
      menu="add_message"
      for="zope.app.interfaces.container.IAdding"
      action="Image"
      title="Image" />

  <browser:menuItem 
      menu="add_message"
      for="zope.app.interfaces.container.IAdding"
      action="File"
      title="File" />

  <browser:page
      name="contents.html"
      for="zopeproducts.messageboard.interfaces.IMessage"
      permission="zope.ManageContent"
      class="zope.app.browser.container.contents.Contents"
      attribute="contents"
      menu="zmi_views" title="Contents"/>

  <browser:defaultView
      for="zopeproducts.messageboard.interfaces.IMessage"
      name="details.html"/>

  <browser:icon
      name="zmi_icon"
      for="zopeproducts.messageboard.interfaces.IMessage"
      file="message.png" />

  <!-- Custom Widgets -->

  <browser:page
      permission="zope.Public"
      allowed_interface="zope.app.interfaces.browser.form.IBrowserWidget"
      for="zopeproducts.messageboard.interfaces.IHTML"
      name="edit"
      class=".widgets.HTMLSourceWidget" />

</zopeConfigure>


=== Added File Products3/demo/messageboard/step7/browser/details.pt ===
<html metal:use-macro="views/standard_macros/page">
  <body>
    <div metal:fill-slot="body" i18n:domain="messageboard">

      <h1 i18n:translate="">Message Details</h1>

        <div class="row">
            <div class="label" i18n:translate="">Title</div>
            <div class="field" tal:content="context/title" />
        </div>

        <div class="row">
            <div class="label" i18n:translate="">Author</div>
            <div class="field" tal:content="view/author"/>
        </div>

        <div class="row">
            <div class="label" i18n:translate="">Date/Time</div>
            <div class="field" tal:content="view/modified"/>
        </div>

        <div class="row">
            <div class="label" i18n:translate="">Parent</div>
            <div class="field" tal:define="info view/parent_info">
              <a href="../" 
	          tal:condition="info"
                  tal:content="info/title" />
            </div>
        </div>

        <div class="row">
            <div class="label" i18n:translate="">Body</div>
            <div class="field" tal:content="structure context/body"/>
        </div>

    </div>
  </body>
</html>


=== Added File Products3/demo/messageboard/step7/browser/message.png ===
  <Binary-ish file>

=== Added File Products3/demo/messageboard/step7/browser/message.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Browser Views for IMessage

$Id: message.py,v 1.1 2003/07/12 16:43:16 srichter Exp $
"""
from zope.app.interfaces.dublincore import ICMFDublinCore
from zopeproducts.messageboard.interfaces import IMessage, IMailSubscriptions

from zope.component import getAdapter
from zope.app.traversing import getParent, getName
from zope.app.browser.container.adding import Adding


class MessageDetails:

    def author(self):
        """Get user who last modified the Wiki Page."""
        creators = getAdapter(self.context, ICMFDublinCore).creators
        if not creators:
            return 'unknown'
        return creators[0]

    def modified(self):
        """Get last modification date."""
        date = getAdapter(self.context, ICMFDublinCore).modified
        if date is None:
            date = getAdapter(self.context, ICMFDublinCore).created
        if date is None:
            return ''
        formatter = self.request.locale.getDateTimeFormatter('medium')
        return formatter.format(date)

    def parent_info(self):
        """Get the parent of the message"""
        parent = getParent(self.context)
        if not IMessage.isImplementedBy(parent):
            return None
        return {'name': getName(parent), 'title': parent.title}


class MailSubscriptions:

    def subscriptions(self):
        return getAdapter(self.context, IMailSubscriptions).getSubscriptions()

    def change(self):
        if 'ADD' in self.request:
            emails = self.request['emails'].split('\n')
            getAdapter(self.context,
                       IMailSubscriptions).addSubscriptions(emails)
        elif 'REMOVE' in self.request:
            emails = self.request['remails']
            print emails
            if isinstance(emails, (str, unicode)):
                emails = [emails]
            getAdapter(self.context,
                       IMailSubscriptions).removeSubscriptions(emails)

        self.request.response.redirect('.')


class MessageAdding(Adding):
    """Custom adding view for Message objects."""
    menu_id = "add_message"


=== Added File Products3/demo/messageboard/step7/browser/messageboard.png ===
  <Binary-ish file>

=== Added File Products3/demo/messageboard/step7/browser/messageboard.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Browser Views for IMessageBoard

$Id: messageboard.py,v 1.1 2003/07/12 16:43:16 srichter Exp $
"""
from zope.app.browser.container.adding import Adding

class MessageBoardAdding(Adding):
    """Custom adding view for MessageBoard objects."""
    menu_id = "add_messageboard"


=== Added File Products3/demo/messageboard/step7/browser/subscriptions.pt ===
<html metal:use-macro="views/standard_macros/page">
  <head>
    <style metal:fill-slot="style_slot">
    </style>
  </head>
  <body>
    <div metal:fill-slot="body" i18n:domain="messageboard">

      <form action="changeSubscriptions.html" method="post">

        <div class="row">
            <div class="label" i18n:translate="">Current Subscriptions</div>
            <div class="field">
	      <div tal:repeat="email view/subscriptions">
                <input type="checkbox" name="remails:list" 
                       value="" tal:attributes="value email">
                <div tal:replace="email">zope3@zope3.org</div>
              </div>
              <input type="submit" name="REMOVE" value="Remove" 
                   i18n:attributes="value remove-button">
            </div>
        </div>

        <div class="row">
            <div class="label" i18n:translate="">
              Enter new Users (separate by 'Return')
            </div>
            <div class="field">
	      <textarea name="emails" cols="40" rows="10"></textarea>
            </div>
        </div>

      	<div class="row">
      	  <div class="controls">
      	    <input type="submit" value="Refresh" 
                i18n:attributes="value refresh-button" />
      	    <input type="submit" name="ADD" value="Add" 
      		i18n:attributes="value add-button" />
      	  </div>
      	</div>

      </form>

    </div>
  </body>
</html>


=== Added File Products3/demo/messageboard/step7/browser/subthread.pt ===
<ul>
  <li tal:repeat="item view/listContentInfo">
    <a href="" 
        tal:attributes="href item/url"
        tal:content="item/title">Message 1</a>
    <div tal:replace="structure item/thread"/>
  </li>
</ul>

=== Added File Products3/demo/messageboard/step7/browser/thread.pt ===
<html metal:use-macro="views/standard_macros/page">
  <body>
    <div metal:fill-slot="body" i18n:domain="messageboard">

      <h1 i18n:translate="">Discussion Thread</h1>

      <div tal:replace="structure view/subthread" />

    </div>
  </body>
</html>


=== Added File Products3/demo/messageboard/step7/browser/thread.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Browser View for the sub-thread of a Message or MessageBoard

$Id: thread.py,v 1.1 2003/07/12 16:43:16 srichter Exp $
"""
from zopeproducts.messageboard.interfaces import IMessage
from zope.app.context import ContextWrapper
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile

class Thread:

    def __init__(self, context, request, base_url=''):
        self.context = context
        self.request = request
        self.base_url = base_url

    def listContentInfo(self):
        children = []
        for name, child in self.context.items():
            if IMessage.isImplementedBy(child):
                wrapped = ContextWrapper(child, self.context, name=name)
                info = {}
                info['title'] = child.title
                url = self.base_url + name + '/'
                info['url'] = url + '@@thread.html'
                thread = Thread(wrapped, self.request, url)
                info['thread'] = thread.subthread()
                children.append(info)
        return children

    subthread = ViewPageTemplateFile('subthread.pt')



=== Added File Products3/demo/messageboard/step7/browser/widgets.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Module containing custom widget definitions.

$Id: widgets.py,v 1.1 2003/07/12 16:43:16 srichter Exp $
"""
import re
from zope.app.browser.form.widget import TextAreaWidget
from zopeproducts.messageboard.fields import \
     forbidden_regex, allowed_regex

class HTMLSourceWidget(TextAreaWidget):

    def _convert(self, value):

        if self.context.forbidden_tags:
            regex = forbidden_regex %'|'.join(
                self.context.forbidden_tags)
            value = re.sub(regex, '', value)

        if self.context.allowed_tags:
            regex = allowed_regex %'|'.join(
                self.context.allowed_tags)
            value = re.sub(regex, '', value)

        return value