[Checkins] SVN: Sandbox/darrylcousins/tfws.website/src/tfws/website/ Continuing with the project

Darryl Cousins darryl at darrylcousins.net.nz
Tue Jul 24 08:43:04 EDT 2007


Log message for revision 78308:
  Continuing with the project

Changed:
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/BROWSER.txt
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/authentication.py
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/browser/browser.py
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/browser/index.pt
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/configure.zcml
  A   Sandbox/darrylcousins/tfws.website/src/tfws/website/folderindex.py
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/interfaces.py
  A   Sandbox/darrylcousins/tfws.website/src/tfws/website/page.py
  A   Sandbox/darrylcousins/tfws.website/src/tfws/website/permissions.py
  A   Sandbox/darrylcousins/tfws.website/src/tfws/website/roles.py
  D   Sandbox/darrylcousins/tfws.website/src/tfws/website/security.zcml
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/site.py
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/site.txt
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/skin.py
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/template.pt
  A   Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/website.js
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/templates/index.pt
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/testing.py
  U   Sandbox/darrylcousins/tfws.website/src/tfws/website/tests.py

-=-
Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/BROWSER.txt
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/BROWSER.txt	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/BROWSER.txt	2007-07-24 12:43:02 UTC (rev 78308)
@@ -20,7 +20,7 @@
 
 Using our authenticated browser instance we can add a website.
 
-  >>> browser.open("http://localhost/add")
+  >>> browser.open("http://localhost/++skin++tfwswebsite/add")
   >>> browser.getControl('name').value = u'treefern'
   >>> browser.getControl('Title').value = u'Tree Fern'
   >>> browser.getControl('Login').value = u'darrylcousins'
@@ -40,5 +40,6 @@
 
 We can edit the new site.
 
-  >>> #print browser.contents
-  >>> browser.getLink('Tree Fern').click()
+  >>> browser.getLink('treefern').click()
+  >>> testing.printElement(browser, "//h1")
+  <h1>Tree Fern</h1>

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/authentication.py
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/authentication.py	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/authentication.py	2007-07-24 12:43:02 UTC (rev 78308)
@@ -9,8 +9,17 @@
 from z3c.authentication.simple import member
 from z3c.authentication.simple import group
 
+import grok
+
 from tfws.website import interfaces
+from tfws.website import roles
+from tfws.website import permissions
 
+grok.define_permission(permissions.VIEW)
+grok.define_permission(permissions.MANAGEUSERS)
+grok.define_permission(permissions.MANAGESITE)
+grok.define_permission(permissions.MANAGECONTENT)
+
 def setup_site_auth(auth):    
 
     # setup credentials plugin
@@ -37,13 +46,12 @@
     # setup 'Members' group
     grp =  group.Group(u'Members', u'Members')
     groups.addGroup('Members', grp) 
-    prm.assignRoleToPrincipal('tfws.website.Member', 'groups.Members')
+    prm.assignRoleToPrincipal(roles.MEMBER, 'groups.Members')
 
     # setup 'Administrators' group
     grp =  group.Group(u'Administrators', u'Administrators')
     groups.addGroup('Administrators', grp) 
-    prm.assignRoleToPrincipal('tfws.website.Administrator', 
-        'groups.Administrators')
+    prm.assignRoleToPrincipal(roles.ADMINISTRATOR, 'groups.Administrators')
 
 def role_factory(*args):
     def factory():

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/browser/browser.py
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/browser/browser.py	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/browser/browser.py	2007-07-24 12:43:02 UTC (rev 78308)
@@ -1,9 +1,16 @@
-from zope.traversing.browser import absoluteURL
+import zope.schema
+import zope.event
+import zope.lifecycleevent
+from zope.traversing import api
 from zope.app.folder.interfaces import IRootFolder
 from zope.dublincore.interfaces import IZopeDublinCore
-from zope.traversing import api
+from zope.pagetemplate.interfaces import IPageTemplate
+from zope.traversing.browser import absoluteURL
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
 
-from z3c.form import form, field
+from z3c.form import form, field, group, button
+from z3c.formui import layout
+from z3c.configurator import configurator
 
 from zc.table import column
 from zc.table import table
@@ -13,17 +20,19 @@
 import mars.layer
 import mars.view
 import mars.template
+import mars.viewlet
+import mars.form
 
 from tfws.website import interfaces
+from tfws.website import permissions
+from tfws.website import site
 from tfws.website.browser import formatter
 from tfws.website.layer import IWebSiteLayer
 from tfws.website.i18n import MessageFactory as _
 
