Commits

Thomas Waldmann  committed e93157b

refactor modify views to use flatland, see details below

code is more OO now, the Item instance now handles modify view AND
post handling in do_modify() - moving this was needed so a flatland Form
subclass could be used that depends on the Item type.

moved item_modified event triggering to _save().

templates: use flatland generator to generate most form fields

  • Participants
  • Parent commits f464adc

Comments (0)

Files changed (6)

File MoinMoin/apps/frontend/views.py

         abort(403)
     return converted_item._convert(item.internal_representation())
 
+
 @frontend.route('/+modify/<itemname:item_name>', methods=['GET', 'POST'])
 def modify_item(item_name):
     """Modify the wiki item item_name.
         item = Item.create(item_name, contenttype=contenttype)
     except AccessDeniedError:
         abort(403)
-    if request.method == 'GET':
-        if not flaskg.user.may.write(item_name):
-            abort(403)
-        content = item.do_modify(template_name)
-        return content
-    elif request.method == 'POST':
-        form = TextChaizedForm.from_flat(request.form)
-        TextCha(form).amend_form()
-        valid = form.validate()
-        if not valid:
-            data_text = request.values.get('data_text')
-            meta_text = item.meta_dict_to_text(item.meta)
-            comment = request.values.get('comment')
-            return render_template(item.template,
-                                   item_name=item_name,
-                                   gen=make_generator(),
-                                   form=form,
-                                   data_text=data_text,
-                                   meta_text=meta_text,
-                                   comment=comment,
-                                   cols=COLS,
-                                   rows_data=ROWS_DATA,
-                                   rows_meta=ROWS_META,
-                                  )
-        try:
-            item.modify()
-            item_modified.send(app._get_current_object(),
-                               item_name=item_name)
-            if contenttype in ('application/x-twikidraw', 'application/x-anywikidraw', 'application/x-svgdraw'):
-                # TWikiDraw/AnyWikiDraw/SvgDraw POST more than once, redirecting would break them
-                return "OK"
-        except AccessDeniedError:
-            abort(403)
-        return redirect(url_for('frontend.show_item', item_name=item_name))
+    if not flaskg.user.may.write(item_name):
+        abort(403)
+    return item.do_modify(contenttype, template_name)
 
 
 class CommentForm(TextChaizedForm):

File MoinMoin/items/__init__.py

 from StringIO import StringIO
 from array import array
 
+from flatland import Form, String, Integer, Boolean, Enum
+from flatland.validation import Validator, Present, IsEmail, ValueBetween, URLValidator, Converted
+
 from MoinMoin.security.textcha import TextCha, TextChaizedForm, TextChaValid
+from MoinMoin.signalling import item_modified
 from MoinMoin.util.forms import make_generator
 from MoinMoin.util.mimetype import MimeType
 from MoinMoin.util.mime import Type, type_moin_document
 from flask import current_app as app
 from flask import g as flaskg
 
-from flask import request, url_for, Response, abort, escape
+from flask import request, url_for, flash, Response, redirect, abort, escape
+
 from werkzeug import is_resource_modified
 from jinja2 import Markup
 
         newrev[ACTION] = unicode(action)
         self.before_revision_commit(newrev, data)
         storage_item.commit()
-        # XXX Event ?
+        item_modified.send(app._get_current_object(), item_name=name)
         return new_rev_no, size
 
     def before_revision_commit(self, newrev, data):
     def _convert(self):
         abort(404)
 
-    def do_modify(self, template_name):
+    def do_modify(self, contenttype, template_name):
         # XXX think about and add item template support
         return render_template('modify_show_type_selection.html',
                                item_name=self.name,
         items = [item.name for item in item_iterator]
         return sorted(items)
 
-    def do_modify(self, template_name):
+    def do_modify(self, contenttype, template_name):
         # XXX think about and add item template support
         #if template_name is None and isinstance(self.rev, DummyRev):
         #    return self._do_modify_show_templates()
-        form = TextChaizedForm.from_defaults()
-        TextCha(form).amend_form()
+        from MoinMoin.apps.frontend.views import CommentForm
+        class ModifyForm(CommentForm):
+            rev = Integer.using(optional=False)
+            meta_text = String.using(optional=False).with_properties(placeholder=L_("MetaData (JSON)"))
+
+        if request.method == 'GET':
+            form = ModifyForm.from_defaults()
+            TextCha(form).amend_form()
+            form['meta_text'] = self.meta_dict_to_text(self.meta)
+            form['rev'] = 0 # XXX ???
+        elif request.method == 'POST':
+            form = ModifyForm.from_flat(request.form)
+            TextCha(form).amend_form()
+            valid = form.validate()
+            if valid:
+                try:
+                    self.modify() # XXX
+                except AccessDeniedError:
+                    abort(403)
+                else:
+                    return redirect(url_for('frontend.show_item', item_name=self.name))
         return render_template(self.template,
                                item_name=self.name,
-                               rows_meta=ROWS_META, cols=COLS,
-                               revno=0,
-                               meta_text=self.meta_dict_to_text(self.meta),
+                               rows_meta=str(ROWS_META), cols=str(COLS),
                                help=self.modify_help,
                                form=form,
                                gen=make_generator(),
         doc = html_conv(doc)
         return conv_serialize(doc, {html.namespace: ''})
 
-    def do_modify(self, template_name):
-        form = TextChaizedForm.from_defaults()
-        TextCha(form).amend_form()
-        if template_name is None and isinstance(self.rev, DummyRev):
-            return self._do_modify_show_templates()
-        if template_name:
-            item = Item.create(template_name)
-            data_text = self.data_storage_to_internal(item.data)
-        else:
-            data_text = self.data_storage_to_internal(self.data)
-        meta_text = self.meta_dict_to_text(self.meta)
+    def do_modify(self, contenttype, template_name):
+        # XXX think about and add item template support
+        #if template_name is None and isinstance(self.rev, DummyRev):
+        #    return self._do_modify_show_templates()
+        from MoinMoin.apps.frontend.views import CommentForm
+        class ModifyForm(CommentForm):
+            rev = Integer.using(optional=False)
+            meta_text = String.using(optional=False).with_properties(placeholder=L_("MetaData (JSON)"))
+            data_text = String.using(optional=False).with_properties(placeholder=L_("Type your text here"))
+
+        if request.method == 'GET':
+            if template_name is None and isinstance(self.rev, DummyRev):
+                return self._do_modify_show_templates()
+            form = ModifyForm.from_defaults()
+            TextCha(form).amend_form()
+            if template_name:
+                item = Item.create(template_name)
+                form['data_text'] = self.data_storage_to_internal(item.data)
+            else:
+                form['data_text'] = self.data_storage_to_internal(self.data)
+            form['meta_text'] = self.meta_dict_to_text(self.meta)
+            form['rev'] = 0 # XXX ???
+        elif request.method == 'POST':
+            form = ModifyForm.from_flat(request.form)
+            TextCha(form).amend_form()
+            valid = form.validate()
+            if valid:
+                try:
+                    self.modify() # XXX
+                except AccessDeniedError:
+                    abort(403)
+                else:
+                    return redirect(url_for('frontend.show_item', item_name=self.name))
         return render_template(self.template,
                                item_name=self.name,
-                               rows_data=ROWS_DATA, rows_meta=ROWS_META, cols=COLS,
-                               revno=0,
-                               data_text=data_text,
-                               meta_text=meta_text,
-                               lang='en', direction='ltr',
+                               rows_data=str(ROWS_DATA), rows_meta=str(ROWS_META), cols=str(COLS),
                                help=self.modify_help,
                                form=form,
                                gen=make_generator(),
     """
     template = "modify_text_html.html"
 
