[Checkins] SVN: Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/ Started working on membership management. Functionally complete but needs tidying, tests and registration.

Charlie Clark charlie at begeistert.org
Thu Sep 23 07:06:12 EDT 2010


Log message for revision 116761:
  Started working on membership management. Functionally complete but needs tidying, tests and registration.

Changed:
  U   Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/TODO.txt
  U   Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/configure.zcml
  A   Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/delete_members.pt
  A   Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/members.pt
  A   Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/members.py

-=-
Modified: Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/TODO.txt
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/TODO.txt	2010-09-23 11:05:32 UTC (rev 116760)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/TODO.txt	2010-09-23 11:06:12 UTC (rev 116761)
@@ -2,19 +2,19 @@
 
   [x] login:
 
-      login_form_template -> templates/login.pt
+      login_form_template -> login.pt
       loggged_in.py -> LoggedIn
-      logged_in.pt -> templates/logged_in.pt
+      logged_in.pt -> logged_in.pt
 
   [x] logout:
 
       logout.py -> Logout
-      logged_out.pt -> templates/logout.pt
+      logged_out.pt -> logout.pt
 
   [x] mail password:
 
       mail_password_form -> MailPasswordFormView
-      mail_password_form.pt -> templates/mail_password.pt
+      mail_password_form.pt -> mail_password.pt
       mail_password_response.pt -> joined.pt
 
   [x] join:
@@ -24,14 +24,24 @@
       members_add_control.py -> Join
       join_form_template -> templates/join.pt
 
-  [ ] preferences:
+  [x] preferences:
 
       preference_form.pt -> preferences.py
       personalize.py -> preferences.py
 
   [ ] password:
+      
+      password_form.py -> password.py
+      password_form_template -> password.pt
 
   [ ] member roster:
+      
+      members_manage_form.py
+      members_manage_template.pt
+      members_add_control.py
+      members_delete_control.py
+      members_delete_form.py
+      members_delete_template_template.py
 
 
   [ ] complete this todo list

Modified: Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/configure.zcml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/configure.zcml	2010-09-23 11:05:32 UTC (rev 116760)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/configure.zcml	2010-09-23 11:06:12 UTC (rev 116761)
@@ -71,5 +71,13 @@
       class=".password.Password"
       permission="cmf.SetOwnPassword"
       />
+      
+  <browser:page
+      for="Products.CMFCore.interfaces.ISiteRoot"
+      layer="Products.CMFDefault.interfaces.ICMFDefaultSkin"
+      name="members.html"
+      class=".members.Manage"
+      permission="cmf.ListPortalMembers"
+      />
   
 </configure>

Added: Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/delete_members.pt
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/delete_members.pt	                        (rev 0)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/delete_members.pt	2010-09-23 11:06:12 UTC (rev 116761)
@@ -0,0 +1,25 @@
+<html metal:use-macro="context/@@standard_macros/page">
+<body>
+
+<metal:slot metal:fill-slot="body" i18n:domain="cmf_default">
+   <h1 i18n:translate="">Delete Members</h1>
+   
+   <form action="." method="post" tal:attributes="action request/ACTUAL_URL">
+
+  <tal:block repeat="widget view/widgets"
+             replace="structure widget/hidden" />
+  
+ <p i18n:translate="">The following members - including all their data, home
+  folders and roles - are selected for deletion:</p>
+ <p><strong tal:content="view/status">MEMBERS</strong></p>
+ 
+ <div class="buttons">
+   <tal:loop tal:repeat="action view/actions"
+    tal:replace="structure action/render" />
+ </div>
+
+</form>
+</metal:slot>
+
+</body>
+</html>

Added: Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/members.pt
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/members.pt	                        (rev 0)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/members.pt	2010-09-23 11:06:12 UTC (rev 116761)
@@ -0,0 +1,54 @@
+<html metal:use-macro="context/@@standard_macros/page">
+
+<body>
+
+<metal:slot metal:fill-slot="body" i18n:domain="cmf_default">
+<h1 i18n:translate="">Manage Members</h1>
+
+<p class="status"
+  tal:condition="exists: request/portal_status_message"
+  tal:content="request/portal_status_message"></p>
+
+<form action="." method="post" tal:attributes="action request/ACTUAL_URL">
+  
+  <tal:block repeat="widget view/hidden_widgets"
+             replace="structure widget/hidden" />
+ <table class="BatchTable" tal:condition="view/_get_items">
+  <thead>
+   <tr class="list-header">
+    <td>&nbsp;</td>
+    <th i18n:translate="">Member</th>
+    <th i18n:translate="">E-mail Address</th>
+    <th i18n:translate="">Last Login</th>
+   </tr>
+  </thead>
+     <tbody>
+       <tr tal:repeat="item view/_get_items"
+           tal:attributes="class python: (repeat['item'].even() and 'row-hilite') or None">
+         <td><input class="checkboxType" 
+           tal:attributes="id string:${item/id}.select;
+                           name string:${item/id}.select"
+                 type="checkbox" value="on"/></td>
+          <td><a href="" tal:content="item/id" tal:attributes="href item/absolute_url"></a>
+          </td>
+          <td><a href="" tal:content="item/email" tal:attributes="href string:mailto:${item/email}"></a></td>
+          <td tal:content="python: item.login_time == '2000/01/01' and '---' or item.login_time.Date()"></td>         
+      </tr>
+
+     </tbody>
+     </table>
+  <div class="buttons">
+    <tal:loop tal:repeat="action view/actions"
+     tal:replace="structure action/render" />
+  </div>
+  
+ <p tal:condition="not: view/_get_items" i18n:translate="">Currently there
+  are no members registered.</p>
+  <metal:macro metal:use-macro="context/@@batch_widget/navigation" />
+  <metal:macro metal:use-macro="context/@@batch_widget/pagination" />
+
+</form>
+</metal:slot>
+
+</body>
+</html>