+
 mars.layer.layer(IWebSiteLayer)
 
-# rremove this defintion
-grok.define_permission('tfws.ManageSites')
-
 class CheckboxColumn(column.Column):
 
     def renderCell(self, item, formatter):
@@ -51,7 +60,11 @@
 
 class Index(mars.view.PageletView):
     grok.context(IRootFolder)
-    grok.require('tfws.ManageSites')
+    grok.require(permissions.MANAGESITE)
+    # this allows the standard http auth to get called, @@absolute_url
+    # wasn't able to be rendered with Unauthorized
+    # See zope.traversing.browser.absoluteurl.py
+    __name__ = u'bug-fix'
 
     columns = (
         CheckboxColumn(_('Sel')),
@@ -91,10 +104,82 @@
             else:
                 self.status = _('No sites were selected.')
 
-
 class IndexTemplate(mars.template.TemplateFactory):
     """layout template for `home`"""
     grok.context(Index)
     grok.template('index.pt') 
     
+class AddSite(mars.form.FormView, layout.AddFormLayoutSupport, 
+                              group.GroupForm, 
+                              form.AddForm):
+    """ Add form for tfws.website."""
+    grok.name('add')
+    grok.context(IRootFolder)
 
+    label = _('Add a Tree Fern WebSite')
+    contentName = None
+    data = None
+    _finishedAdd = False
+
+    fields = field.Fields(zope.schema.TextLine(__name__='__name__',
+                                title=_(u"name"), required=True))
+
+    groups = (site.ContentMetaDataGroup, site.InitialManagerGroup)
+
+    @button.buttonAndHandler(_('Add'), name='add')
+    def handleAdd(self, action):
+        data, errors = self.extractData()
+        if errors:
+            self.status = self.formErrorsMessage
+            return
+        obj = self.create(data)
+        zope.event.notify(zope.lifecycleevent.ObjectCreatedEvent(obj))
+        result = self.add(obj)
+        if result is not None:
+            self._finishedAdd = True
+
+    def create(self, data):
+        self.data = data
+        # get form data
+        title = data.get('title', u'')
+        description = data.get('description', u'')
+        self.contentName = data.get('__name__', u'')
+
+        # Create site
+        return site.WebSite(title, description)
+
+    def add(self, obj):
+        data = self.data
+        # Add the site
+        if self.context.get(self.contentName) is not None:
+            self.status = _('Site with name already exist.')
+            self._finishedAdd = False
+            return None
+        self.context[self.contentName] = obj
+
+        # Configure the new site
+        configurator.configure(obj, data)
+
+        self._finishedAdd = True
+        return obj
+
+    def nextURL(self):
+        return self.request.URL[-1]
+
+#from zope.security.interfaces import Unauthorized, IUnauthorized
+#from zope.publisher.interfaces.http import IHTTPRequest
+#from zope.traversing.browser.interfaces import IAbsoluteURL
+#class AbsoluteURL(grok.MultiAdapter):
+#    zope.interface.implements(IAbsoluteURL, IHTTPRequest)
+#    grok.provides(IAbsoluteURL)
+#    grok.adapts(IUnauthorized, IHTTPRequest)
+
+#    def __init__(self, context, request):
+#        self.context = context
+#        self.context.__name__ = u'Unauthorized'
+#        self.request = request
+
+#    def __str__(self):
+#        return 'I am absolute url'
+
+#    __call__ = __str__

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/browser/index.pt
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/browser/index.pt	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/browser/index.pt	2007-07-24 12:43:02 UTC (rev 78308)
@@ -1,4 +1,4 @@
-<h1>Tree Fern Web Site Demos</h1>
+<h1>Tree Fern Web Site Demo</h1>
 <div class="message"
      tal:condition="view/status"
      tal:content="view/status"

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/configure.zcml
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/configure.zcml	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/configure.zcml	2007-07-24 12:43:02 UTC (rev 78308)
@@ -23,6 +23,7 @@
 
   <include package="z3c.breadcrumb" />
   <include package="z3c.form" />
+  <include package="z3c.formjs" />
   <include package="z3c.formui" />
   <include package="z3c.layer.pagelet" />
   <include package="z3c.macro" />
@@ -42,7 +43,6 @@
   <include package="mars.adapter" file="meta.zcml" />
   <include package="mars.form" file="meta.zcml" />
 
-  <include file="security.zcml" />
 <!-- grok the package for components and registrations -->
   <grok:grok package="." />
 

Added: Sandbox/darrylcousins/tfws.website/src/tfws/website/folderindex.py
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/folderindex.py	                        (rev 0)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/folderindex.py	2007-07-24 12:43:02 UTC (rev 78308)
@@ -0,0 +1,58 @@
+import  zope.interface
+import  zope.schema
+
+import grok
+
+from tfws.website import interfaces
+
+class FolderIndexForContent(grok.Adapter):
+    """Adapt possible folder to folder.
+    """
+    grok.context(interfaces.IContent)
+    grok.provides(interfaces.IIndexFolder)
+
+    def __init__(self, context):
+        self.context = context
+
+    def setFolderIndex(self, item=None):
+        # remove any current index
+        for page in self.context.values():
+            if interfaces.IFolderIndex.providedBy(page):
+                zope.interface.directlyProvides(page, 
+                    zope.interface.directlyProvidedBy(page) - \
+                                         interfaces.IFolderIndex)
+        # set the index page
+        if item is not None:
+            zope.interface.directlyProvides(item, 
+                    interfaces.IFolderIndex, 
+                    zope.interface.directlyProvidedBy(item))
+
+class FolderIndexSource(object):
+    """A source of items in a folder."""
+
+    def __call__(self, context):
+
+        result = []
+        for key in context.values():
+            item = context[key]
+            term = zope.schema.vocabulary.SimpleTerm(item, token=item.title)
+            result.append(term)
+        return zope.schema.vocabulary.SimpleVocabulary(result)
+
+grok.global_utility(FolderIndexSource, 
+                    provides=zope.schema.interfaces.IVocabularyFactory,
+                    name=u'Folder Index Source')
+
+
+ at grok.subscribe(interfaces.IPage, grok.IObjectCopiedEvent)
+def removeFolderIndexOnCopiedObject(item, event):
+    """Remove IFolderIndex on copied objects.
+    
+    This handler removes the IFolderIndex from a copied object after
+    copy/paste. This is needed for clean up copied objects because we can't have
+    more the one object marked with IFolderIndex.
+
+    """
+    if interfaces.IFolderIndex.providedBy(item):
+            zope.interface.directlyProvides(item, 
+            zope.interface.directlyProvidedBy(item) - interfaces.IFolderIndex)


Property changes on: Sandbox/darrylcousins/tfws.website/src/tfws/website/folderindex.py
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/interfaces.py
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/interfaces.py	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/interfaces.py	2007-07-24 12:43:02 UTC (rev 78308)
@@ -25,11 +25,35 @@
         default=u'',
         required=False)
 
