new style massmailing view tls-sprint
authorsylvain.thenault@logilab.fr
Wed, 11 Mar 2009 19:54:30 +0100
branchtls-sprint
changeset 1074 c07f3accf04a
parent 1073 e4342c74ed2d
child 1081 f2a85f52b9e5
new style massmailing view
web/test/unittest_form.py
web/views/massmailing.py
--- a/web/test/unittest_form.py	Wed Mar 11 19:54:03 2009 +0100
+++ b/web/test/unittest_form.py	Wed Mar 11 19:54:30 2009 +0100
@@ -34,6 +34,13 @@
         rset = self.execute('EGroup X')
         self.assertTextEquals(self.view('deleteconf', rset, template=None).source,
                               '')
+        
+    def test_massmailing_form(self):
+        self.execute('INSERT EmailAddress X: X address L + "@cubicweb.org", '
+                     'U use_email X WHERE U is EUser, U login L')
+        rset = self.execute('EUser X')
+        self.assertTextEquals(self.view('massmailing', rset, template=None).source,
+                              '')
 
     # fields tests ############################################################
 
--- a/web/views/massmailing.py	Wed Mar 11 19:54:03 2009 +0100
+++ b/web/views/massmailing.py	Wed Mar 11 19:54:30 2009 +0100
@@ -17,12 +17,12 @@
 
 
 class SendEmailAction(Action):
-    category = 'mainactions'
+    id = 'sendemail'
     # XXX should check email is set as well
     __select__ = implements(IEmailable) & match_user_groups('managers', 'users')
 
-    id = 'sendemail'
     title = _('send email')
+    category = 'mainactions'
 
     def url(self):
         params = {'vid': 'massmailing', '__force_display': 1}
@@ -31,95 +31,96 @@
         return self.build_url(self.req.relative_path(includeparams=False),
                               **params)
 
+from cubicweb.web.form import FieldsForm, FormRenderer
+from cubicweb.web.form import StringField, CheckBox, TextInput, AjaxWidget
+            
+class MassMailingForm(FieldsForm):
+    id = 'massmailing'
+    
+    sender = StringField(widget=TextInput({'disabled': 'disabled'}), label=_('From:'))
+    recipient = StringField(widget=CheckBox(), label=_('Recipients:'))
+    subject = StringField(label=_('Subject:'))
+    mailbody = StringField(widget=AjaxWidget(wdgtype='TemplateTextField',
+                                             inputid='mailarea'))
 
-class MassMailingForm(EntityView):
+    def form_field_vocabulary(self, field):
+        if field.name == 'recipient':
+            vocab = [(entity.get_email(), entity.eid) for entity in self.rset.entities()]
+            return [(label, value) for label, value in vocab if label]
+        return super(MassMailingForm, self).form_field_vocabulary(field)
+    
+    def form_field_value(self, field, values):
+        if field.name == 'recipient':
+            return [entity.eid for entity in self.rset.entities() if entity.get_email()]
+        elif field.name == 'mailbody':
+            field.widget.attrs['cubicweb:variables'] = self.get_allowed_substitutions()
+        return super(MassMailingForm, self).form_field_value(field, values)
+
+    def form_buttons(self):
+        context = {'domid': self.domid,
+                   'cancel' : self.req._(stdmsgs.BUTTON_CANCEL),
+                   'cancelimgpath' : self.req.external_resource('CANCEL_EMAIL_ICON'),
+                   'send' : self.req._('send email'),
+                   'sendimgpath' : self.req.external_resource('SEND_EMAIL_ICON'),
+                }
+        return ['''<a id="sendbutton" href="javascript: $('%(domid)s').submit()">
+<img src="%(sendimgpath)s" alt="%(send)s"/>%(send)s</a>''' % context,
+                '''<a id="cancelbutton" href="javascript: history.back()">
+<img src="%(cancelimgpath)s" alt="%(cancel)s"/>%(cancel)s</a>''' % context,
+                ]
+    
+    def get_allowed_substitutions(self):
+        attrs = []
+        for coltype in self.rset.column_types(0):
+            eclass = self.vreg.etype_class(coltype)
+            attrs.append(eclass.allowed_massmail_keys())
+        return sorted(reduce(operator.and_, attrs))
+
+    def build_substitutions_help(self):
+        insertLink = u'<a href="javascript: insertText(\'%%(%s)s\', \'emailarea\');">%%(%s)s</a>'
+        substs = (u'<div class="substitution">%s</div>' % (insertLink % (subst, subst))
+                  for subst in self.get_allowed_substitutions())
+        helpmsg = self.req._('You can use any of the following substitutions in your text')
+        return u'<div id="substitutions"><span>%s</span>%s</div>' % (
+            helpmsg, u'\n'.join(substs))
+
+
+class MassMailingFormRenderer(FormRenderer):
+    button_bar_class = u'toolbar'
+    
+    def _render_fields(self, fields, w, form, display_help):
+        w(u'<table class="headersform">')
+        for field in fields:
+            if field.name == 'mailbody':
+                w(u'</table>')
+                w(u'<table>')
+                w(u'<tr><td><div>')
+            else:
+                w(u'<tr>')
+                w(u'<td class="hlabel">%s</td>' % self.render_label(form, field))
+                w(u'<td class="hvalue">')
+            w(field.render(form, self))
+            if field.name == 'mailbody':
+                w(u'</div></td>')
+                w(u'<td>%s</td>' % form.build_substitutions_help())
+                w(u'</tr>')
+            else:
+                w(u'</td></tr>')
+        w(u'</table>')
+
+    
+class MassMailingFormView(EntityView):
     id = 'massmailing'
     __select__ = implements(IEmailable) & match_user_groups('managers', 'users')
 