-    def do_modify(self, template_name):
-        form = TextChaizedForm.from_defaults()
-        TextCha(form).amend_form()
-        if template_name is None and isinstance(self.rev, DummyRev):
-            return self._do_modify_show_templates()
-        if template_name:
-            item = Item.create(template_name)
-            data_text = self.data_storage_to_internal(item.data)
-        else:
-            data_text = self.data_storage_to_internal(self.data)
-        meta_text = self.meta_dict_to_text(self.meta)
-        return render_template(self.template,
-                               item_name=self.name,
-                               rows_data=ROWS_DATA, rows_meta=ROWS_META, cols=COLS,
-                               revno=0,
-                               data_text=data_text,
-                               meta_text=meta_text,
-                               lang='en', direction='ltr',
-                               help=self.modify_help,
-                               form=form,
-                               gen=make_generator(),
-                              )
-
 item_registry.register(HTML._factory, Type('text/html'))
 
 
         self.put_member('drawing' + ext, filecontent, content_length,
                         expected_members=set(['drawing.draw', 'drawing.map', 'drawing.png']))
 
-    def do_modify(self, template_name):
-        """
-        Fills params into the template for initialzing of the the java applet.
-        The applet is called for doing modifications.
-        """
-        form = TextChaizedForm.from_defaults()
-        TextCha(form).amend_form()
+    def do_modify(self, contenttype, template_name):
+        # XXX think about and add item template support
+        #if template_name is None and isinstance(self.rev, DummyRev):
+        #    return self._do_modify_show_templates()
+        from MoinMoin.apps.frontend.views import CommentForm
+        class ModifyForm(CommentForm):
+            rev = Integer.using(optional=False)
+            # XXX as the "saving" POSTs come from TWikiDraw (not the form), editing meta_text doesn't work
+            meta_text = String.using(optional=False).with_properties(placeholder=L_("MetaData (JSON)"))
+
+        if request.method == 'GET':
+            form = ModifyForm.from_defaults()
+            TextCha(form).amend_form()
+            # XXX currently this is rather pointless, as the form does not get POSTed:
+            form['meta_text'] = self.meta_dict_to_text(self.meta)
+            form['rev'] = 0 # XXX ???
+        elif request.method == 'POST':
+            # this POST comes directly from TWikiDraw (not from Browser), thus no validation
+            try:
+                self.modify() # XXX
+            except AccessDeniedError:
+                abort(403)
+            else:
+                # TWikiDraw POSTs more than once, redirecting would break them
+                return "OK"
         return render_template(self.template,
                                item_name=self.name,
-                               rows_meta=ROWS_META, cols=COLS,
-                               revno=0,
-                               meta_text=self.meta_dict_to_text(self.meta),
+                               rows_meta=str(ROWS_META), cols=str(COLS),
                                help=self.modify_help,
                                form=form,
                                gen=make_generator(),
         self.put_member('drawing' + ext, filecontent, content_length,
                         expected_members=set(['drawing.svg', 'drawing.map', 'drawing.png']))
 
-    def do_modify(self, template_name):
-        """
-        Fills params into the template for initialzing of the the java applet.
-        The applet is called for doing modifications.
-        """
-        form = TextChaizedForm.from_defaults()
-        TextCha(form).amend_form()
-        drawing_exists = 'drawing.svg' in self.list_members()
+    def do_modify(self, contenttype, template_name):
+        # XXX think about and add item template support
+        #if template_name is None and isinstance(self.rev, DummyRev):
+        #    return self._do_modify_show_templates()
+        from MoinMoin.apps.frontend.views import CommentForm
+        class ModifyForm(CommentForm):
+            rev = Integer.using(optional=False)
+            # XXX as the "saving" POSTs come from AnyWikiDraw (not the form), editing meta_text doesn't work
+            meta_text = String.using(optional=False).with_properties(placeholder=L_("MetaData (JSON)"))
+
+        if request.method == 'GET':
+            form = ModifyForm.from_defaults()
+            TextCha(form).amend_form()
+            # XXX currently this is rather pointless, as the form does not get POSTed:
+            form['meta_text'] = self.meta_dict_to_text(self.meta)
+            form['rev'] = 0 # XXX ???
+        elif request.method == 'POST':
+            # this POST comes directly from AnyWikiDraw (not from Browser), thus no validation
+            try:
+                self.modify() # XXX
+            except AccessDeniedError:
+                abort(403)
+            else:
+                # AnyWikiDraw POSTs more than once, redirecting would break them
+                return "OK"
+        try:
+            drawing_exists = 'drawing.svg' in self.list_members()
+        except:
+            drawing_exists = False
         return render_template(self.template,
                                item_name=self.name,
-                               rows_meta=ROWS_META, cols=COLS,
-                               revno=0,
-                               meta_text=self.meta_dict_to_text(self.meta),
+                               rows_meta=str(ROWS_META), cols=str(COLS),
                                help=self.modify_help,
                                drawing_exists=drawing_exists,
                                form=form,
         self.put_member(filename, filecontent, content_length,
                         expected_members=set(['drawing.svg', 'drawing.png']))
 
-    def do_modify(self, template_name):
-        """
-        Fills params into the template for initializing of the applet.
-        """
-        form = TextChaizedForm.from_defaults()
-        TextCha(form).amend_form()
+    def do_modify(self, contenttype, template_name):
+        # XXX think about and add item template support
+        #if template_name is None and isinstance(self.rev, DummyRev):
+        #    return self._do_modify_show_templates()
+        from MoinMoin.apps.frontend.views import CommentForm
+        class ModifyForm(CommentForm):
+            rev = Integer.using(optional=False)
+            # XXX as the "saving" POSTs come from SvgDraw (not the form), editing meta_text doesn't work
+            meta_text = String.using(optional=False).with_properties(placeholder=L_("MetaData (JSON)"))
+
+        if request.method == 'GET':
+            form = ModifyForm.from_defaults()
+            TextCha(form).amend_form()
+            # XXX currently this is rather pointless, as the form does not get POSTed:
+            form['meta_text'] = self.meta_dict_to_text(self.meta)
+            form['rev'] = 0 # XXX ???
+        elif request.method == 'POST':
+            # this POST comes directly from SvgDraw (not from Browser), thus no validation
+            try:
+                self.modify() # XXX
+            except AccessDeniedError:
+                abort(403)
+            else:
+                # SvgDraw POSTs more than once, redirecting would break them
+                return "OK"
         return render_template(self.template,
                                item_name=self.name,
-                               rows_meta=ROWS_META, cols=COLS,
-                               revno=0,
-                               meta_text=self.meta_dict_to_text(self.meta),
+                               rows_meta=str(ROWS_META), cols=str(COLS),
                                help=self.modify_help,
                                form=form,
                                gen=make_generator(),

File MoinMoin/templates/modify_applet.html

+{% import "forms.html" as forms %}
 {% extends theme("layout.html") %}
 {% block content %}
 <h1>{{ _("Modifying %(item_name)s", item_name=item_name) }}</h1>
 <div class="moin-form">
-<form action="" method="POST" enctype="multipart/form-data">
-<input type="hidden" name="action" value="modify" />
-<input type="hidden" name="rev" value="{{ revno }}" />
+{{ gen.form.open(form, method='post', action='', enctype='multipart/form-data') }}
+{{ forms.render_errors(form) }}
+{{ gen.input(form['rev'], type='hidden') }}
 {% block extra_form %}{% endblock %}
 {% block data_editor %}{% endblock %}
     <dl>
         </dd>
     </dl>
 <pre>{{ help }}</pre>
-<textarea name="meta_text" lang="en" dir="ltr" rows="{{ rows_meta }}" cols="{{ cols }}">{{ meta_text }}</textarea>
-</form>
+{{ gen.textarea(form['meta_text'], lang='en', dir='ltr', rows=rows_meta, cols=cols) }}
+<br />
+{{ forms.render_errors(form['meta_text']) }}
+{{ gen.form.close() }}
 </div>
 {% endblock %}

File MoinMoin/templates/modify_binary.html

 {% import "forms.html" as forms %}
 {% extends "modify_applet.html" %}
 {% block extra_form %}
-<input class="button" type="submit" name="button_save" value="{{ _("Save") }}" />
+{{ gen.input(form['submit'], class='button', type='submit') }}
 {{ forms.render_textcha(gen, form) }}
-<br />
-<label for="comment">{{ _("Comment:") }}</label><input type="text" id="comment" name="comment" size="80" maxlength="200" value="{{ comment }}" />
-<br />
+{{ forms.render_field(gen, form['comment'], 'text') }}
 {% endblock %}

File MoinMoin/templates/modify_text.html

 {% extends "modify_binary.html" %}
 {% block data_editor %}
-<textarea name="data_text" lang="{{ lang }}" dir="{{ direction }}" rows="{{ rows_data }}" cols="{{ cols }}">{{ data_text }}</textarea>
+{{ gen.textarea(form['data_text'], lang=lang, dir=direction, rows=rows_data, cols=cols) }}
 <br />
 {% endblock %}

File MoinMoin/templates/modify_text_html.html

 
 {% block data_editor %}
 <p>
-    <textarea class="ckeditor" id="data_text" name="data_text" rows="{{ rows_data }}" cols="{{ cols }}">{{
-        data_text
-    }}</textarea>
+{{ gen.textarea(form['data_text'], class='ckeditor', lang=lang, dir=direction, rows=rows_data, cols=cols) }}
 </p>
 {% endblock %}