+    keyword = zope.schema.Text(
+        title=_(u'Keyword'),
+        description=_(u'Keyword of the content.'),
+        default=u'',
+        required=False)
 
+    body = zope.schema.Text(
+        title=_(u'Body'),
+        description=_(u'Body is the main part of the page.'),
+        default=u'',
+        required=False)
+
+
 class IWebSite(IContent):
     """grok/mars/z3c demo site."""
 
 
+class IPage(IContent):
+    """Page for site."""
+
+
+class IFolderIndex(zope.interface.Interface):
+    """Marker interface for page providing IFolderIndex"""
+
+
+class IIndexFolder(zope.interface.Interface):
+    """Marker interface for adapting to IContent"""
+
+
 class IWebSiteMember(IMember):
     """WebSite member."""
 

Added: Sandbox/darrylcousins/tfws.website/src/tfws/website/page.py
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/page.py	                        (rev 0)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/page.py	2007-07-24 12:43:02 UTC (rev 78308)
@@ -0,0 +1,35 @@
+import zope.component
+import zope.interface
+from zope.schema.fieldproperty import FieldProperty
+
+import grok
+
+import mars.layer
+
+from tfws.website import interfaces
+from tfws.website.layer import IWebSiteLayer
+
+mars.layer.layer(IWebSiteLayer)
+
+class Page(grok.Container):
+    """Mars/Grok/Z3C page.
+
+    """
+    zope.interface.implements(interfaces.IPage)
+
+    title = FieldProperty(interfaces.IPage['title'])
+    description = FieldProperty(interfaces.IPage['description'])
+    keyword = FieldProperty(interfaces.IPage['keyword'])
+    body = FieldProperty(interfaces.IPage['body'])
+
+    def __init__(self, title=u'', description=u'',
+                       keyword=u'', body=u''):
+        super(Page, self).__init__()
+        self.title = title
+        self.description = description
+        self.keyword = keyword
+        self.body = body
+
+    def __repr__(self):
+        return '<%s %r>' % (self.__class__.__name__, self.__name__)
+


