Index: main/waeup.ikoba/trunk/CHANGES.txt
===================================================================
--- main/waeup.ikoba/trunk/CHANGES.txt	(revision 12402)
+++ main/waeup.ikoba/trunk/CHANGES.txt	(revision 12408)
@@ -5,5 +5,5 @@
 ===================
 
-* Add components for customer management.
+* Add products, documents and customers modules and tons of components.
 
 * Rename 'kofa' 'ikoba', 'university' 'company' and 'student' 'customer'.
Index: main/waeup.ikoba/trunk/layout/static/css/base.css
===================================================================
--- main/waeup.ikoba/trunk/layout/static/css/base.css	(revision 12402)
+++ main/waeup.ikoba/trunk/layout/static/css/base.css	(revision 12408)
@@ -279,4 +279,20 @@
 }
 
+
+ /* docutils stuff */
+
+.section h1 {
+    font-size: 30px}
+
+.section h2 {
+    font-size: 24px}
+
+.section h3 {
+    font-size: 18px}
+
+.section h4 {
+    font-size: 14px}
+
+
 .sorting { background: url('../img/sort_both.png') no-repeat center right; }
 .sorting_asc { background: url('../img/sort_asc.png') no-repeat center right; }
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/fileviewlets.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/customers/fileviewlets.py	(revision 12402)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/customers/fileviewlets.py	(revision 12408)
@@ -90,5 +90,5 @@
     label = _(u'Sample Scan')
     title = _(u'Sample Scan')
-    mus = 1024 * 50
+    mus = 1024 * 200
     download_name = u'sample'
     tab_redirect = '#tab2'
@@ -134,5 +134,5 @@
     label = _(u'PDF File')
     title = _(u'PDF File')
-    mus = 1024 * 200
+    mus = 1024 * 1000
     download_name = u'sample.pdf'
     tab_redirect = '#tab2'
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/documents/browser.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/documents/browser.py	(revision 12402)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/documents/browser.py	(revision 12408)
@@ -33,5 +33,5 @@
 from zope.formlib.textwidgets import BytesDisplayWidget
 from zope.security import checkPermission
-from waeup.ikoba.utils.helpers import html2dict
+from waeup.ikoba.utils.helpers import html2dict, rest2dict
 from waeup.ikoba.interfaces import MessageFactory as _
 from waeup.ikoba.interfaces import (
@@ -49,5 +49,6 @@
 
 from waeup.ikoba.documents.interfaces import (
-    IDocumentsContainer, IPublicDocument, IHTMLDocument, IDocumentsUtils)
+    IDocumentsContainer, IPublicDocument,
+    IHTMLDocument, IRESTDocument, IDocumentsUtils)
 
 grok.context(IIkobaObject) # Make IKofaObject the default context
@@ -217,4 +218,23 @@
 
 
+class RESTDocumentDisplayFormPage(HTMLDocumentDisplayFormPage):
+    """ Page to display html document data
+    """
+    grok.context(IRESTDocument)
+
+    @property
+    def form_fields(self):
+        return grok.AutoFields(self.context.form_fields_interface).omit(
+            'html_dict', 'rest_multilingual')
+
+
+class RESTDocumentDisplayContentPage(HTMLDocumentDisplayContentPage):
+    """ Page to display the html content of document
+    """
+    grok.context(IRESTDocument)
+
+    label = None
+
+
 class DocumentManageFormPage(IkobaEditFormPage,
                             LocalRoleAssignmentUtilityView):
@@ -270,4 +290,19 @@
         portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE
         self.context.html_dict = html2dict(html_multilingual, portal_language)
