[Zope3-checkins] CVS: Products3/demo/messageboard/step4/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 subthread.pt:1.1 thread.pt:1.1 thread.py:1.1 widgets.py:1.1

Stephan Richter srichter@cosmos.phy.tufts.edu
Tue, 10 Jun 2003 17:47:53 -0400


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

Added Files:
	__init__.py add.pt configure.zcml details.pt message.png 
	message.py messageboard.png messageboard.py subthread.pt 
	thread.pt thread.py widgets.py 
Log Message:
This is step 4 of the message board recipes, which deals with security.


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


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

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

  <caption>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 " />
    </td>
  </tr>

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



=== Added File Products3/demo/messageboard/step4/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:menuItems menu="zmi_views"
      for="zopeproducts.messageboard.interfaces.IMessageBoard">
    <browser:menuItem title="Contents" action="@@contents.html" />
  </browser:menuItems>

  <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: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:menuItems menu="zmi_views"
      for="zopeproducts.messageboard.interfaces.IMessage">
    <browser:menuItem title="Contents" action="@@contents.html" />
  </browser:menuItems>

  <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/step4/browser/details.pt ===
<html metal:use-macro="views/standard_macros/page">
  <body>
    <div metal:fill-slot="body">

      <h1>Message Details</h1>

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

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

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

        <div class="row">
            <div class="label">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">Body</div>
            <div class="field" tal:content="structure context/body"/>
        </div>

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


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

=== Added File Products3/demo/messageboard/step4/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/06/10 21:47:51 srichter Exp $
"""
from zope.app.interfaces.dublincore import ICMFDublinCore
from zopeproducts.messageboard.interfaces import IMessage

from zope.component import getAdapter
from zope.app.traversing import getParent, objectName
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 ''
        return date.strftime('%d/%m/%Y %H:%M:%S')

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


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


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

=== Added File Products3/demo/messageboard/step4/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/06/10 21:47:51 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/step4/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/step4/browser/thread.pt ===
<html metal:use-macro="views/standard_macros/page">
  <body>
    <div metal:fill-slot="body">

      <h1>Discussion Thread</h1>

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

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


=== Added File Products3/demo/messageboard/step4/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/06/10 21:47:51 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/step4/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/06/10 21:47:51 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