Property changes on: Sandbox/darrylcousins/tfws.website/src/tfws/website/page.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: Sandbox/darrylcousins/tfws.website/src/tfws/website/permissions.py
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/permissions.py	                        (rev 0)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/permissions.py	2007-07-24 12:43:02 UTC (rev 78308)
@@ -0,0 +1,11 @@
+# Allows to edit content.
+MANAGECONTENT = 'tfws.website.ManageContent'
+
+# Allows to edit site components.
+MANAGESITE = 'tfws.website.ManageSite'
+
+# Allows to manage all users.
+MANAGEUSERS = 'tfws.website.ManageUsers'
+
+# Allows to view site
+VIEW = 'tfws.website.View'


Property changes on: Sandbox/darrylcousins/tfws.website/src/tfws/website/permissions.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: Sandbox/darrylcousins/tfws.website/src/tfws/website/roles.py
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/roles.py	                        (rev 0)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/roles.py	2007-07-24 12:43:02 UTC (rev 78308)
@@ -0,0 +1,2 @@
+ADMINISTRATOR = 'tfws.website.Administrator'
+MEMBER = 'tfws.website.Member'


Property changes on: Sandbox/darrylcousins/tfws.website/src/tfws/website/roles.py
___________________________________________________________________
Name: svn:keywords
   + Id

Deleted: Sandbox/darrylcousins/tfws.website/src/tfws/website/security.zcml
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/security.zcml	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/security.zcml	2007-07-24 12:43:02 UTC (rev 78308)
@@ -1,70 +0,0 @@
-<configure
-    xmlns="http://namespaces.zope.org/zope">
-
-  <!-- permissions -->
-  <permission
-      id="tfws.website.ManageContent"
-      title="Manage Content"
-      description="Allows to edit content."
-      />
-
-  <permission
-      id="tfws.website.ViewSite"
-      title="View Site"
-      description="View site."
-      />
-
-  <permission
-      id="tfws.website.ManageSite"
-      title="Manage Site"
-      description="Allows to edit site components."
-      />
-
-  <permission
-      id="tfws.website.ManageUsers"
-      title="Manage Users"
-      description="Allows to manage all users."
-      />
-
-
-  <!-- Administrator role -->
-  <role
-      id="tfws.website.Administrator"
-      title="WebSite Administrator"
-      description="Administrators can manage the site and tests"
-      />
-
-  <grant
-      permission="tfws.website.ManageContent"
-      role="tfws.website.Administrator"
-      />
-
-  <grant
-      permission="tfws.website.ViewSite"
-      role="tfws.website.Administrator"
-      />
-
-  <grant
-      permission="tfws.website.ManageSite"
-      role="tfws.website.Administrator"
-      />
-
-  <grant
-      permission="tfws.website.ManageUsers"
-      role="tfws.website.Administrator"
-      />
-
-
-  <!-- Member role -->
-  <role
-      id="tfws.website.Member"
-      title="WebSite Member"
-      description="Member can edit content"
-      />
-
-  <grant
-      permission="tfws.website.ManageContent"
-      role="tfws.website.Member"
-      />
-
-</configure>

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/site.py
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/site.py	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/site.py	2007-07-24 12:43:02 UTC (rev 78308)
@@ -9,12 +9,13 @@
 from zope.app.intid.interfaces import IIntIds
 from zope.app.catalog.catalog import Catalog
 from zope.app.catalog.interfaces import ICatalog
-from zope.app.folder.interfaces import IRootFolder
 from zope.app.security.interfaces import IAuthentication
+from zope.app.securitypolicy.interfaces import IRolePermissionManager
 
 from z3c.form import form, field, button, group
+from z3c.form.interfaces import IWidgets
 from z3c.formui import layout
-from z3c.formjs import jsaction, jsevent, ajax
+from z3c.formjs import jsaction, jsevent, jsvalidator, ajax
 from z3c.configurator import configurator
 from z3c.authentication.simple.authentication import SimpleAuthentication
 
@@ -27,6 +28,8 @@
 
 from tfws.website import interfaces
 from tfws.website import authentication
+from tfws.website import permissions
+from tfws.website import roles
 from tfws.website.catalog import setup_catalog
 from tfws.website.layer import IWebSiteLayer
 from tfws.website.i18n import MessageFactory as _