+        return
+
+
+class RESTDocumentManageFormPage(DocumentManageFormPage):
+    """ View to manage restdocument data
+    """
+    grok.context(IRESTDocument)
+    grok.template('htmldocumentmanagepage')
+
+    @action(_('Save'), style='primary')
+    def save(self, **data):
+        msave(self, **data)
+        html_multilingual = getattr(self.context, 'rest_multilingual', None)
+        portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE
+        self.context.html_dict = rest2dict(html_multilingual, portal_language)
         return
 
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/documents/document.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/documents/document.py	(revision 12402)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/documents/document.py	(revision 12408)
@@ -38,5 +38,5 @@
 from waeup.ikoba.documents.interfaces import (
     IDocument, IPublicDocument, IDocumentsUtils,
-    IPDFDocument, IHTMLDocument)
+    IPDFDocument, IHTMLDocument, IRESTDocument)
 
 class Document(grok.Container):
@@ -150,4 +150,19 @@
 
 
+class RESTDocument(PublicDocumentBase):
+    """This is a  document to render html-coded text.
+    """
+    grok.implements(IRESTDocument)
+    grok.provides(IRESTDocument)
+
+    form_fields_interface = IRESTDocument
+
+    def __init__(self, *args, **kw):
+        super(RESTDocument, self).__init__(*args, **kw)
+        self.html_dict = {}
+
+RESTDocument = attrs_to_fields(RESTDocument)
+
+
 class PDFDocumentFactory(grok.GlobalUtility):
     """A factory for documents.
@@ -178,4 +193,20 @@
     def getInterfaces(self):
         return implementedBy(HTMLDocument)
+
+
+class RESTDocumentFactory(grok.GlobalUtility):
+    """A factory for REST documents.
+    """
+    grok.implements(IFactory)
+    grok.name(u'waeup.RESTDocument')
+    title = u"Create a new REST document.",
+    description = u"This factory instantiates new REST documents."
+
+    def __call__(self, *args, **kw):
+        return RESTDocument(*args, **kw)
+
+    def getInterfaces(self):
+        return implementedBy(RESTDocument)
+
 
 #: The file id marker for files
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/documents/interfaces.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/documents/interfaces.py	(revision 12402)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/documents/interfaces.py	(revision 12408)
@@ -92,8 +92,21 @@
     """
 
-    html_dict = Attribute('Content as language dictionary with values in html format')
+    html_dict = Attribute('Content as language dictionary with values in HTML format')
 
     html_multilingual = schema.Text(
         title = _(u'Multilingual content in HTML format'),
+        required = False,
+        )
+
+class IRESTDocument(IPublicDocument):
+    """A base representation of REST documents.
+
+    """
+
+    html_dict = Attribute(
+        'Content as language dictionary with values in HTML format')
+
+    rest_multilingual = schema.Text(
+        title = _(u'Multilingual content in REST (reStructuredText) format'),
         required = False,
         )
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/documents/tests/test_browser.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/documents/tests/test_browser.py	(revision 12402)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/documents/tests/test_browser.py	(revision 12408)
@@ -292,2 +292,62 @@
             % document.document_id in logcontent)
 
