changeset 628:819c4121f9a0

FormCreate/FormSubmit: change to LF-only line endings
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Mon, 25 Mar 2013 19:48:31 +0100
parents f683dea1ac1b
children 23bf696cf294
files data/plugin/action/loadactions.py data/plugin/action/submitattachment.py data/plugin/action/submitbase.py data/plugin/action/submitcsv.py data/plugin/action/submitemail.py data/plugin/macro/FormBase.py data/plugin/macro/FormCheckbox.py data/plugin/macro/FormField.py data/plugin/macro/FormFooter.py data/plugin/macro/FormHeader.py data/plugin/macro/FormRadio.py data/plugin/macro/FormSelect.py data/plugin/macro/FormSubmit.py data/plugin/macro/FormText.py data/plugin/macro/FormTextarea.py data/plugin/macro/FormUpload.py
diffstat 16 files changed, 985 insertions(+), 985 deletions(-) [+]
line wrap: on
line diff
--- a/data/plugin/action/loadactions.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/action/loadactions.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,29 +1,29 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - loadactions Action
-    
-    Triggers multiple actions at once.
-    Actions are defined in actions[] CGI parameter, 
-    where actions[] is array of action names.
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from MoinMoin import wikiutil
-from MoinMoin.Page import Page
-from MoinMoin.action import ActionBase
-from MoinMoin.action import getHandler
-
-from submitbase import SubmitError
-
-
-def execute(pagename, request):
-    for action in request.form.getlist("actions[]"):
-        handler = getHandler(request, action)
-        try:
-            if handler:
-                handler(pagename, request)
-        except SubmitError:
-            # Stop executing next actions if there is an error
-            break
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - loadactions Action
+    
+    Triggers multiple actions at once.
+    Actions are defined in actions[] CGI parameter, 
+    where actions[] is array of action names.
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin import wikiutil
+from MoinMoin.Page import Page
+from MoinMoin.action import ActionBase
+from MoinMoin.action import getHandler
+
+from submitbase import SubmitError
+
+
+def execute(pagename, request):
+    for action in request.form.getlist("actions[]"):
+        handler = getHandler(request, action)
+        try:
+            if handler:
+                handler(pagename, request)
+        except SubmitError:
+            # Stop executing next actions if there is an error
+            break
--- a/data/plugin/action/submitattachment.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/action/submitattachment.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,62 +1,62 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - submitattachment Action
-
-    Attach file into standard MoinMoin attachment folder or defined in
-    targetpage CGI parameter.
-    
-    If attachment with same name already exists, numeric index
-    is added to new attachment. (file_1.txt, file_2.txt, ...)
-    
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from MoinMoin import wikiutil
-from MoinMoin.Page import Page
-from MoinMoin.action import AttachFile
-
-from submitbase import SubmitBase, SubmitValidationError
-
-
-def execute(pagename, request):
-    submitattachment(pagename, request).render()
-
-
-class submitattachment(SubmitBase):
-    
-    def rewrite_filename(self, filename):
-        """ Rewrites filename if there already exists attachment with the same name
-        """
-        attachFile = filename
-        i = 0 
-        while AttachFile.exists(self.request, self.targetpage, attachFile):
-            attachFile = self.attachFile
-            attachFileSplit = attachFile.split(".", 2)
-            ext = attachFileSplit.pop()
-            name = '.'.join(attachFileSplit)
-            attachFile = "%(name)s_%(index)d.%(extension)s" % {'name': name, 'index': i, 'extension': ext}
-            i += 1
-            
-        filename = attachFile
-        
-        return filename
-            
-    def validate(self):
-        """ Evaluates whethere valid file was specified """
-        SubmitBase.validate(self)
-        
-        if not self.attachFile:
-            self.msg = self._("File was not specified")
-            raise SubmitValidationError(self.msg)
-        
-        if not self.attachContent:
-            self.msg = self._("Invalid file '%(file)s'") % {'file': self.attachFile}
-            raise SubmitValidationError(self.msg)
-     
-    def sanitize(self):
-        SubmitBase.sanitize(self)
-        self.request.files['file'].filename = self.attachFile = self.rewrite_filename(self.attachFile)
-         
-    def submit(self):
-        AttachFile.add_attachment(self.request, self.targetpage, self.attachFile, self.attachContent, 0)
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - submitattachment Action
+
+    Attach file into standard MoinMoin attachment folder or defined in
+    targetpage CGI parameter.
+    
+    If attachment with same name already exists, numeric index
+    is added to new attachment. (file_1.txt, file_2.txt, ...)
+    
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin import wikiutil
+from MoinMoin.Page import Page
+from MoinMoin.action import AttachFile
+
+from submitbase import SubmitBase, SubmitValidationError
+
+
+def execute(pagename, request):
+    submitattachment(pagename, request).render()
+
+
+class submitattachment(SubmitBase):
+    
+    def rewrite_filename(self, filename):
+        """ Rewrites filename if there already exists attachment with the same name
+        """
+        attachFile = filename
+        i = 0 
+        while AttachFile.exists(self.request, self.targetpage, attachFile):
+            attachFile = self.attachFile
+            attachFileSplit = attachFile.split(".", 2)
+            ext = attachFileSplit.pop()
+            name = '.'.join(attachFileSplit)
+            attachFile = "%(name)s_%(index)d.%(extension)s" % {'name': name, 'index': i, 'extension': ext}
+            i += 1
+            
+        filename = attachFile
+        
+        return filename
+            
+    def validate(self):
+        """ Evaluates whethere valid file was specified """
+        SubmitBase.validate(self)
+        
+        if not self.attachFile:
+            self.msg = self._("File was not specified")
+            raise SubmitValidationError(self.msg)
+        
+        if not self.attachContent:
+            self.msg = self._("Invalid file '%(file)s'") % {'file': self.attachFile}
+            raise SubmitValidationError(self.msg)
+     
+    def sanitize(self):
+        SubmitBase.sanitize(self)
+        self.request.files['file'].filename = self.attachFile = self.rewrite_filename(self.attachFile)
+         
+    def submit(self):
+        AttachFile.add_attachment(self.request, self.targetpage, self.attachFile, self.attachContent, 0)
--- a/data/plugin/action/submitbase.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/action/submitbase.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,242 +1,242 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - submitbase Action
-
-    All actions handling forms should extend SubmitBase class.
-    
-    Basic methods to override:
-        - validate
-        - sanitize
-        - submit
-        
-    Base class methods should be called at first from overriding methods.
-    All data sent from user are filtered by _exlude_metadata() and then stored in 
-    fields dictionary. Data are then sorted into labels and values lists.
-    
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-import copy
-
-from MoinMoin import wikiutil
-from MoinMoin.action import ActionBase
-from MoinMoin.Page import Page
-from MoinMoin.action import AttachFile
-from MoinMoin.action import getHandler
-from MoinMoin.security.textcha import TextCha
-
-
-def execute(pagename, request):
-    raise NotImplementedError
-
-
-class SubmitBase(ActionBase):
-    """ submit base class with some generic stuff to inherit """
-    
-    debug = True
-    msgtype = 'text/html'
-
-    metadata = [
-        'doit', 
-        'action', 
-        'actions[]', 
-        'labels', 
-        'targetfile', 
-        'targetpage', 
-        'targetemail', 
-        'file', 
-        'file__filename__', 
-        'uploadlabel',
-        'textcha-question',
-        'textcha-answer',
-    ]
-    
-    def __init__(self, pagename, request):
-        ActionBase.__init__(self, pagename, request)
-        
-        self.msg = ""
-        self.actions = []
-        self.fields = {}
-        self.labels = []
-        self.values = []
-        self.attachFile = ""
-        self.attachContent = ""
-        self.targetpage = self.pagename
-        self.module = self.__module__.split(".").pop()
-        
-        if "actions[]" in self.request.form:
-            self.actions = copy.copy(self.request.form.getlist("actions[]"))
-        else:
-            self.actions.append(self.module)
-        
-        self.fields = self._exclude_metadata(self.request.form)
-        
-        # file upload is present
-        file_upload = request.files.get('file')
-        if file_upload:
-            self.attachFile = wikiutil.taintfilename(file_upload.filename)
-            self.attachContent = file_upload.stream
-            self.attachLabel = request.form.get("uploadlabel")
-            self.attachLabel = self.attachLabel.encode('utf-8')
-            
-        # page where all submited data will be stored
-        if "targetpage" in request.form:
-            targetpage = request.form.get("targetpage")
-            page = Page(self.request, targetpage)
-            if page.isStandardPage(False):
-                self.targetpage = targetpage
-
-    def is_last(self):
-        """ Evaluates whether currently executed action is last action from actions array
-        """
-        module = self.module
-        lastAction = self.actions.pop()
-        
-        if module == lastAction:
-            return True
-        else:
-            return False
-        
-    def append_link(self):
-        """ Makes formated link and apends it to fields dictionary
-        """
-        if self.attachFile:
-            attachUrl = AttachFile.getAttachUrl(self.targetpage, self.attachFile, self.request)
-            attachLink = self.request.getQualifiedURL() + attachUrl
-            self.fields[self.attachLabel] = attachLink
-        elif "file" in self.request.form:
-            self.fields[self.attachLabel] = ""
-            
-    def validate(self):
-        """ Validates user input.
-            
-        On error raise Exception and assign error message to self.msg property
-        """      
-        if not TextCha(self.request).check_answer_from_form(self.form):
-            self.msg = self._("Incorrect answer to control question")
-            raise SubmitValidationError(self.msg)
-        
-        empty = True
-        for name, value in self.fields.iteritems():
-            if value:
-                empty = False
-                break
-        if empty:
-            self.msg = self._("Form is empty")
-            raise SubmitValidationError(self.msg)
-    
-    def sanitize(self):
-        """ Sanitize input data passed by validation """        
-        for label, value in self.fields.iteritems():
-            self.fields[label] = wikiutil.escape(value)
-    
-    def submit(self):
-        """ Main submit logic
-        
-        Works with validated and sanitized data 
-        """
-        self.append_link()
-        self.labels, self.values = self._sort_fields(self.fields, self.request.form)
-    
-    def do_action(self):
-        """ Executes core methods: validate, sanitize, submit.
-        
-        Method is executed from ActionBase.render()
-        """
-        if not self.debug:
-            try:
-                self.validate()
-                self.sanitize()
-                self.submit()
-            except SubmitValidationError:
-                return False, self.msg
-            except Exception, e:
-                # TODO: Log exception
-                return False, e
-        else:
-            try:
-                self.validate()
-                self.sanitize()
-                self.submit()
-            except SubmitValidationError:
-                return False, self.msg
-
-        self.msg = self._("Data has been processed successfuly")
-        
-        return True, self.msg
-    
-    def do_action_finish(self, success):
-        if success:
-            if self.is_last():
-                self.render_success(self.error, self.msgtype)
-        else:
-            self.render_msg(self.error, self.msgtype)
-            if not self.is_last():
-                raise SubmitError
-            
-    def render_success(self, msg, msgtype):
-        """ Triggered on success """
-        self._delete_cache()
-        ActionBase.render_success(self, msg, self.msgtype)
-        
-    def render_msg(self, msg, msgtype):
-        """ Triggered on error """
-        if not msg:
-            msg = self._("Failed to process data")
-        msg = self._("Error - %s") % msg
-        self._delete_cache()
-        ActionBase.render_msg(self, msg, self.msgtype)
-        
-    def _delete_cache(self):
-        """ Delete cache after each form submit """
-        pagename = self.pagename
-        request = self.request
-        
-        arena = request.form.get('arena', 'Page.py')
-        if arena == 'Page.py':
-            arena = Page(request, pagename)
-        key = request.form.get('key', 'text_html')
-    
-        # Remove cache entry (if exists), and send the page
-        from MoinMoin import caching
-        caching.CacheEntry(request, arena, key, scope='item').remove()
-        caching.CacheEntry(request, arena, "pagelinks", scope='item').remove()
-        
-    def _exclude_metadata(self, form):
-        """ Filter all form metadata and returns only data send by user """
-        fields = dict([(k, v) for k, v in form.to_dict().iteritems()
-                       if k not in self.metadata])
-        return fields
-            
-    def _sort_fields(self, fields, form):
-        """ Sort form fields to order defined in CGI labels parameter
-        
-        labels is string containing field names separated by semicolon
-        Generation should be defined in FormFooter macro
-        """
-        labels = []
-        values = []                    
-        
-        if 'labels' in form:
-            _labels = form.get('labels').split(";")
-            for label in _labels:
-                label = label.encode('utf-8')
-                labels.append(label)
-                if label == 'Attachment' and label not in fields and self.targetFile:
-                    fields[label] = self.targetFile  # provide filename, if none is given
-                values.append(fields[label])
-        else:
-            labels = fields.keys()
-            values = fields.values()
-        
-        return labels, values
-
-
-class SubmitError(Exception):
-    """ Exception raised for submit action errors """
-
-
-class SubmitValidationError(Exception):
-    """ Exception raised for errors during validation """
-
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - submitbase Action
+
+    All actions handling forms should extend SubmitBase class.
+    
+    Basic methods to override:
+        - validate
+        - sanitize
+        - submit
+        
+    Base class methods should be called at first from overriding methods.
+    All data sent from user are filtered by _exlude_metadata() and then stored in 
+    fields dictionary. Data are then sorted into labels and values lists.
+    
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+import copy
+
+from MoinMoin import wikiutil
+from MoinMoin.action import ActionBase
+from MoinMoin.Page import Page
+from MoinMoin.action import AttachFile
+from MoinMoin.action import getHandler
+from MoinMoin.security.textcha import TextCha
+
+
+def execute(pagename, request):
+    raise NotImplementedError
+
+
+class SubmitBase(ActionBase):
+    """ submit base class with some generic stuff to inherit """
+    
+    debug = True
+    msgtype = 'text/html'
+
+    metadata = [
+        'doit', 
+        'action', 
+        'actions[]', 
+        'labels', 
+        'targetfile', 
+        'targetpage', 
+        'targetemail', 
+        'file', 
+        'file__filename__', 
+        'uploadlabel',
+        'textcha-question',
+        'textcha-answer',
+    ]
+    
+    def __init__(self, pagename, request):
+        ActionBase.__init__(self, pagename, request)
+        
+        self.msg = ""
+        self.actions = []
+        self.fields = {}
+        self.labels = []
+        self.values = []
+        self.attachFile = ""
+        self.attachContent = ""
+        self.targetpage = self.pagename
+        self.module = self.__module__.split(".").pop()
+        
+        if "actions[]" in self.request.form:
+            self.actions = copy.copy(self.request.form.getlist("actions[]"))
+        else:
+            self.actions.append(self.module)
+        
+        self.fields = self._exclude_metadata(self.request.form)
+        
+        # file upload is present
+        file_upload = request.files.get('file')
+        if file_upload:
+            self.attachFile = wikiutil.taintfilename(file_upload.filename)
+            self.attachContent = file_upload.stream
+            self.attachLabel = request.form.get("uploadlabel")
+            self.attachLabel = self.attachLabel.encode('utf-8')
+            
+        # page where all submited data will be stored
+        if "targetpage" in request.form:
+            targetpage = request.form.get("targetpage")
+            page = Page(self.request, targetpage)
+            if page.isStandardPage(False):
+                self.targetpage = targetpage
+
+    def is_last(self):
+        """ Evaluates whether currently executed action is last action from actions array
+        """
+        module = self.module
+        lastAction = self.actions.pop()
+        
+        if module == lastAction:
+            return True
+        else:
+            return False
+        
+    def append_link(self):
+        """ Makes formated link and apends it to fields dictionary
+        """
+        if self.attachFile:
+            attachUrl = AttachFile.getAttachUrl(self.targetpage, self.attachFile, self.request)
+            attachLink = self.request.getQualifiedURL() + attachUrl
+            self.fields[self.attachLabel] = attachLink
+        elif "file" in self.request.form:
+            self.fields[self.attachLabel] = ""
+            
+    def validate(self):
+        """ Validates user input.
+            
+        On error raise Exception and assign error message to self.msg property
+        """      
+        if not TextCha(self.request).check_answer_from_form(self.form):
+            self.msg = self._("Incorrect answer to control question")
+            raise SubmitValidationError(self.msg)
+        
+        empty = True
+        for name, value in self.fields.iteritems():
+            if value:
+                empty = False
+                break
+        if empty:
+            self.msg = self._("Form is empty")
+            raise SubmitValidationError(self.msg)
+    
+    def sanitize(self):
+        """ Sanitize input data passed by validation """        
+        for label, value in self.fields.iteritems():
+            self.fields[label] = wikiutil.escape(value)
+    
+    def submit(self):
+        """ Main submit logic
+        
+        Works with validated and sanitized data 
+        """
+        self.append_link()
+        self.labels, self.values = self._sort_fields(self.fields, self.request.form)
+    
+    def do_action(self):
+        """ Executes core methods: validate, sanitize, submit.
+        
+        Method is executed from ActionBase.render()
+        """
+        if not self.debug:
+            try:
+                self.validate()
+                self.sanitize()
+                self.submit()
+            except SubmitValidationError:
+                return False, self.msg
+            except Exception, e:
+                # TODO: Log exception
+                return False, e
+        else:
+            try:
+                self.validate()
+                self.sanitize()
+                self.submit()
+            except SubmitValidationError:
+                return False, self.msg
+
+        self.msg = self._("Data has been processed successfuly")
+        
+        return True, self.msg
+    
+    def do_action_finish(self, success):
+        if success:
+            if self.is_last():
+                self.render_success(self.error, self.msgtype)
+        else:
+            self.render_msg(self.error, self.msgtype)
+            if not self.is_last():
+                raise SubmitError
+            
+    def render_success(self, msg, msgtype):
+        """ Triggered on success """
+        self._delete_cache()
+        ActionBase.render_success(self, msg, self.msgtype)
+        
+    def render_msg(self, msg, msgtype):
+        """ Triggered on error """
+        if not msg:
+            msg = self._("Failed to process data")
+        msg = self._("Error - %s") % msg
+        self._delete_cache()
+        ActionBase.render_msg(self, msg, self.msgtype)
+        
+    def _delete_cache(self):
+        """ Delete cache after each form submit """
+        pagename = self.pagename
+        request = self.request
+        
+        arena = request.form.get('arena', 'Page.py')
+        if arena == 'Page.py':
+            arena = Page(request, pagename)
+        key = request.form.get('key', 'text_html')
+    
+        # Remove cache entry (if exists), and send the page
+        from MoinMoin import caching
+        caching.CacheEntry(request, arena, key, scope='item').remove()
+        caching.CacheEntry(request, arena, "pagelinks", scope='item').remove()
+        
+    def _exclude_metadata(self, form):
+        """ Filter all form metadata and returns only data send by user """
+        fields = dict([(k, v) for k, v in form.to_dict().iteritems()
+                       if k not in self.metadata])
+        return fields
+            
+    def _sort_fields(self, fields, form):
+        """ Sort form fields to order defined in CGI labels parameter
+        
+        labels is string containing field names separated by semicolon
+        Generation should be defined in FormFooter macro
+        """
+        labels = []
+        values = []                    
+        
+        if 'labels' in form:
+            _labels = form.get('labels').split(";")
+            for label in _labels:
+                label = label.encode('utf-8')
+                labels.append(label)
+                if label == 'Attachment' and label not in fields and self.targetFile:
+                    fields[label] = self.targetFile  # provide filename, if none is given
+                values.append(fields[label])
+        else:
+            labels = fields.keys()
+            values = fields.values()
+        
+        return labels, values
+
+
+class SubmitError(Exception):
+    """ Exception raised for submit action errors """
+
+
+class SubmitValidationError(Exception):
+    """ Exception raised for errors during validation """
+
--- a/data/plugin/action/submitcsv.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/action/submitcsv.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,108 +1,108 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - submitcsv Action
-    
-    Store submited data into CSV file. CSV file is located
-    in standard MoinMoin attchment folder or defined in 
-    targetpage CGI parameter.
-    
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-import os
-import csv
-import codecs
-import cStringIO
-
-from MoinMoin import config, wikiutil
-from MoinMoin.Page import Page
-from MoinMoin.action import AttachFile
-
-from submitbase import SubmitBase
-
-
-def execute(pagename, request):
-    submitcsv(pagename, request).render()           
-
-
-class submitcsv(SubmitBase):
-        
-    def __init__(self, pagename, request):
-        SubmitBase.__init__(self, pagename, request)
-        
-        self.delimiter = ';'
-        self.targetFile = request.form.get("targetfile", "list.csv")
-        self.targetFile = wikiutil.taintfilename(self.targetFile)  # replace illegal chars
-
-    def sanitize(self):
-        SubmitBase.sanitize(self)
-        self.targetFile = wikiutil.clean_input(self.targetFile)
-            
-    def submit(self):
-        SubmitBase.submit(self)        
-        request = self.request
-        pagename = self.targetpage
-                                
-        attachDir = AttachFile.getAttachDir(request, pagename, create=1)
-            
-        targetFile = self.targetFile
-        
-        filePath = os.path.join(attachDir, targetFile).encode(config.charset)
-        
-        # save header
-        if not os.path.exists(filePath):
-            fh = open(filePath, 'wb')
-            
-            # Encoded Input to writer.writerow
-            writer = csv.writer(fh, delimiter=self.delimiter)
-            writer.writerow(self.labels)
-            
-            # Decoded Input to writer.writerow
-            #writer = UnicodeWriter(fh, delimiter=self.delimiter)
-            #writer.writerow(self.labels)
-            
-            fh.close()
-        
-        # save content
-        fh = open(filePath, 'ab')
-        
-        # Encoded Input to writer.writerow
-        #writer = csv.writer(fh, delimiter=self.delimiter, quoting=csv.QUOTE_MINIMAL)
-        #writer.writerow(self.values)
-        
-        # Decoded Input to writer.writerow
-        writer = UnicodeWriter(fh, delimiter=self.delimiter, quoting=csv.QUOTE_MINIMAL)
-        writer.writerow(self.values)
-        
-        fh.close()
-
-
-class UnicodeWriter:
-    """
-    A CSV writer which will write rows to CSV file "f",
-    which is encoded in the given encoding.
-    """
-
-    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
-        # Redirect output to a queue
-        self.queue = cStringIO.StringIO()
-        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
-        self.stream = f
-        self.encoder = codecs.getincrementalencoder(encoding)()
-
-    def writerow(self, row):
-        self.writer.writerow([s.encode("utf-8") for s in row])
-        # Fetch UTF-8 output from the queue ...
-        data = self.queue.getvalue()
-        data = data.decode("utf-8")
-        # ... and reencode it into the target encoding
-        data = self.encoder.encode(data)
-        # write to the target stream
-        self.stream.write(data)
-        # empty queue
-        self.queue.truncate(0)
-
-    def writerows(self, rows):
-        for row in rows:
-            self.writerow(row)
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - submitcsv Action
+    
+    Store submited data into CSV file. CSV file is located
+    in standard MoinMoin attchment folder or defined in 
+    targetpage CGI parameter.
+    
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+import os
+import csv
+import codecs
+import cStringIO
+
+from MoinMoin import config, wikiutil
+from MoinMoin.Page import Page
+from MoinMoin.action import AttachFile
+
+from submitbase import SubmitBase
+
+
+def execute(pagename, request):
+    submitcsv(pagename, request).render()           
+
+
+class submitcsv(SubmitBase):
+        
+    def __init__(self, pagename, request):
+        SubmitBase.__init__(self, pagename, request)
+        
+        self.delimiter = ';'
+        self.targetFile = request.form.get("targetfile", "list.csv")
+        self.targetFile = wikiutil.taintfilename(self.targetFile)  # replace illegal chars
+
+    def sanitize(self):
+        SubmitBase.sanitize(self)
+        self.targetFile = wikiutil.clean_input(self.targetFile)
+            
+    def submit(self):
+        SubmitBase.submit(self)        
+        request = self.request
+        pagename = self.targetpage
+                                
+        attachDir = AttachFile.getAttachDir(request, pagename, create=1)
+            
+        targetFile = self.targetFile
+        
+        filePath = os.path.join(attachDir, targetFile).encode(config.charset)
+        
+        # save header
+        if not os.path.exists(filePath):
+            fh = open(filePath, 'wb')
+            
+            # Encoded Input to writer.writerow
+            writer = csv.writer(fh, delimiter=self.delimiter)
+            writer.writerow(self.labels)
+            
+            # Decoded Input to writer.writerow
+            #writer = UnicodeWriter(fh, delimiter=self.delimiter)
+            #writer.writerow(self.labels)
+            
+            fh.close()
+        
+        # save content
+        fh = open(filePath, 'ab')
+        
+        # Encoded Input to writer.writerow
+        #writer = csv.writer(fh, delimiter=self.delimiter, quoting=csv.QUOTE_MINIMAL)
+        #writer.writerow(self.values)
+        
+        # Decoded Input to writer.writerow
+        writer = UnicodeWriter(fh, delimiter=self.delimiter, quoting=csv.QUOTE_MINIMAL)
+        writer.writerow(self.values)
+        
+        fh.close()
+
+
+class UnicodeWriter:
+    """
+    A CSV writer which will write rows to CSV file "f",
+    which is encoded in the given encoding.
+    """
+
+    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
+        # Redirect output to a queue
+        self.queue = cStringIO.StringIO()
+        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
+        self.stream = f
+        self.encoder = codecs.getincrementalencoder(encoding)()
+
+    def writerow(self, row):
+        self.writer.writerow([s.encode("utf-8") for s in row])
+        # Fetch UTF-8 output from the queue ...
+        data = self.queue.getvalue()
+        data = data.decode("utf-8")
+        # ... and reencode it into the target encoding
+        data = self.encoder.encode(data)
+        # write to the target stream
+        self.stream.write(data)
+        # empty queue
+        self.queue.truncate(0)
+
+    def writerows(self, rows):
+        for row in rows:
+            self.writerow(row)
--- a/data/plugin/action/submitemail.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/action/submitemail.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,47 +1,47 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - submitemail Action
-    
-    Send submited data email address specified in targetemail CGI parameter
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from MoinMoin import wikiutil
-from MoinMoin.action import ActionBase
-from MoinMoin.Page import Page
-from MoinMoin.mail.sendmail import sendmail
-
-from submitbase import SubmitBase
-
-
-def execute(pagename, request):
-    submitemail(pagename, request).render()
-
-
-class submitemail(SubmitBase):          
-    
-    def __init__(self, pagename, request):
-        SubmitBase.__init__(self, pagename, request)
-        
-        self.subject = "MoinMoin mail"
-        self.targetemail = request.form.get("targetemail", "")
-        
-    def build_content(self):
-        """ Builds simple 'label: value' string """
-        text = ""
-        for label in self.labels:
-            index = self.labels.index(label)
-            label = label.decode('utf-8')
-            value = self.values[index]
-            text += "%(label)s: %(value)s \n" % {'label': label, 'value': value}
-        return text
-        
-    def submit(self):
-        SubmitBase.submit(self)   
-        text = self.build_content()
-        status, msg = sendmail(self.request, self.targetemail, self.subject, text, mail_from=self.targetemail)
-        self.msg = self._(msg)
-        if status != 1:
-            raise Exception(self.msg)
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - submitemail Action
+    
+    Send submited data email address specified in targetemail CGI parameter
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin import wikiutil
+from MoinMoin.action import ActionBase
+from MoinMoin.Page import Page
+from MoinMoin.mail.sendmail import sendmail
+
+from submitbase import SubmitBase
+
+
+def execute(pagename, request):
+    submitemail(pagename, request).render()
+
+
+class submitemail(SubmitBase):          
+    
+    def __init__(self, pagename, request):
+        SubmitBase.__init__(self, pagename, request)
+        
+        self.subject = "MoinMoin mail"
+        self.targetemail = request.form.get("targetemail", "")
+        
+    def build_content(self):
+        """ Builds simple 'label: value' string """
+        text = ""
+        for label in self.labels:
+            index = self.labels.index(label)
+            label = label.decode('utf-8')
+            value = self.values[index]
+            text += "%(label)s: %(value)s \n" % {'label': label, 'value': value}
+        return text
+        
+    def submit(self):
+        SubmitBase.submit(self)   
+        text = self.build_content()
+        status, msg = sendmail(self.request, self.targetemail, self.subject, text, mail_from=self.targetemail)
+        self.msg = self._(msg)
+        if status != 1:
+            raise Exception(self.msg)
--- a/data/plugin/macro/FormBase.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/macro/FormBase.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,102 +1,102 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - FormBase Macro
-
-    Base stuff for all form macros.
-    Macro generates HTML form elements in following sequence:
-    - parse_args   parse defined parameters
-    - validate     validate correct definition of parameters  
-    - build        build HTML element and stores it into self.output
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from MoinMoin import wikiutil
-
-
-class FormBase(object):
-
-    debug = False
-    
-    def __init__(self, macro, args):
-        self.macro = macro
-        self.request = macro.request
-        self._ = self.request.getText
-        self.module = self.__module__.split(".").pop()
-        self.args = args
-        
-        self.msg = ""
-        self.output = ""
-        
-        # Macro parameters
-        self._main = {}  # Main parameters
-        self._attribs = {}  # in FormField macros used as HTML tag attributes
-        self._params = {}  # Additional parameters
-
-    def parse_args(self):
-        """ Parse parameters into specific macro properties """
-        self._main, self._attribs, self._params = wikiutil.parse_quoted_separated(self.args)    
-    
-    def validate(self):
-        """ Validates macro parameters """
-        for name, value in self._attribs.iteritems():
-            if not hasattr(self, name):
-                self.msg = self._("Invalid attribute [%(attr)s] specified in macro [%(mod)s]" % {
-                                  'attr': name, 'mod': self.module})
-                raise FormValidationError(self.msg)
-    
-    def build(self):
-        """ Build HTML element """
-        raise NotImplementedError
-    
-    def render(self):
-        """ Executes core methods: parse_args, validate, build 
-        
-        Returns output as HTML element or error message.
-        """
-        if not self.debug:
-            try:
-                self.parse_args()
-                self.validate()
-                self.build()
-            except FormValidationError:
-                return self.msg
-            except Exception, e:
-                # TODO: Log exception
-                self.output = self._("Error - %s") % e
-                            
-            return self.output
-        
-        else:
-            try:
-                self.parse_args()
-                self.validate()
-                self.build()
-            except FormValidationError:
-                return self.msg
-            
-            return self.output
-
-    def _build_attribs(self, attribs):
-        """ Converts HTML element attributes from dictionary to string """
-        attrstr = ""
-        for name, value in attribs.iteritems():
-            if value:
-                attrstr += "%(name)s=\"%(value)s\" " % {'name': name, 'value': value}
-            
-        return attrstr
-    
-    def _build_input(self, type, name, args):
-        """ Builds HTML input element """
-        attrs = self._build_attribs(args)
-        if name is None:
-            input = "<input type=\"%(type)s\" %(attrs)s/>\n" % {'type': type, 'attrs': attrs}
-        else:
-            input = "<input type=\"%(type)s\" name=\"%(name)s\" %(attrs)s/>\n" % {
-                'type': type, 'name': name, 'attrs': attrs}
-        return input
-
-
-class FormValidationError(Exception):
-    """ Exception raised for errors during validation """
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - FormBase Macro
+
+    Base stuff for all form macros.
+    Macro generates HTML form elements in following sequence:
+    - parse_args   parse defined parameters
+    - validate     validate correct definition of parameters  
+    - build        build HTML element and stores it into self.output
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin import wikiutil
+
+
+class FormBase(object):
+
+    debug = False
+    
+    def __init__(self, macro, args):
+        self.macro = macro
+        self.request = macro.request
+        self._ = self.request.getText
+        self.module = self.__module__.split(".").pop()
+        self.args = args
+        
+        self.msg = ""
+        self.output = ""
+        
+        # Macro parameters
+        self._main = {}  # Main parameters
+        self._attribs = {}  # in FormField macros used as HTML tag attributes
+        self._params = {}  # Additional parameters
+
+    def parse_args(self):
+        """ Parse parameters into specific macro properties """
+        self._main, self._attribs, self._params = wikiutil.parse_quoted_separated(self.args)    
+    
+    def validate(self):
+        """ Validates macro parameters """
+        for name, value in self._attribs.iteritems():
+            if not hasattr(self, name):
+                self.msg = self._("Invalid attribute [%(attr)s] specified in macro [%(mod)s]" % {
+                                  'attr': name, 'mod': self.module})
+                raise FormValidationError(self.msg)
+    
+    def build(self):
+        """ Build HTML element """
+        raise NotImplementedError
+    
+    def render(self):
+        """ Executes core methods: parse_args, validate, build 
+        
+        Returns output as HTML element or error message.
+        """
+        if not self.debug:
+            try:
+                self.parse_args()
+                self.validate()
+                self.build()
+            except FormValidationError:
+                return self.msg
+            except Exception, e:
+                # TODO: Log exception
+                self.output = self._("Error - %s") % e
+                            
+            return self.output
+        
+        else:
+            try:
+                self.parse_args()
+                self.validate()
+                self.build()
+            except FormValidationError:
+                return self.msg
+            
+            return self.output
+
+    def _build_attribs(self, attribs):
+        """ Converts HTML element attributes from dictionary to string """
+        attrstr = ""
+        for name, value in attribs.iteritems():
+            if value:
+                attrstr += "%(name)s=\"%(value)s\" " % {'name': name, 'value': value}
+            
+        return attrstr
+    
+    def _build_input(self, type, name, args):
+        """ Builds HTML input element """
+        attrs = self._build_attribs(args)
+        if name is None:
+            input = "<input type=\"%(type)s\" %(attrs)s/>\n" % {'type': type, 'attrs': attrs}
+        else:
+            input = "<input type=\"%(type)s\" name=\"%(name)s\" %(attrs)s/>\n" % {
+                'type': type, 'name': name, 'attrs': attrs}
+        return input
+
+
+class FormValidationError(Exception):
+    """ Exception raised for errors during validation """
--- a/data/plugin/macro/FormCheckbox.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/macro/FormCheckbox.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,59 +1,59 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - FormCheckbox Macro
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from FormField import FormField
-
-
-class FormCheckbox(FormField):
-    
-    def __init__(self, macro, args):
-        FormField.__init__(self, macro, args)
-        
-        self.true = self._("True")
-        self.false = self._("False")
-        self.checked = ""
-        self.size = ""
-        
-    def parse_args(self):
-        FormField.parse_args(self)
-        length = len(self._main)
-        if length == 2:
-            self.true = self._main[1]
-        elif length == 3:
-            self.true = self._main[1]
-            self.false = self._main[2]
-        
-    def build(self):
-        FormField.build(self)
-        self.output += """
-        <script type=\"text/javascript\">
-        function checkbox(box, input)
-        {
-            if(box.checked==false)
-            {
-                input.value = "%(false)s"
-            }
-            else
-            {
-                input.value = "%(true)s"
-            }
-        }
-        </script>
-        """ % {'true': self.true, 'false': self.false}
-        inputId = self.label
-        checkboxId = self.label + "box"
-        
-        self._attribs["id"] = checkboxId
-        self._attribs["onclick"] = "checkbox(document.getElementById('" + checkboxId + "'), document.getElementById('" + inputId + "'))"
-        
-        self.output += self._build_input("hidden", self.label, {'id': inputId, 'value': self.false})
-        self.output += self._build_input("checkbox", None, self._attribs)
-
-
-def execute(macro, args):
-    return FormCheckbox(macro, args).render()
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - FormCheckbox Macro
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from FormField import FormField
+
+
+class FormCheckbox(FormField):
+    
+    def __init__(self, macro, args):
+        FormField.__init__(self, macro, args)
+        
+        self.true = self._("True")
+        self.false = self._("False")
+        self.checked = ""
+        self.size = ""
+        
+    def parse_args(self):
+        FormField.parse_args(self)
+        length = len(self._main)
+        if length == 2:
+            self.true = self._main[1]
+        elif length == 3:
+            self.true = self._main[1]
+            self.false = self._main[2]
+        
+    def build(self):
+        FormField.build(self)
+        self.output += """
+        <script type=\"text/javascript\">
+        function checkbox(box, input)
+        {
+            if(box.checked==false)
+            {
+                input.value = "%(false)s"
+            }
+            else
+            {
+                input.value = "%(true)s"
+            }
+        }
+        </script>
+        """ % {'true': self.true, 'false': self.false}
+        inputId = self.label
+        checkboxId = self.label + "box"
+        
+        self._attribs["id"] = checkboxId
+        self._attribs["onclick"] = "checkbox(document.getElementById('" + checkboxId + "'), document.getElementById('" + inputId + "'))"
+        
+        self.output += self._build_input("hidden", self.label, {'id': inputId, 'value': self.false})
+        self.output += self._build_input("checkbox", None, self._attribs)
+
+
+def execute(macro, args):
+    return FormCheckbox(macro, args).render()
--- a/data/plugin/macro/FormField.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/macro/FormField.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,50 +1,50 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - FormField Macro
-
-    Base stuff for field macros. All form fields should 
-    be derived from FormField class.
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from MoinMoin import wikiutil
-
-from FormBase import FormBase, FormValidationError
-
-
-class FormField(FormBase):
-    
-    def __init__(self, macro, args):
-        FormBase.__init__(self, macro, args)
-        
-        self.label = ""
-        self.width = ""
-        self.height = ""
-        
-        #if not hasattr(self.request, "fieldindex"):
-        #    self.request.fieldindex = 0
-        #else:
-        #    self.request.fieldindex += 1    
-        #self.index = str(self.request.fieldindex)
-        
-    def parse_args(self):
-        FormBase.parse_args(self)
-        self.label = self._main[0]
-        
-    def validate(self):
-        FormBase.validate(self)
-        if not self.label:
-            self.msg = self._("Field label is not defined")
-            raise FormValidationError(self.msg)
-
-    def build(self):
-        if not hasattr(self.request, "labels"):
-            self.request.labels = []
-            self.request.labels.append(self.label)
-        else:
-            if self.request.labels.count(self.label) == 0:
-                self.request.labels.append(self.label)
-            
-        #self.output += self._build_input("hidden", self.label+"_index", {'value':self.index})
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - FormField Macro
+
+    Base stuff for field macros. All form fields should 
+    be derived from FormField class.
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin import wikiutil
+
+from FormBase import FormBase, FormValidationError
+
+
+class FormField(FormBase):
+    
+    def __init__(self, macro, args):
+        FormBase.__init__(self, macro, args)
+        
+        self.label = ""
+        self.width = ""
+        self.height = ""
+        
+        #if not hasattr(self.request, "fieldindex"):
+        #    self.request.fieldindex = 0
+        #else:
+        #    self.request.fieldindex += 1    
+        #self.index = str(self.request.fieldindex)
+        
+    def parse_args(self):
+        FormBase.parse_args(self)
+        self.label = self._main[0]
+        
+    def validate(self):
+        FormBase.validate(self)
+        if not self.label:
+            self.msg = self._("Field label is not defined")
+            raise FormValidationError(self.msg)
+
+    def build(self):
+        if not hasattr(self.request, "labels"):
+            self.request.labels = []
+            self.request.labels.append(self.label)
+        else:
+            if self.request.labels.count(self.label) == 0:
+                self.request.labels.append(self.label)
+            
+        #self.output += self._build_input("hidden", self.label+"_index", {'value':self.index})
--- a/data/plugin/macro/FormFooter.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/macro/FormFooter.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,20 +1,20 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - FormFooter Macro
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from FormBase import FormBase
-
-
-class FormFooter(FormBase):
-        
-    def build(self):
-        self.output += self._build_input("hidden", "labels", {'value':';'.join(self.request.labels)})
-        self.output += "</form>\n"
-
-
-def execute(macro, args):
-    return FormFooter(macro, args).render()  
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - FormFooter Macro
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from FormBase import FormBase
+
+
+class FormFooter(FormBase):
+        
+    def build(self):
+        self.output += self._build_input("hidden", "labels", {'value':';'.join(self.request.labels)})
+        self.output += "</form>\n"
+
+
+def execute(macro, args):
+    return FormFooter(macro, args).render()  
--- a/data/plugin/macro/FormHeader.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/macro/FormHeader.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,66 +1,66 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - FormHeader Macro
-
-    Generates form header with some additional parameters.
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from MoinMoin.Page import Page
-
-from FormBase import FormBase, FormValidationError
-
-
-class FormHeader(FormBase):
-     
-    def parse_args(self):
-        FormBase.parse_args(self)
-        
-        self.action = ""
-        self.actions = ()
-
-        length = len(self._main)
-        
-        if length > 1:
-            self.action = "loadactions"
-            self.actions = self._main
-        elif length == 1:
-            self.action = self._main[0]
-
-        self.targetfile = self._attribs.get('targetfile', '')
-        self.targetemail = self._attribs.get('targetemail', '')
-        self.targetpage = self._attribs.get('targetpage', '')
-        
-    def validate(self):
-        FormBase.validate(self)    
-        if not self.action:
-            self.msg = self._("No action was specified in macro [%(macro)s]" % {'macro': self.module})
-            raise FormValidationError(self.msg)
-        
-    def build(self):
-        self.output += "<form enctype=\"multipart/form-data\" action=\"\" method=\"post\">\n"
-        self.output += self._build_input("hidden", "doit", {'value': "Do it"})
-        self.output += self._build_input("hidden", "action", {'value': self.action})
-        
-        if self.actions:
-            for action in self.actions:
-                self.output += self._build_input("hidden", "actions[]", {'value': action})
-        
-        if self.targetfile:
-            self.output += self._build_input("hidden", "targetfile", {'value': self.targetfile})
-            
-        if self.targetemail:
-            self.output += self._build_input("hidden", "targetemail", {'value': self.targetemail})
-            
-        if self.targetpage:
-            page = Page(self.request, self.targetpage)
-            if page.isStandardPage(False):
-                self.output += self._build_input("hidden", "targetpage", {'value': self.targetpage})
-            else:
-                self.output += self._("Targetpage [%(targetpage)s] does not exists" % {'targetpage': self.targetpage})
-
-        
-def execute(macro, args):
-    return FormHeader(macro, args).render()  
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - FormHeader Macro
+
+    Generates form header with some additional parameters.
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin.Page import Page
+
+from FormBase import FormBase, FormValidationError
+
+
+class FormHeader(FormBase):
+     
+    def parse_args(self):
+        FormBase.parse_args(self)
+        
+        self.action = ""
+        self.actions = ()
+
+        length = len(self._main)
+        
+        if length > 1:
+            self.action = "loadactions"
+            self.actions = self._main
+        elif length == 1:
+            self.action = self._main[0]
+
+        self.targetfile = self._attribs.get('targetfile', '')
+        self.targetemail = self._attribs.get('targetemail', '')
+        self.targetpage = self._attribs.get('targetpage', '')
+        
+    def validate(self):
+        FormBase.validate(self)    
+        if not self.action:
+            self.msg = self._("No action was specified in macro [%(macro)s]" % {'macro': self.module})
+            raise FormValidationError(self.msg)
+        
+    def build(self):
+        self.output += "<form enctype=\"multipart/form-data\" action=\"\" method=\"post\">\n"
+        self.output += self._build_input("hidden", "doit", {'value': "Do it"})
+        self.output += self._build_input("hidden", "action", {'value': self.action})
+        
+        if self.actions:
+            for action in self.actions:
+                self.output += self._build_input("hidden", "actions[]", {'value': action})
+        
+        if self.targetfile:
+            self.output += self._build_input("hidden", "targetfile", {'value': self.targetfile})
+            
+        if self.targetemail:
+            self.output += self._build_input("hidden", "targetemail", {'value': self.targetemail})
+            
+        if self.targetpage:
+            page = Page(self.request, self.targetpage)
+            if page.isStandardPage(False):
+                self.output += self._build_input("hidden", "targetpage", {'value': self.targetpage})
+            else:
+                self.output += self._("Targetpage [%(targetpage)s] does not exists" % {'targetpage': self.targetpage})
+
+        
+def execute(macro, args):
+    return FormHeader(macro, args).render()  
--- a/data/plugin/macro/FormRadio.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/macro/FormRadio.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,41 +1,41 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - FormRadio Macro
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from FormField import FormField
-
-
-class FormRadio(FormField):
-    
-    def __init(self, macro, args):
-        FormField.__init__(self, macro, args)
-        
-        self.value = ""
-        self.checked = ""
-        self.size = ""
-        
-    def parse_args(self):
-        FormField.parse_args(self)
-        
-        self.value = self._main[1]
-        
-    def validate(self):
-        FormField.validate(self)
-        if not self.value:
-            self.msg = self._("Field value is not defined")
-            raise FormValidationError(self.msg)     
-            
-    def build(self):
-        FormField.build(self)
-        self._attribs["value"] = self.value
-        self._attribs["checked"] = "checked"
-        #self.output += self._build_input("hidden", "labels[]", {'value':self.label})
-        self.output += self._build_input("radio", self.label, self._attribs)
-    
-
-def execute(macro, args):
-    return FormRadio(macro, args).render()
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - FormRadio Macro
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from FormField import FormField
+
+
+class FormRadio(FormField):
+    
+    def __init(self, macro, args):
+        FormField.__init__(self, macro, args)
+        
+        self.value = ""
+        self.checked = ""
+        self.size = ""
+        
+    def parse_args(self):
+        FormField.parse_args(self)
+        
+        self.value = self._main[1]
+        
+    def validate(self):
+        FormField.validate(self)
+        if not self.value:
+            self.msg = self._("Field value is not defined")
+            raise FormValidationError(self.msg)     
+            
+    def build(self):
+        FormField.build(self)
+        self._attribs["value"] = self.value
+        self._attribs["checked"] = "checked"
+        #self.output += self._build_input("hidden", "labels[]", {'value':self.label})
+        self.output += self._build_input("radio", self.label, self._attribs)
+    
+
+def execute(macro, args):
+    return FormRadio(macro, args).render()
--- a/data/plugin/macro/FormSelect.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/macro/FormSelect.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,38 +1,38 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - FormSelect Macro
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from FormField import FormField
-
-
-class FormSelect(FormField):
-            
-    def __init__(self, macro, args):
-        FormField.__init__(self, macro, args)
-        
-        self.list = ()
-        self.size = ""
-        self.multiple = ""
-        self.disabled = ""
-        
-    def parse_args(self):
-        FormField.parse_args(self)
-        self.list = self._main
-        self.list.pop(0)
-        
-    def build(self):
-        FormField.build(self)
-        #self.output += self._build_input("hidden", "labels[]", {'value':self.label})
-        self.output += "<select name=\"%(label)s\" %(attribs)s>\n" % {'label': self.label, 'attribs': self._attribs}
-        self.output += "<option value=\"\"></option>\n"
-        for item in self.list:
-            self.output += "<option value=\"%(item)s\">%(item)s</option>\n" % {'item': item}
-        self.output += "</select>\n"
-    
-
-def execute(macro, args):
-    return FormSelect(macro, args).render()
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - FormSelect Macro
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from FormField import FormField
+
+
+class FormSelect(FormField):
+            
+    def __init__(self, macro, args):
+        FormField.__init__(self, macro, args)
+        
+        self.list = ()
+        self.size = ""
+        self.multiple = ""
+        self.disabled = ""
+        
+    def parse_args(self):
+        FormField.parse_args(self)
+        self.list = self._main
+        self.list.pop(0)
+        
+    def build(self):
+        FormField.build(self)
+        #self.output += self._build_input("hidden", "labels[]", {'value':self.label})
+        self.output += "<select name=\"%(label)s\" %(attribs)s>\n" % {'label': self.label, 'attribs': self._attribs}
+        self.output += "<option value=\"\"></option>\n"
+        for item in self.list:
+            self.output += "<option value=\"%(item)s\">%(item)s</option>\n" % {'item': item}
+        self.output += "</select>\n"
+    
+
+def execute(macro, args):
+    return FormSelect(macro, args).render()
--- a/data/plugin/macro/FormSubmit.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/macro/FormSubmit.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,32 +1,32 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - FormSubmit Macro
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from MoinMoin.security.textcha import TextCha
-
-from FormField import FormField
-
-
-class FormSubmit(FormField):
-    
-    def __init__(self, macro, args):
-        FormField.__init__(self, macro, args)
-        
-        self.value = ""
-        self.size = ""
-        
-    def parse_args(self):
-        FormField.parse_args(self)
-        self.value = self.label
-        
-    def build(self):
-        self.output += TextCha(self.request).render()
-        self.output += self._build_input("submit", None, {'value': self.value})
-    
-
-def execute(macro, args):
-    return FormSubmit(macro, args).render()
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - FormSubmit Macro
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin.security.textcha import TextCha
+
+from FormField import FormField
+
+
+class FormSubmit(FormField):
+    
+    def __init__(self, macro, args):
+        FormField.__init__(self, macro, args)
+        
+        self.value = ""
+        self.size = ""
+        
+    def parse_args(self):
+        FormField.parse_args(self)
+        self.value = self.label
+        
+    def build(self):
+        self.output += TextCha(self.request).render()
+        self.output += self._build_input("submit", None, {'value': self.value})
+    
+
+def execute(macro, args):
+    return FormSubmit(macro, args).render()
--- a/data/plugin/macro/FormText.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/macro/FormText.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,30 +1,30 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - FormText Macro
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from FormField import FormField
-
-
-class FormText(FormField):
-    
-    def __init__(self, macro, args):
-        FormField.__init__(self, macro, args)
-        
-        self.maxlength = ""
-        self.size = ""
-        self.autocomplete = ""
-        self.disabled = ""
-        self.readonly = ""
-        
-    def build(self):
-        FormField.build(self)
-        #self.output += self._build_input("hidden", "labels[]", {'value':self.label})
-        self.output += self._build_input("text", self.label, self._attribs)
-    
-
-def execute(macro, args):
-    return FormText(macro, args).render()
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - FormText Macro
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from FormField import FormField
+
+
+class FormText(FormField):
+    
+    def __init__(self, macro, args):
+        FormField.__init__(self, macro, args)
+        
+        self.maxlength = ""
+        self.size = ""
+        self.autocomplete = ""
+        self.disabled = ""
+        self.readonly = ""
+        
+    def build(self):
+        FormField.build(self)
+        #self.output += self._build_input("hidden", "labels[]", {'value':self.label})
+        self.output += self._build_input("text", self.label, self._attribs)
+    
+
+def execute(macro, args):
+    return FormText(macro, args).render()
--- a/data/plugin/macro/FormTextarea.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/macro/FormTextarea.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,30 +1,30 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - FormTextarea Macro
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from FormField import FormField
-
-
-class FormTextarea(FormField):
-    
-    def __init__(self, macro, args):
-        FormField.__init__(self, macro, args)
-        
-        self.rows = ""
-        self.cols = ""
-        self.disabled = ""
-        self.readonly = ""
-        
-    def build(self):
-        FormField.build(self)
-        #self.output += self._build_input("hidden", "labels[]", {'value':self.label})
-        self.output += "<textarea name=\"%(label)s\" %(attribs)s></textarea>" % {
-            'attribs': self._build_attribs(self._attribs), 'label': self.label}
-    
-
-def execute(macro, args):
-    return FormTextarea(macro, args).render()
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - FormTextarea Macro
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from FormField import FormField
+
+
+class FormTextarea(FormField):
+    
+    def __init__(self, macro, args):
+        FormField.__init__(self, macro, args)
+        
+        self.rows = ""
+        self.cols = ""
+        self.disabled = ""
+        self.readonly = ""
+        
+    def build(self):
+        FormField.build(self)
+        #self.output += self._build_input("hidden", "labels[]", {'value':self.label})
+        self.output += "<textarea name=\"%(label)s\" %(attribs)s></textarea>" % {
+            'attribs': self._build_attribs(self._attribs), 'label': self.label}
+    
+
+def execute(macro, args):
+    return FormTextarea(macro, args).render()
--- a/data/plugin/macro/FormUpload.py	Mon Mar 25 19:41:11 2013 +0100
+++ b/data/plugin/macro/FormUpload.py	Mon Mar 25 19:48:31 2013 +0100
@@ -1,29 +1,29 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - FormUpload Macro
-
-    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
-    @license: GNU GPL, see COPYING for details.
-"""
-
-from FormField import FormField
-
-
-class FormUpload(FormField):
-    
-    def __init__(self, macro, args):
-        FormField.__init__(self, macro, args)
-        
-        self.size = ""
-                
-    def parse_args(self):
-        FormField.parse_args(self)
-        
-    def build(self):
-        FormField.build(self)
-        self.output += self._build_input("hidden", "uploadlabel", {'value': self.label})
-        self.output += self._build_input("file", "file", self._attribs)
-    
-
-def execute(macro, args):
-    return FormUpload(macro, args).render()
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - FormUpload Macro
+
+    @copyright: 2008 by Peter Bodi <petrdll@centrum.sk>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from FormField import FormField
+
+
+class FormUpload(FormField):
+    
+    def __init__(self, macro, args):
+        FormField.__init__(self, macro, args)
+        
+        self.size = ""
+                
+    def parse_args(self):
+        FormField.parse_args(self)
+        
+    def build(self):
+        FormField.build(self)
+        self.output += self._build_input("hidden", "uploadlabel", {'value': self.label})
+        self.output += self._build_input("file", "file", self._attribs)
+    
+
+def execute(macro, args):
+    return FormUpload(macro, args).render()