@@ -48,20 +51,30 @@
     title = FieldProperty(interfaces.IWebSite['title'])
     description = FieldProperty(interfaces.IWebSite['description'])
 
-    def __init__(self, title=None):
+    def __init__(self, title=u'', description=u''):
         super(WebSite, self).__init__()
-        if title is not None:
-            self.title = title
+        self.title = title
+        self.description = description
 
     def __repr__(self):
         return '<%s %r>' % (self.__class__.__name__, self.__name__)
 
-
-class Index(mars.form.FormView, layout.FormLayoutSupport, form.DisplayForm):
+class Index(mars.view.PageletView):
     """Temp display view for site"""
-    fields = field.Fields(interfaces.IWebSite).omit('__parent__', 'title')
 
+    def render(self):
+        """First try to locate an index page for the site"""
+        for page in self.context.values():
+            if interfaces.IFolderIndex.providedBy(page):
+                view = zope.component.getMultiAdapter(
+                        (page, self.request), name='index')
+                return view(page, self.request).render()
+        template = zope.component.getMultiAdapter(
+            (self, self.request), self._template_interface, 
+            name=self._template_name)
+        return template(self)
 
+
 class IndexTemplate(mars.template.TemplateFactory):
     grok.context(Index)
     grok.template('templates/index.pt')
@@ -74,14 +87,15 @@
         'member.lastName', 'member.email')
 
 
-class SiteMetaDataGroup(group.Group):
+class ContentMetaDataGroup(group.Group):
     label = u'Site Metadata'
     fields = field.Fields(interfaces.IWebSite).select('title', 
                                                       'description')
 