+    def test_manage_rest_document(self):
+        # Managers can access the pages of documentsconter
+        # and can perform actions
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open('http://localhost/app')
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.browser.getLink("Documents").click()
+        self.assertEqual(self.browser.url, self.container_path)
+        self.browser.getLink("Manage").click()
+        self.browser.getControl("Add document").click()
+        self.browser.getControl(name="doctype").value = ['RESTDocument']
+        self.browser.getControl(name="form.document_id").value = 'DOC3'
+        self.browser.getControl(name="form.title").value = 'My REST Document'
+        self.browser.getControl("Add document").click()
+        self.assertTrue('REST Document added.' in self.browser.contents)
+        document = self.app['documents']['DOC3']
+
+        # Document can be edited
+        self.browser.getLink("DOC3").click()
+        self.browser.getLink("Manage").click()
+        self.browser.getControl(name="form.rest_multilingual").value = """
+----------
+Main Title
+----------
+
+Subtitle
+========
+>>de<<
+----------
+Haupttitel
+----------
+
+Untertitel
+==========
+"""
+        self.browser.getControl("Save").click()
+        self.assertTrue('Form has been saved.' in self.browser.contents)
+        self.browser.getLink("View").click()
+        self.assertEqual(self.browser.url, self.container_path + '/DOC3/index')
+        self.assertTrue(
+            '<h1 class="title">Main Title</h1>' in self.browser.contents)
+        self.assertTrue(
+            '<h2 class="subtitle" id="subtitle">Subtitle</h2>'
+            in self.browser.contents)
+        self.assertFalse(
+            '<h1 class="title">Haupttitel</h1>' in self.browser.contents)
+        self.browser.getLink("de").click()
+        self.assertFalse(
+            '<h1 class="title">Main Title</h1>' in self.browser.contents)
+        self.assertTrue(
+            '<h1 class="title">Haupttitel</h1>' in self.browser.contents)
+        # The content can be rendered
+        IWorkflowState(document).setState(PUBLISHED)
+        self.browser.open(self.container_path + '/DOC3/display')
+        self.assertTrue(
+            '<h1 class="title">Haupttitel</h1>' in self.browser.contents)
+        # The page label (object title) is not displayed
+        self.assertFalse(
+            '<h1 class="ikoba-content-label">My REST Document</h1>'
+            in self.browser.contents)
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/documents/tests/test_document.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/documents/tests/test_document.py	(revision 12402)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/documents/tests/test_document.py	(revision 12408)
@@ -30,8 +30,9 @@
 from waeup.ikoba.imagestorage import DefaultStorage
 from waeup.ikoba.documents.interfaces import (
-    IDocumentsContainer, IPublicDocument, IPDFDocument, IHTMLDocument)
+    IDocumentsContainer, IPublicDocument, IPDFDocument,
+    IHTMLDocument, IRESTDocument)
 from waeup.ikoba.documents.container import DocumentsContainer
 from waeup.ikoba.documents.document import (
-    PDFDocument, HTMLDocument,
+    PDFDocument, HTMLDocument, RESTDocument,
     DocumentFileNameChooser, DocumentFileStoreHandler)
 from waeup.ikoba.testing import (FunctionalLayer, FunctionalTestCase)
@@ -66,4 +67,12 @@
             verifyObject(
                 IHTMLDocument, HTMLDocument())
+            )
+        self.assertTrue(
+            verifyClass(
+                IRESTDocument, RESTDocument)
+            )
+        self.assertTrue(
+            verifyObject(
+                IRESTDocument, RESTDocument())
             )
         return
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/documents/utils.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/documents/utils.py	(revision 12402)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/documents/utils.py	(revision 12408)
@@ -39,4 +39,5 @@
         'PDFDocument': _('PDF Document'),
         'HTMLDocument': _('HTML Document'),
+        'RESTDocument': _('REST Document'),
         }
 
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/utils/helpers.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/utils/helpers.py	(revision 12402)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/utils/helpers.py	(revision 12408)
@@ -832,2 +832,29 @@
                 contents=text)
     return elements
+
+def rest2dict(value=None,portal_language='en'):
+    """Transforms a localized REST text string into a dictionary.
+
+    Different languages must be separated by `>>xy<<` whereas
+    xy is the language code. Text parts without correct leading
+    language separator - usually the first part has no language
+    descriptor - are interpreted as texts in the portal's language.
+    The latter can be configured in waeup.srp.utils.utils.IkobaUtils.
+    """
+    try:
+        parts = value.split('>>')
+    except:
+        return {}
+    elements = {}
+    lang = portal_language
+    for part in parts:
+        if part[2:4] == u'<<':
+            lang = str(part[0:2].lower())
+            text = part[4:]
+            elements[lang] = renderElement(u'div id="rest"',
+                contents=ReST2HTML(text))
+        else:
+            text = part
+            elements[lang] = renderElement(u'div id="rest"',
+                contents=ReST2HTML(text))
+    return elements