Added: Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/members.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/members.py	                        (rev 0)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/members.py	2010-09-23 11:06:12 UTC (rev 116761)
@@ -0,0 +1,136 @@
+"""
+Forms for managing members
+"""
+from logging import getLogger
+
+LOG = getLogger("Manage Members Form")
+
+from zope.interface import Interface
+from zope.formlib import form
+from zope.schema import Bool, TextLine, Date, getFieldsInOrder, List, Choice
+
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+
+from Products.CMFCore.utils import getToolByName
+from Products.CMFDefault.formlib.form import EditFormBase
+from Products.CMFDefault.formlib.schema import EmailLine
+from Products.CMFDefault.utils import Message as _
+
+from Products.CMFDefault.browser.content.folder import BatchViewBase
+from Products.CMFDefault.browser.content.interfaces import IBatchForm
+
+class IMemberItem(Interface):
+    """Schema for portal members """
+
+    select = Bool(
+        required=False)
+
+    name = TextLine(
+        title=u"Name",
+        required=False,
+        readonly=True
+        )
+        
+    email = TextLine(
+        title=_(u"E-mail Address"),
+        required=False,
+        readonly=True
+        )
+        
+    last_login = Date(
+        title=_(u"Last Login"),
+        required=False,
+        readonly=True
+        )
+
+
+class Manage(BatchViewBase, EditFormBase):
+    
+    label = _(u"Manage Members")
+    template = ViewPageTemplateFile("members.pt")
+    delete_template = ViewPageTemplateFile("delete_members.pt")
+    members_selected = False
+    
+    actions = form.Actions(
+        form.Action(
+            name='new',
+            label=_(u'New...'),
+            success='handle_add',
+            failure='handle_failure'),
+        form.Action(
+            name='select',
+            label=_(u'Delete...'),
+            condition="no_members_selected",
+            validator='validate_items',
+            success='handle_select_for_deletion'
+                ),
+        form.Action(
+            name='delete',
+            label=_(u'Delete'),
+            # condition="members_are_selected",
+            success='handle_delete',
+            failure='handle_failure'),
+        form.Action(
+            name='cancel',
+            label=_(u'Cancel'),
+            condition="members_are_selected",
+                )
+            )
+            
+    hidden_fields = form.FormFields(IBatchForm)
+    
+    def _get_items(self):
+        mtool = self._getTool('portal_membership')
+        return mtool.listMembers()
+        
+    def form_fields(self):
+        """Create content field objects only for batched items"""
+        fields = form.FormFields()
+        for item in self._getBatchObj():
+            for name, field in getFieldsInOrder(IMemberItem):
+                field = form.FormField(field, name, item.id)
+                fields += form.FormFields(field)
+        return fields
+        
+    def setUpWidgets(self, ignore_request=False):
+        """Create widgets for the members"""
+        super(Manage, self).setUpWidgets(ignore_request)
+        self.widgets = form.setUpWidgets(self.form_fields(), self.prefix,
+                    self.context, self.request, ignore_request=ignore_request)
+                
+    def no_members_selected(self, action=None):
+        return not self.members_selected
+        
+    def members_are_selected(self, action=None):
+        return self.members_selected
+
+    def validate_items(self, action=None, data=None):
+        """Check whether any items have been selected for
+        the requested action."""
+        super(Manage, self).validate(action, data)
+        if data is None or data == {}:
+            return [_(u"Please select one or more items first.")]
+        else:
+            return []
+            
+    def selected(self, data):
+        """Return the id of the selected objects"""
+        return (key.split(".")[0] for key, value in data.items()
+                                  if value is True)
+
+    def handle_add(self, action, data):
+        """Redirect to the join form where managers can add users"""
+        return self._setRedirect('portal_actions', 'user/join')
+        
+    def handle_select_for_deletion(self, action, data):
+        """Identify members to be deleted and redirect to confirmation
+        template"""
+        self.status = ", ".join(self.selected(data))
+        return self.delete_template()
+        
+    def handle_delete(self, action, data):
+        mtool = self._getTool('portal_membership')
+        mtool.deleteMembers(self.selected(data))
+        self.members_selected = False
+        return self.request.response.redirect(self.request.URL)
+    
\ No newline at end of file


Property changes on: Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/members.py
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native



More information about the checkins mailing list