-class IEditButtons(zope.interface.Interface):
-    apply = jsaction.JSButton(title=_('Apply'))
-    applyView = jsaction.JSButton(title=_('Apply and View'))
+# try this again later
+#class IEditButtons(zope.interface.Interface):
+#    apply = jsaction.JSButton(title=_('Apply'))
+#    applyView = jsaction.JSButton(title=_('Apply and View'))
 
 
 class Edit(mars.form.FormView, layout.FormLayoutSupport, 
@@ -90,7 +104,7 @@
     grok.name('edit')
     form.extends(form.EditForm)
     label = u'Tree Fern Web Site Edit Form'
-    groups = (SiteMetaDataGroup,)
+    groups = (ContentMetaDataGroup,)
 
     @button.buttonAndHandler(u'Apply and View', name='applyView')
     def handleApplyView(self, action):
@@ -100,74 +114,7 @@
             self.request.response.redirect(url)
 
 
-# use this button to call the ajax method
-class IAddButtons(zope.interface.Interface):
-    add = jsaction.JSButton(title=_('Add'))
 
-
-class Add(mars.form.FormView, layout.AddFormLayoutSupport, 
-                              group.GroupForm, form.AddForm):
-    """ Add form for tfws.website."""
-    grok.name('add')
-    grok.context(IRootFolder)
-
-    label = _('Add a Tree Fern WebSite')
-    contentName = None
-    data = None
-
-    fields = field.Fields(zope.schema.TextLine(__name__='__name__',
-                                title=_(u"name"), required=True))
-
-    groups = (SiteMetaDataGroup, InitialManagerGroup)
-    #buttons = button.Buttons(IAddButtons)
-
-# I want this to be an ajax method
-    @button.buttonAndHandler(u'Add', name='add')
-    def handleAdd(self, action):
-        data, errors = self.extractData()
-        if errors:
-            self.status = self.formErrorsMessage
-            return
-        obj = self.create(data)
-        zope.event.notify(zope.lifecycleevent.ObjectCreatedEvent(obj))
-        result = self.add(obj)
-        if result is not None:
-            self._finishedAdd = True
-
-    #def handleAdd(self, event, selector):
-    #@ajax.handler
-    #@jsaction.JSButton(title=_('Test'))
-    #def callAdd(self, event, selector):
-    #    return 'alert("hello")'
-
-    def create(self, data):
-        self.data = data
-        # get form data
-        title = data.get('title', u'')
-        self.contentName = data.get('__name__', u'')
-
-        # Create site
-        return WebSite(title)
-
-    def add(self, obj):
-        data = self.data
-        # Add the site
-        if self.context.get(self.contentName) is not None:
-            self.status = _('Site with name already exist.')
-            self._finishedAdd = False
-            return None
-        self.context[self.contentName] = obj
-
-        # Configure the new site
-        configurator.configure(obj, data)
-
-        self._finishedAdd = True
-        return obj
-
-    def nextURL(self):
-        return self.request.URL[-1]
-
-
 class SiteConfigurator(grok.Adapter, configurator.ConfigurationPluginBase):
     """Configure the site, this has access to the data submitted by the add
     form as well as local utilities defined with grok.local_utility."""
@@ -189,3 +136,17 @@
         adminGroup.setPrincipals(
             adminGroup.principals + (admin.__name__,), check=False)
 
+        # grant permissions to roles
+        role_manager = IRolePermissionManager(self.context)
+        role_manager.grantPermissionToRole(permissions.MANAGESITE, 
+                                           roles.ADMINISTRATOR)
+        role_manager.grantPermissionToRole(permissions.MANAGECONTENT, 
+                                           roles.ADMINISTRATOR)
+        role_manager.grantPermissionToRole(permissions.MANAGEUSERS, 
+                                           roles.ADMINISTRATOR)
+        role_manager.grantPermissionToRole(permissions.VIEW, 
+                                           roles.ADMINISTRATOR)
+        role_manager.grantPermissionToRole(permissions.MANAGECONTENT, 
+                                           roles.MEMBER)
+        role_manager.grantPermissionToRole(permissions.VIEW, 
+                                           roles.MEMBER)

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/site.txt
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/site.txt	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/site.txt	2007-07-24 12:43:02 UTC (rev 78308)
@@ -8,21 +8,72 @@
 
 Imports for later.
 
+    >>> import os
     >>> import zope.component
+    >>> import tfws.website
     >>> from zope.app.security.interfaces import IAuthentication
     >>> from zope.app.catalog.interfaces import ICatalog
+    >>> from tfws.website import interfaces
+    >>> from tfws.website import site
+    >>> from tfws.website.skin import skin
 
+And a request for later.
+
+    >>> from zope.publisher.browser import TestRequest
+    >>> request = TestRequest()
+
 Create a site
 
     >>> from tfws.website.site import WebSite
-    >>> root['treefern'] = site = WebSite(u'Tree Fern')
+    >>> root['treefern'] = website = WebSite(u'Tree Fern')
 
 It has an authentication utility and a catalog.
 
-    >>> auth = zope.component.getUtility(IAuthentication, context=site)
+    >>> auth = zope.component.getUtility(IAuthentication, context=website)
     >>> print auth
     <z3c.authentication.simple.authentication.SimpleAuthentication object at 0x...>
-    >>> catalog = zope.component.getUtility(ICatalog, context=site)
+    >>> catalog = zope.component.getUtility(ICatalog, context=website)
     >>> print catalog
     <zope.app.catalog.catalog.Catalog object at 0x...>
 
+Page
+----
+
+Create a page.
+
+    >>> from tfws.website.page import Page
+    >>> website['page-one'] = page = Page(u'Tree Fern')
+    >>> interfaces.IFolderIndex.providedBy(page)
+    False
+
+Set the page as the default index for the site.
+
+    >>> folder = interfaces.IIndexFolder(website)
+    >>> folder.setFolderIndex(page)
+    >>> interfaces.IFolderIndex.providedBy(page)
+    True
+
+Remove the index.
+
+    >>> folder.setFolderIndex(None)
+    >>> interfaces.IFolderIndex.providedBy(page)
+    False
+
+View the site
+-------------
+
+I haven't figure a way to ``grok`` in the tests except to do it explicitly so
+here we grok the view we want to test.
+
+    >>> from mars.view.meta import PageletViewGrokker
+    >>> PageletViewGrokker().grok('', site.Index, WebSite, module_info, None)
+    True
+    >>> from mars.template.meta import TemplateFactoryGrokker
+    >>> TemplateFactoryGrokker().grok('', site.IndexTemplate, None, module_info, None)
+    True
+    >>> from mars.template.meta import LayoutFactoryGrokker
+    >>> module_info.path = skin.__file__
+    >>> LayoutFactoryGrokker().grok('', skin.Layout, None, module_info, None)
+    True
+    >>> view = zope.component.getMultiAdapter((website, request), name='index')
+    >>> #print view()

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/skin.py
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/skin.py	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/skin.py	2007-07-24 12:43:02 UTC (rev 78308)
@@ -1,12 +1,14 @@
 import zope.component
 import zope.interface
-from zope.viewlet.viewlet import CSSViewlet
+from zope.viewlet.viewlet import CSSViewlet, JavaScriptViewlet
 from zope.publisher.interfaces.browser import IBrowserPage
 from zope.publisher.interfaces.http import IHTTPRequest
 from zope.traversing.browser import absoluteURL
 from zope.app.component import hooks
 
 import z3c.formui
+from z3c.formjs import jsevent
+from z3c.formjs.interfaces import IHaveJSSubscriptions
 
 from jquery.javascript.browser import JQueryJavaScriptViewlet
 
@@ -26,7 +28,7 @@
     """The ``tfwswebsite`` browser skin."""
     pass
 
-class Template(mars.template.LayoutFactory):
+class Layout(mars.template.LayoutFactory):
     """main template for pages (note the context!)"""
     grok.context(IBrowserPage)
     grok.template('template.pt')
@@ -36,12 +38,7 @@
     grok.name('INavigationColumn')
     grok.context(zope.interface.Interface)
 
-class CSSManager(mars.viewlet.ViewletManager):
-    """css viewletmanager"""
-    zope.interface.implements(z3c.formui.interfaces.ICSS)
-    grok.name('ICSS')
-    grok.context(zope.interface.Interface)
-
+### javascript viewlet manager and viewlets
 class JavaScriptManager(mars.viewlet.ViewletManager):
     """javascript viewletmanager"""
     grok.name('IJavaScript')
@@ -54,6 +51,33 @@
 # TODO use mars.viewlet.view to set to a jquery view marker
     mars.viewlet.manager(JavaScriptManager)
 
+WebsiteJSViewlet = JavaScriptViewlet('website.js')
+class WebSiteJavaScriptViewlet(mars.viewlet.SimpleViewlet, WebsiteJSViewlet):
+    """js viewlet"""
+    grok.name('website.js')
+    grok.context(zope.interface.Interface)
+    mars.viewlet.manager(JavaScriptManager)
+
+class WebSiteJavaScript(mars.resource.ResourceFactory):
+    """resources (++resource++website.js)"""
+    grok.name('website.js')
+    mars.resource.file('website.js')
+
+class SubscriptionJavaScriptViewlet(mars.viewlet.SimpleViewlet,
+                                   jsevent.JSSubscriptionsViewlet):
+    """subscriptions viewlet"""
+    grok.name('subscriptions')
+    grok.context(zope.interface.Interface)
+    mars.viewlet.manager(JavaScriptManager)
+    mars.viewlet.view(IHaveJSSubscriptions)
+
+### css viewlet manager and viewlets
+class CSSManager(mars.viewlet.ViewletManager):
+    """css viewletmanager"""
+    zope.interface.implements(z3c.formui.interfaces.ICSS)
+    grok.name('ICSS')
+    grok.context(zope.interface.Interface)
+
 WebsiteCSSViewlet = CSSViewlet('website.css')
 class WebSiteCSSViewlet(mars.viewlet.SimpleViewlet, WebsiteCSSViewlet):
     """css viewlet"""
@@ -76,7 +100,6 @@
 class SiteURL(grok.MultiAdapter):
     """Provides siteURL to all context"""
     grok.name('siteURL')
-    grok.context(zope.interface.Interface)
     zope.interface.implements(ISiteURL)
     zope.component.adapts(zope.interface.Interface, IHTTPRequest)
 

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/template.pt
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/template.pt	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/template.pt	2007-07-24 12:43:02 UTC (rev 78308)
@@ -6,6 +6,13 @@
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 <meta http-equiv="cache-control" content="no-cache" />
 <meta http-equiv="pragma" content="no-cache" />
+<script type="text/javascript"
+    tal:define="contexturl context/@@absolute_url; 
+                viewurl request/URL"
+    tal:content="string:
+	var contextURL = '${contexturl}';
+	var viewURL = '${viewurl}';"> 
+</script>
 <script tal:replace="structure provider:IJavaScript"> </script>
 <style tal:replace="structure provider:ICSS"> 
 </style>

Added: Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/website.js
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/website.js	                        (rev 0)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/skin/website.js	2007-07-24 12:43:02 UTC (rev 78308)
@@ -0,0 +1,18 @@
+function applyErrorMessage(widgetId, msg) {
+    element = $('#' + widgetId + '-row div.error');
+    if (element) {
+        element.remove();
+    }
+    $('#' + widgetId + '-row').append(
+        '<div class="error">' + msg+  '</div>');
+
+    if (msg != '') {
+        $('#' + widgetId).removeClass('valid');
+        $('#' + widgetId).addClass('invalid');
+    }
+    else {
+        $('#' + widgetId).removeClass('invalid');
+        $('#' + widgetId).addClass('valid');
+    }
+}
+

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/templates/index.pt
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/templates/index.pt	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/templates/index.pt	2007-07-24 12:43:02 UTC (rev 78308)
@@ -1,21 +1,2 @@
 <h1 tal:content="context/title">Tree Fern</h1>
 
-        <tal:block repeat="widget view/widgets/values">
-          <div id="" class="row"
-               tal:attributes="id string:${widget/id}-row"
-               tal:condition="python:widget.mode != 'hidden'">
-            <metal:block define-macro="widget-row">
-              <div class="label">
-                <label tal:attributes="for widget/id">
-                  <span i18n:translate=""
-                      tal:content="widget/label">label</span>
-                  <span class="required"
-                        tal:condition="widget/required">*</span>
-                </label>
-              </div>
-              <div class="widget" tal:content="structure widget/render">
-                <input type="text" size="24" value="" />
-              </div>
-            </metal:block>
-          </div>
-        </tal:block>

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/testing.py
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/testing.py	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/testing.py	2007-07-24 12:43:02 UTC (rev 78308)
@@ -1,9 +1,24 @@
 import os.path
 import lxml.etree
 
-import tfws.website
+import zope.interface
 from zope.app.testing.functional import ZCMLLayer
+from zope.app.testing import setup, ztapi
+from zope.app.pagetemplate import metaconfigure
+from zope.contentprovider import tales
 
+from zope.annotation.interfaces import IAnnotatable
+from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
+from zope.app.securitypolicy.interfaces import IRolePermissionManager
+from zope.app.securitypolicy.principalrole \
+     import AnnotationPrincipalRoleManager
+from zope.app.securitypolicy.rolepermission \
+     import AnnotationRolePermissionManager
+
+import grok
+from martian.interfaces import IModuleInfo
+import tfws.website
+
 ftesting_zcml = os.path.join(
     os.path.dirname(tfws.website.__file__), 'ftesting.zcml')
 TestLayer = ZCMLLayer(ftesting_zcml, __name__, 'FunctionalLayer')
@@ -17,3 +32,24 @@
     for elem in result:
         print elem
 
+class ModuleInfo(object):
+    zope.interface.implements(IModuleInfo)
+    path = tfws.website.__file__
+    package_dotted_name = 'tfws.website'
+
+    def getAnnotation(self, name, default):
+        return default
+
+def setUp(test):
+    root = setup.placefulSetUp(site=True)
+    test.globs['root'] = root
+    test.globs['module_info'] = ModuleInfo()
+    ztapi.provideAdapter(IAnnotatable, IPrincipalRoleManager,
+                            AnnotationPrincipalRoleManager)
+    ztapi.provideAdapter(IAnnotatable, IRolePermissionManager,
+                            AnnotationRolePermissionManager)
+    metaconfigure.registerType('provider', tales.TALESProviderExpression)
+
+def tearDown(test):
+    setup.placefulTearDown()
+

Modified: Sandbox/darrylcousins/tfws.website/src/tfws/website/tests.py
===================================================================
--- Sandbox/darrylcousins/tfws.website/src/tfws/website/tests.py	2007-07-24 12:22:48 UTC (rev 78307)
+++ Sandbox/darrylcousins/tfws.website/src/tfws/website/tests.py	2007-07-24 12:43:02 UTC (rev 78308)
@@ -1,27 +1,14 @@
 import unittest
 from zope.testing import doctest
-from zope.app.testing import setup, ztapi
 
-from zope.annotation.interfaces import IAnnotatable
-from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
-from zope.app.securitypolicy.principalrole \
-     import AnnotationPrincipalRoleManager
+from tfws.website import testing
 
 optionflags = doctest.NORMALIZE_WHITESPACE + doctest.ELLIPSIS
 
-def setUp(test):
-    root = setup.placefulSetUp(site=True)
-    test.globs['root'] = root
-    ztapi.provideAdapter(IAnnotatable, IPrincipalRoleManager,
-                            AnnotationPrincipalRoleManager)
-
-def tearDown(test):
-    setup.placefulTearDown()
-
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTests([doctest.DocFileSuite('site.txt',
-                       setUp=setUp, tearDown=tearDown,
+                       setUp=testing.setUp, tearDown=testing.tearDown,
                        optionflags=optionflags),
                    ])
 



More information about the Checkins mailing list