-    form_template = u"""
-<div id="compose">
-<form id="sendemail" action="sendmail" method="post">
-<table class="headersform">
-<tr>
-  <td class="hlabel">%(from_header)s</td>
-  <td class="hvalue">%(from)s</td>
-</tr>
-<tr>
-  <td class="hlabel">%(recipients_header)s</td>
-  <td class="hvalue">%(recipients)s</td>
-</tr>
-<tr>
-  <td class="hlabel">%(subject)s</td>
-  <td class="hvalue"><input id="mailsubj" name="mailsubject" value="" /></td>
-</tr>
-</table>
-<div id="toolbar">
-<ul>
-<li><a id="sendbutton" href="javascript: $('sendemail').submit()">
-    <img src="%(sendimgpath)s" alt="%(send)s"/>%(send)s</a></li>
-<li><a id="cancelbutton" href="javascript: history.back()">
-    <img src="%(cancelimgpath)s" alt="%(cancel)s"/>%(cancel)s</a></li>
- </ul>
-</div>
-<table>
-<tr>
-  <td>
-    <div>
-      <div id="emailbody" class="widget" cubicweb:loadtype="auto" cubicweb:wdgtype="TemplateTextField"
-           cubicweb:inputid="emailarea" cubicweb:inputname="mailbody" cubicweb:variables="%(variables)s"/>
-    </div>
-  </td>
-  <td>%(substitutions)s</td>
-</tr>
-</table>
-</form>
-</div>
-    """    
-
     def call(self):
         req = self.req
         req.add_js('cubicweb.widgets.js')
         req.add_css('cubicweb.mailform.css')
         from_addr = '%s <%s>' % (req.user.dc_title(), req.user.get_email())
-        ctx = {
-            'from_header' : req._('From: '),
-            'from' : html_escape(from_addr),
-            'substitutions' : self._build_substitutions_help(),
-            'recipients_header' : req._('Recipients: '),
-            'subject' : req._('Subject: '),
-            'body' : req._('Email body: '),
-            'variables' : ','.join(self._get_allowed_substitutions()),
-            'recipients' : self._build_recipients_list(),
-            'cancel' : req._(stdmsgs.BUTTON_CANCEL),
-            'cancelimgpath' : req.external_resource('CANCEL_EMAIL_ICON'),
-            'send' : req._('send email'),
-            'sendimgpath' : req.external_resource('SEND_EMAIL_ICON'),
-            }
-        self.w(self.form_template % ctx)
+        form = self.vreg.select_object('forms', 'massmailing', self.req, self.rset,
+                                       action='sendmail', domid='sendmail')
+        self.w(form.form_render(sender=from_addr, renderer=MassMailingFormRenderer()))
 
 
-    def _get_allowed_substitutions(self):
-        coltypes = self.rset.column_types(0)
-        attrs = []
-        for coltype in coltypes:
-            eclass = self.vreg.etype_class(coltype)
-            attrs.append(eclass.allowed_massmail_keys())
-        return sorted(reduce(operator.and_, attrs))
-            
-    def _build_recipients_list(self):
-        emails = ((entity.eid, entity.get_email()) for entity in self.rset.entities())
-        checkboxes = (u'<input name="recipient" type="checkbox" value="%s" checked="checked" />%s'
-                      % (eid, html_escape(email)) for eid, email in emails if email)
-        boxes = (u'<div class="recipient">%s</div>' % cbox for cbox in checkboxes)
-        return u'<div id="recipients">%s</div>' % u'\n'.join(boxes)
-            
-
-    def _build_substitutions_help(self):
-        insertLink = u'<a href="javascript: insertText(\'%%(%s)s\', \'emailarea\');">%%(%s)s</a>'
-        substs = (u'<div class="substitution">%s</div>' % (insertLink % (subst, subst))
-                  for subst in self._get_allowed_substitutions())
-        helpmsg = self.req._('You can use any of the following substitutions in your text')
-        return u'<div id="substitutions"><span>%s</span>%s</div>' % (
-            helpmsg, u'\n'.join(substs))
-