changeset 1316:7657798d40f3 namespaces

merged default branch into namespaces branch
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Tue, 27 Mar 2012 23:48:23 +0200
parents 005e12de8b6a (current diff) 7ca1cab62e38 (diff)
children ff503e7ea7a0
files MoinMoin/apps/feed/views.py MoinMoin/apps/frontend/views.py MoinMoin/config/default.py MoinMoin/conftest.py wikiconfig.py
diffstat 99 files changed, 2344 insertions(+), 241 deletions(-) [+]
line wrap: on
line diff
--- a/MANIFEST.in	Tue Mar 20 20:59:55 2012 -0300
+++ b/MANIFEST.in	Tue Mar 27 23:48:23 2012 +0200
@@ -12,6 +12,7 @@
 recursive-include   MoinMoin/apps/misc/templates *
 
 recursive-include   MoinMoin/themes/modernized *
+recursive-include   MoinMoin/themes/foobar *
 
 global-include */_tests/*
 
--- a/MoinMoin/apps/feed/views.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/apps/feed/views.py	Tue Mar 27 23:48:23 2012 +0200
@@ -24,7 +24,6 @@
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
-from MoinMoin import wikiutil
 from MoinMoin.i18n import _, L_, N_
 from MoinMoin.apps.feed import feed
 from MoinMoin.config import (NAME, NAME_EXACT, WIKINAME, ACL, ACTION, ADDRESS,
--- a/MoinMoin/apps/frontend/views.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/apps/frontend/views.py	Tue Mar 27 23:48:23 2012 +0200
@@ -49,7 +49,7 @@
 from MoinMoin.apps.frontend import frontend
 from MoinMoin.items import Item, NonExistent
 from MoinMoin.items import ROWS_META, COLS, ROWS_DATA
-from MoinMoin import config, user, util, wikiutil
+from MoinMoin import config, user, util
 from MoinMoin.config import CONTENTTYPE_GROUPS
 from MoinMoin.constants.keys import *
 from MoinMoin.util import crypto
@@ -973,7 +973,7 @@
                 'username': form['username'].value,
                 'password': form['password1'].value,
                 'email': form['email'].value,
-                #'openid': form['openid'].value,
+                'openid': form['openid'].value,
             }
             if app.cfg.user_email_verification:
                 user_kwargs['is_disabled'] = True
@@ -1344,7 +1344,7 @@
                     response['flash'].append((_("Your password has been changed."), "info"))
                 else:
                     if part == 'personal':
-                        if form['openid'].value != flaskg.user.openid and user.search_users(openid=form['openid'].value):
+                        if form['openid'].value and form['openid'].value != flaskg.user.openid and user.search_users(openid=form['openid'].value):
                             # duplicate openid
                             response['flash'].append((_("This openid is already in use."), "error"))
                             success = False
--- a/MoinMoin/auth/__init__.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/auth/__init__.py	Tue Mar 27 23:48:23 2012 +0200
@@ -144,7 +144,7 @@
 from flask import current_app as app
 from jinja2 import Markup
 
-from MoinMoin import user, wikiutil
+from MoinMoin import user
 from MoinMoin.i18n import _, L_, N_
 
 
--- a/MoinMoin/config/default.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/config/default.py	Tue Mar 27 23:48:23 2012 +0200
@@ -369,7 +369,9 @@
         ('frontend.modify_item', L_('Modify'), L_('Edit or Upload'), True, ),
         ('special.supplementation', None, None, False, ),
         ('frontend.index', L_('Index'), L_('List sub-items'), False, ),
-        ('special.comments', L_('Comments'), L_('Switch showing comments on or off'), True, ),
+        # The | character in the comments and transclusions lines below separate the off/on title (tooltip) values used by javascript
+        ('special.comments', L_('Comments'), L_('Show comments|Hide comments'), True, ),
+        ('special.transclusions', L_('Transclusions'), L_('Show transclusions|Hide transclusions'), True, ),
         ('frontend.highlight_item', L_('Highlight'), L_('Show with Syntax-Highlighting'), True, ),
         ('frontend.show_item_meta', L_('Meta'), L_('Display Metadata'), True, ),
         ('frontend.quicklink_item', None, L_('Create or remove a navigation link to this item'), False, ),
--- a/MoinMoin/conftest.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/conftest.py	Tue Mar 27 23:48:23 2012 +0200
@@ -59,7 +59,7 @@
     app = create_app_ext(flask_config_dict=dict(SECRET_KEY='foobarfoobar'),
                          moin_config_class=given_config,
                          **more_config)
-    ctx = app.test_request_context('/')
+    ctx = app.test_request_context('/', base_url="http://localhost:8080/")
     ctx.push()
     before_wiki()
     return app, ctx
--- a/MoinMoin/constants/misc.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/constants/misc.py	Tue Mar 27 23:48:23 2012 +0200
@@ -23,7 +23,6 @@
     re.UNICODE | re.VERBOSE
     )
 
-# used for wikiutil.clean_input
 clean_input_translation_map = {
     # these chars will be replaced by blanks
     ord(u'\t'): u' ',
--- a/MoinMoin/converter/_tests/test_include.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/converter/_tests/test_include.py	Tue Mar 27 23:48:23 2012 +0200
@@ -72,32 +72,36 @@
         update_item(u'page4', {CONTENTTYPE: u'text/x.moin.wiki'}, u'{{page2}}')
 
         page1 = MoinWiki.create(u'page1')
+        rendered = page1._render_data()
+        # an error message will follow strong tag
+        assert '<strong class="moin-error">' in rendered
 
-        page1._render_data()
+    def test_ExternalInclude(self):
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'{{http://moinmo.in}}')
+        rendered = MoinWiki.create(u'page1')._render_data()
+        assert '<object class="moin-http moin-transclusion" data="http://moinmo.in" data-href="http://moinmo.in">http://moinmo.in</object>' in rendered
 
     def test_InlineInclude(self):
         # issue #28
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'Content of page2 is "{{page2}}"')
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'Content of page2 is "{{page2}}".')
 
         update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u'Single line')
         rendered = MoinWiki.create(u'page1')._render_data()
-        assert 'Content of page2 is "Single line"' in rendered
+        assert '<p>Content of page2 is "<span class="moin-transclusion" data-href="/page2">Single line</span>".</p>' in rendered
 
         update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u'Two\n\nParagraphs')
         rendered = MoinWiki.create(u'page1')._render_data()
-        assert '<p>Two</p>' in rendered
-        assert '<p>Paragraphs</p>' in rendered
+        assert '<p>Content of page2 is "</p><div class="moin-transclusion" data-href="/page2"><p>Two</p><p>Paragraphs</p></div><p>".</p></div>' in rendered
 
         update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"this text contains ''italic'' string")
         rendered = MoinWiki.create(u'page1')._render_data()
-        assert 'Content of page2 is "this text contains' in rendered
-        assert '<em>italic</em>' in rendered
+        assert 'Content of page2 is "<span class="moin-transclusion" data-href="/page2">this text contains <em>italic</em>' in rendered
 
         update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'Content of page2 is\n\n{{page2}}')
         update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"Single Line")
         rendered = MoinWiki.create(u'page1')._render_data()
-        assert 'Content of page2 is</p>' in rendered
-        assert '<p>Single Line</p>' in rendered
+        assert '<p>Content of page2 is</p><p><span class="moin-transclusion" data-href="/page2">Single Line</span></p>' in rendered
+        #           '<p>Content of page2 is</p><p><span class="moin-transclusion" data-href="http://127.0.0.1:8080/page2">Single Line</span></p>'
 
         update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'Content of page2 is "{{page2}}"')
         update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"|| table || cell ||")
@@ -112,3 +116,17 @@
         assert 'Content of page2 is "</p>' in rendered
         assert '<table>' in rendered
         assert rendered.count('<table>') == 1
+
+    def test_InlineIncludeLogo(self):
+        # the 3rd parameter, u'',  should be a binary string defining a png image, but it is not needed for this simple test
+        update_item(u'logo', {CONTENTTYPE: u'image/png'}, u'')
+
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'{{logo}}')
+        rendered = MoinWiki.create(u'page1')._render_data()
+        assert '<img alt="logo" class="moin-transclusion"' in rendered
+
+        # <p /> is not valid html5; should be <p></p>. to be valid.  Even better, there should be no empty p's.
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'{{logo}}{{logo}}')
+        rendered = MoinWiki.create(u'page1')._render_data()
+        assert '<p />' not in rendered
+        assert '<p></p>' not in rendered
--- a/MoinMoin/converter/creole_in.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/converter/creole_in.py	Tue Mar 27 23:48:23 2012 +0200
@@ -27,7 +27,7 @@
 
 import re
 
-from MoinMoin import config, wikiutil
+from MoinMoin import config
 from MoinMoin.util.iri import Iri
 from MoinMoin.util.tree import moin_page, xlink, xinclude
 
--- a/MoinMoin/converter/docbook_in.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/converter/docbook_in.py	Tue Mar 27 23:48:23 2012 +0200
@@ -23,7 +23,6 @@
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
-from MoinMoin import wikiutil
 from MoinMoin.util.tree import moin_page, xlink, docbook, xml, html
 
 from ._wiki_macro import ConverterMacro
--- a/MoinMoin/converter/docbook_out.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/converter/docbook_out.py	Tue Mar 27 23:48:23 2012 +0200
@@ -16,7 +16,6 @@
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
-from MoinMoin import wikiutil
 from MoinMoin.util.tree import html, moin_page, xlink, docbook, xml
 
 
--- a/MoinMoin/converter/html_in.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/converter/html_in.py	Tue Mar 27 23:48:23 2012 +0200
@@ -20,7 +20,6 @@
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
-from MoinMoin import wikiutil
 from MoinMoin.util.tree import html, moin_page, xlink, xml
 
 from ._wiki_macro import ConverterMacro
--- a/MoinMoin/converter/html_out.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/converter/html_out.py	Tue Mar 27 23:48:23 2012 +0200
@@ -12,48 +12,50 @@
 
 from __future__ import absolute_import, division
 
+import re
+
+from flask import request
 from emeraldtree import ElementTree as ET
 
 from MoinMoin import wikiutil
 from MoinMoin.i18n import _, L_, N_
 from MoinMoin.util.tree import html, moin_page, xlink, xml, Name
 
-
-def remove_overlay_prefixes(url):
-    """
-    Returns url without the prefixes, like +get or +modify
-
-    TODO: Find a way to limit the removal to internal links only
-    This could remove +get or +modify for external links,
-        when they shouldn't really be removed.
-    """
-    return unicode(url).replace("/+get/", "/+show/").replace("/+modify/", "/+show/")
+from MoinMoin import log
+logging = log.getLogger(__name__)
 
 
-def wrap_object_with_overlay(elem, href):
+def convert_getlink_to_showlink(href):
     """
-    Given both an element and either an href or text, wraps an object with the appropriate div,
-    and attaches the overlay element.
+    If the incoming transclusion reference is within this domain, then remove "+get/<revision number>/".
     """
-    txt = u"→"
-
-    href = remove_overlay_prefixes(href)
+    if href.startswith('/'):
+        return re.sub(r'\+get/\+[0-9a-fA-F]+/', '', href)
+    return href
 
-    child = html.a(attrib={
-        html.href: href
-    }, children=(txt, ))
+def mark_item_as_transclusion(elem, href):
+    """
+    Return elem after adding a "moin-transclusion" class and a "data-href" attribute with
+    a link to the transcluded item.
 
-    overlay = html.div(attrib={
-        html.class_: "object-overlay"
-    }, children=(child, ))
-
-    owrapper = html.div(attrib={
-        html.class_: "object-overlay-wrapper"
-    }, children=(overlay, ))
-
-    return html.div(attrib={
-        html.class_: "page-object"
-    }, children=(elem, owrapper))
+    On the client side, a Javascript function will wrap the element (or a parent element)
+    in a span or div and 2 overlay siblings will be created.
+    """
+    href = unicode(href)
+    # href will be "/wikiroot/SomeObject" or "/SomePage" for internal wiki items
+    # or "http://Some.Org/SomeThing" for external link
+    if elem.tag.name == 'page':
+        # if wiki is not running at server root, prefix href with wiki root
+        wiki_root = request.url_root[len(request.host_url):-1]
+        if wiki_root:
+            href = '/' + wiki_root + href
+    href = convert_getlink_to_showlink(href)
+    # data_href will create an attribute named data-href: any attribute beginning with "data-" passes html5 validation
+    elem.attrib[html.data_href] = href
+    classes = elem.attrib.get(html.class_, '').split()
+    classes.append('moin-transclusion')
+    elem.attrib[html.class_] = ' '.join(classes)
+    return elem
 
 
 class ElementException(RuntimeError):
@@ -376,7 +378,7 @@
                 attrib[html.controls] = 'controls'
             new_elem = self.new_copy(getattr(html, obj_type), elem, attrib)
 
-        return wrap_object_with_overlay(new_elem, href=href)
+        return mark_item_as_transclusion(new_elem, href)
 
     def visit_moinpage_p(self, elem):
         return self.new_copy(html.p, elem)
@@ -384,7 +386,11 @@
     def visit_moinpage_page(self, elem):
         for item in elem:
             if item.tag.uri == moin_page and item.tag.name == 'body':
-                return self.new_copy(html.div, item)
+                # if this is a transcluded page, we must pass the class and data-href attribs
+                attribs = elem.attrib.copy()
+                if moin_page.page_href in attribs:
+                    del attribs[moin_page.page_href]
+                return self.new_copy(html.div, item, attribs)
 
         raise RuntimeError('page:page need to contain exactly one page:body tag, got {0!r}'.format(elem[:]))
 
--- a/MoinMoin/converter/include.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/converter/include.py	Tue Mar 27 23:48:23 2012 +0200
@@ -6,6 +6,9 @@
 MoinMoin - Include handling
 
 Expands include elements in an internal Moin document.
+
+Although this module is named include.py, many comments within and the moin docs
+use the word transclude as defined by http://www.linfo.org/transclusion.html, etc.
 """
 
 
@@ -23,13 +26,12 @@
 from whoosh.query import Term, And, Wildcard
 
 from MoinMoin.config import NAME, NAME_EXACT, WIKINAME
-from MoinMoin import wikiutil
 from MoinMoin.items import Item
 from MoinMoin.util.mime import type_moin_document
 from MoinMoin.util.iri import Iri, IriPath
 from MoinMoin.util.tree import html, moin_page, xinclude, xlink
 
-from MoinMoin.converter.html_out import wrap_object_with_overlay
+from MoinMoin.converter.html_out import mark_item_as_transclusion, Attributes
 
 
 class XPointer(list):
@@ -113,7 +115,9 @@
             return cls()
 
     def recurse(self, elem, page_href):
-        # Check if we reached a new page
+        # on first call, elem.tag.name=='page'. Decendants (body, div, p, include, page, etc.) are processed by recursing through DOM
+
+        # stack is used to detect transclusion loops
         page_href_new = elem.get(self.tag_page_href)
         if page_href_new:
             page_href_new = Iri(page_href_new)
@@ -127,6 +131,8 @@
 
         try:
             if elem.tag == self.tag_xi_include:
+                # we have already recursed several levels and found a transclusion: "{{SomePage}}" or similar
+                # process the transclusion and add it to the DOM.  Subsequent recursions will traverse through the transclusion's elements.
                 href = elem.get(self.tag_xi_href)
                 xpointer = elem.get(self.tag_xi_xpointer)
 
@@ -173,7 +179,7 @@
                                 xp_include_level = data
 
                 if href:
-                    # We have a single page to include
+                    # We have a single page to transclude
                     href = Iri(href)
                     link = Iri(scheme='wiki', authority='')
                     if href.scheme == 'wiki':
@@ -245,12 +251,13 @@
 
                     page_doc = page.internal_representation()
                     # page_doc.tag = self.tag_div # XXX why did we have this?
+
                     self.recurse(page_doc, page_href)
-                    # Wrap the page with the overlay, but only if it's a "page", or "a".
+
+                    # if this is an existing item, mark it as a transclusion.  non-existent items are not marked (page_doc.tag.name == u'a')
                     # The href needs to be an absolute URI, without the prefix "wiki://"
-                    if page_doc.tag.endswith("page") or page_doc.tag.endswith("a"):
-                        page_doc = wrap_object_with_overlay(page_doc, href=unicode(p_href.path))
-
+                    if page_doc.tag.name == u'page':
+                        page_doc = mark_item_as_transclusion(page_doc, p_href.path)
                     included_elements.append(page_doc)
 
                 if len(included_elements) > 1:
@@ -261,45 +268,73 @@
                     result = included_elements[0]
                 else:
                     result = None
-
+                #  end of processing for transclusion; the "result" will get inserted into the DOM below
                 return result
 
-            container = [elem]
 
+            # Traverse the DOM by calling self.recurse with each child of the current elem.  Starting elem.tag.name=='page'.
+            container = []
             i = 0
             while i < len(elem):
                 child = elem[i]
                 if isinstance(child, ET.Node):
+                    # almost everything in the DOM will be an ET.Node, exceptions are unicode nodes under p nodes
+
                     ret = self.recurse(child, page_href)
+
                     if ret:
-                        if type(ret) == types.ListType:
+                        # "Normally" we are here because child.tag.name==include and ret is a transcluded item (ret.tag.name=page, image, or object, etc.)
+                        # that must be inserted into the DOM replacing elem[i].
+                        # This is complicated by the DOM having many inclusions, such as "\n{{SomePage}}\n" that are a child of a "p".
+                        # To prevent generation of invalid HTML5 (e.g. "<p>text<p>text</p></p>"), the DOM must be adjusted.
+                        if isinstance(ret, types.ListType):
+                            # the transclusion may be a return of the container variable from below, add to DOM replacing the current node
                             elem[i:i+1] = ret
                         elif elem.tag.name == 'p':
-                            try:
-                                body = ret[0][0]
-                                if len(body) == 1 and body[0].tag.name == 'p':
-                                    single = True
-                                else:
-                                    single = False
-                            except AttributeError:
-                                single = False
-
-                            if single:
-                                # content inside P is inserted directly into this P
-                                p = ret[0][0][0]
-                                elem[i:i+1] = [p[k] for k in xrange(len(p))]
+                            # ancestor P nodes with tranclusions  have special case issues, we may need to mangle the ret
+                            body = ret[0]
+                            # check for instance where ret is a page, ret[0] a body, ret[0][0] a P
+                            if not isinstance(body, unicode) and ret.tag.name == 'page' and body.tag.name == 'body' and \
+                                len(body) == 1 and body[0].tag.name == 'p':
+                                # special case:  "some text {{SomePage}} more text" or "\n{{SomePage}}\n" where SomePage contains a single p.
+                                # the content of the transcluded P will be inserted directly into ancestor P.
+                                p = body[0]
+                                # get attributes from page node; we expect {class: "moin-transclusion"; data-href: "http://some.org/somepage"}
+                                attrib = Attributes(ret).convert()
+                                # make new span node and "convert" p to span by copying all of p's children
+                                span = ET.Element(html.span, attrib=attrib, children=p[:])
+                                # insert the new span into the DOM replacing old include, page, body, and p elements
+                                elem[i] = span
+                            elif not isinstance(body, unicode) and ret.tag.name == 'page' and body.tag.name == 'body':
+                                # special case: "some text {{SomePage}} more text" or "\n{{SomePage}}\n" and SomePage body contains multiple p's, a table, preformatted text, etc.
+                                # note: ancestor P may have text before or after include
+                                if i > 0:
+                                    # there is text before transclude, make new p node to hold text before include and save in container
+                                    pa = ET.Element(html.p)
+                                    pa[:] = elem[0:i]
+                                    container.append(pa)
+                                # get attributes from page node; we expect {class: "moin-transclusion"; data-href: "http://some.org/somepage"}
+                                attrib = Attributes(ret).convert()
+                                # make new div node, copy all of body's children, and save in container
+                                div = ET.Element(html.div, attrib=attrib, children=body[:])
+                                container.append(div)
+                                 # empty elem of siblings that were just placed in container
+                                elem[0:i+1] = []
+                                if len(elem) > 0:
+                                    # there is text after transclude, make new p node to hold text, copy siblings, save in container
+                                    pa = ET.Element(html.p)
+                                    pa[:] = elem[:]
+                                    container.append(pa)
+                                    elem[:] = []
+                                # elem is now empty so while loop will terminate and container will be returned up one level in recursion
                             else:
-                                # P is closed and element is inserted after
-                                pa = ET.Element(html.p)
-                                pa[0:i] = elem[0:i]
-                                ret[0:1] = elem[i:i+1]
-                                elem[0:i+1] = []
-                                container[0:0] = [pa, ret]
-                                i = 0
+                                # ret may be a unicode string: take default action
+                                elem[i] = ret
                         else:
+                            # default action for any ret not fitting special cases above
                             elem[i] = ret
                 i += 1
-            if len(container) > 1:
+            if len(container) > 0:
                 return container
 
         finally:
@@ -307,7 +342,6 @@
 
     def __call__(self, tree):
         self.stack = []
-
         self.recurse(tree, None)
 
         return tree
--- a/MoinMoin/converter/rst_in.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/converter/rst_in.py	Tue Mar 27 23:48:23 2012 +0200
@@ -25,7 +25,7 @@
 
 from flask import g as flaskg
 
-from MoinMoin import config, wikiutil
+from MoinMoin import config
 from MoinMoin.util.iri import Iri
 from MoinMoin.util.tree import html, moin_page, xlink
 
--- a/MoinMoin/static/js/common.js	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/static/js/common.js	Tue Mar 27 23:48:23 2012 +0200
@@ -114,35 +114,6 @@
     }
 }
 
-// for long documents with many comments this is expensive to calculate,
-// thus we keep it here:
-comments = null;
-
-function toggleComments() {
-    // Toggle visibility of every tag with class "comment"
-    for (i = 0; i < comments.length; i++){
-        el = comments[i];
-        if ( el.style.display != 'none' ) {
-            el.style.display = 'none';
-        } else {
-            el.style.display = '';
-        }
-    }
-}
-
-function show_toggleComments() {
-    // Show edit bar item for toggling inline comments on/off only if inline comments exist on the page
-    comments = getElementsByClassName('comment', null, document);
-    if (comments.length > 0) {
-        var buttons = getElementsByClassName('toggleCommentsButton', null, document);
-        for (i = 0; i < buttons.length; i++){
-            el = buttons[i];
-            el.style.display = '';
-        }
-    }
-}
-
-
 function load() {
     // Do not name this "onload", it does not work with IE :-)
     // TODO: create separate onload for each type of view and set the
@@ -156,9 +127,6 @@
     // Editor stuff
     show_switch2gui();
 
-    // Enable menu item "ToggleComments" if inline comments exist
-    show_toggleComments();
-
     // data browser widget
     dbw_hide_buttons();
 }
@@ -786,27 +754,116 @@
 }
 jQuery(moinFirefoxWordBreak);
 
-/* For the overlays on transcluded objects */
-function removeURLPrefixes(url) {
-    return url.replace("+get/", "").replace("+modify/", "")
-}
-function attachHoverToObjects() {
-    $(".page-object").mouseenter(function(e) {
-        elements = $(".object-overlay", this)
-        elements.each(function(i) {
-            if (location.href == removeURLPrefixes(this.firstChild.href)) {
-                var elem = $(this)
-                setTimeout(function() {
-                    elem.hide()
-                }, 10)
-            }
-        })
+// globals used to save translated show/hide titles (tooltips) for Comments buttons
+var pageComments = null;
+var commentsShowTitle = ''; // "Show comments"
+var commentsHideTitle = ''; // "Hide comments"
 
-        $(elements.slice(1)).hide()
-    })
+// This is executed when user clicks a Comments button and conditionally on dom ready
+function toggleComments() {
+    // Toggle visibility of every tag with class "comment"
+    var buttons = jQuery('.moin-toggle-comments-button > a');
+    if (pageComments.is(':hidden')) {
+        pageComments.show();
+        buttons.attr('title', commentsHideTitle);
+    } else {
+        pageComments.hide();
+        buttons.attr('title', commentsShowTitle);
+    }
 }
 
-$(document).ready(attachHoverToObjects)
+// Comments initialization is executed once after document ready
+function initToggleComments() {
+    var titles;
+    var show_comments = '0';
+    pageComments = jQuery('.comment');
+    if (pageComments.length > 0) {
+        // There are comments, so show itemview Comments button
+        jQuery('.moin-toggle-comments-button').css('display', '');
+        // read translated show|hide Comments button title, split into show and hide parts, and save
+        titles = jQuery('.moin-toggle-comments-button > a').attr('title').split('|');
+        if (titles.length === 2) {
+            commentsShowTitle = titles[0];
+            commentsHideTitle = titles[1];
+            jQuery('.moin-toggle-comments-button > a').attr('title', commentsHideTitle);
+        }
+        // show or hide comments based on user option or default option:
+        //     show comments if  there is a <meta name="moin-show-comments" content="1" />
+        if (document.getElementsByName('moin-show-comments').length > 0) {
+            show_comments = document.getElementsByName('moin-show-comments')[0].content;
+        }
+        if (show_comments !== '1') {
+            // user option is to hide comments
+            toggleComments();
+        }
+    }
+}
+jQuery(document).ready(initToggleComments);
+
+// globals used to save translated show/hide titles (tooltips) for Transclusions buttons
+var transclusionShowTitle = ''; // "Show Transclusions"
+var transclusionHideTitle = ''; // "Hide Transclusions"
+
+// This is executed when user clicks a Transclusions button
+function toggleTransclusionOverlays() {
+    var overlays = jQuery('.moin-item-overlay-ul, .moin-item-overlay-lr');
+    if (overlays.length > 0) {
+        var buttons = jQuery('.moin-transclusions-button > a');
+        if (overlays.is(':visible')) {
+            overlays.hide();
+            buttons.attr('title', transclusionShowTitle);
+        } else {
+            overlays.show();
+            buttons.attr('title', transclusionHideTitle);
+}
+            }
+}
+
+// Transclusion initialization is executed once after document ready
+function initTransclusionOverlays() {
+    var elem, overlayUL, overlayLR, wrapper, wrappers;
+    var rightArrow = '\u2192';
+    // get list of elements to be wrapped;  must work in reverse order in case there are nested transclusions
+    var transclusions = jQuery(jQuery('.moin-transclusion').get().reverse());
+    transclusions.each(function (index) {
+        elem = transclusions[index];
+        // if this is the transcluded item page, do not wrap (avoid creating useless overlay links to same page)
+        if (location.href !== elem.getAttribute('data-href')) {
+            if (elem.tagName === 'DIV') {
+                wrapper = jQuery('<div class="moin-item-wrapper"></div>');
+            } else {
+                wrapper = jQuery('<span class="moin-item-wrapper"></span>');
+            }
+            overlayUL = jQuery('<a class="moin-item-overlay-ul"></a>');
+            jQuery(overlayUL).attr('href', elem.getAttribute('data-href'));
+            jQuery(overlayUL).append(rightArrow);
+            overlayLR = jQuery(overlayUL).clone(true);
+            jQuery(overlayLR).attr('class', 'moin-item-overlay-lr');
+            // if the parent of this element is an A, then wrap parent (avoid A's within A's)
+            if (jQuery(elem).parent()[0].tagName === 'A') {
+                elem = jQuery(elem).parent()[0];
+            }
+            // wrap element, add UL and LR overlay siblings, and replace old elem with wrapped elem
+            jQuery(wrapper).append(jQuery(elem).clone(true));
+            jQuery(wrapper).append(overlayUL);
+            jQuery(wrapper).append(overlayLR);
+            jQuery(elem).replaceWith(wrapper);
+        }
+    });
+    // if an element was wrapped above, then make the Transclusions buttons visible
+    wrappers = jQuery('.moin-item-wrapper');
+    if (wrappers.length > 0) {
+        jQuery('.moin-transclusions-button').css('display', '');
+        // read translated show|hide Transclusions button title, split into show and hide parts, and save
+        var titles = jQuery('.moin-transclusions-button > a').attr('title').split('|');
+        if (titles.length === 2) {
+            transclusionShowTitle = titles[0];
+            transclusionHideTitle = titles[1];
+            jQuery('.moin-transclusions-button > a').attr('title', transclusionShowTitle);
+        }
+    }
+}
+jQuery(document).ready(initTransclusionOverlays);
 
 /*
     For the quicklinks patch that
--- a/MoinMoin/storage/backends/fileserver.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/storage/backends/fileserver.py	Tue Mar 27 23:48:23 2012 +0200
@@ -27,6 +27,8 @@
 
 from MoinMoin.util.mimetype import MimeType
 
+NAME_SEP = '/'
+
 
 class Backend(BackendBase):
     """
@@ -50,26 +52,38 @@
 
     def _mkpath(self, key):
         """
-        key -> rel path, absolute path (strip mtime)
+        key -> itemname, absolute path (strip mtime)
         """
         # XXX unsafe keys?
         try:
-            relpath, mtime = key.rsplit('.', 1)
+            itemname, mtime = key.rsplit('.', 1)
         except ValueError:
             # we only generate revids that look like path.mtime,
             # so if the split does not work, the revid is invalid
             # and we raise KeyError like if the rev is not there
             raise KeyError(key)
-        return relpath, os.path.join(self.path, relpath)
+        # we get NAME_SEP and need to replace them by os.sep to make valid pathes:
+        if os.sep == NAME_SEP:
+            relpath = itemname
+        else:
+            relpath = itemname.replace(NAME_SEP, os.sep)
+        return itemname, os.path.join(self.path, relpath)
 
     def _mkkey(self, path):
         """
-        absolute path -> relpath, mtime
+        absolute path -> itemname, mtime
         """
         st = os.stat(path)
         root = self.path
         assert path.startswith(root)
-        return path[len(root)+1:], int(st.st_mtime)
+        relpath = path[len(root)+1:]
+        # we always want to give NAME_SEP-separated names (not backslash):
+        if os.sep == NAME_SEP:
+            itemname = relpath
+        else:
+            itemname = relpath.replace(os.sep, NAME_SEP)
+        mtime = int(st.st_mtime)
+        return itemname, mtime
 
     def _encode(self, key):
         """
@@ -81,15 +95,15 @@
     def _decode(self, qkey):
         return url_unquote(qkey)
 
-    def _get_meta(self, fn, path):
+    def _get_meta(self, itemname, path):
         try:
             st = os.stat(path)
         except OSError as e:
             if e.errno == errno.ENOENT:
-                raise KeyError(fn)
+                raise KeyError(itemname)
             raise
         meta = {}
-        meta[NAME] = fn
+        meta[NAME] = itemname
         meta[MTIME] = int(st.st_mtime) # use int, not float
         meta[REVID] = unicode(self._encode('%s.%d' % (meta[NAME], meta[MTIME])))
         meta[ITEMID] = meta[REVID]
@@ -101,7 +115,7 @@
             size = 0
         elif stat.S_ISREG(st.st_mode):
             # normal file
-            ct = unicode(MimeType(filename=fn).content_type())
+            ct = unicode(MimeType(filename=itemname).content_type())
             size = int(st.st_size) # use int instead of long
         else:
             # symlink, device file, etc.
@@ -134,7 +148,7 @@
             content = unicode(err)
         return content
 
-    def _get_data(self, fn, path):
+    def _get_data(self, itemname, path):
         try:
             st = os.stat(path)
             if stat.S_ISDIR(st.st_mode):
@@ -146,7 +160,7 @@
                 return StringIO('')
         except (OSError, IOError) as e:
             if e.errno == errno.ENOENT:
-                raise KeyError(fn)
+                raise KeyError(itemname)
             raise
 
     def __iter__(self):
@@ -162,8 +176,8 @@
 
     def retrieve(self, key):
         key = self._decode(key)
-        fn, path = self._mkpath(key)
-        meta = self._get_meta(fn, path)
-        data = self._get_data(fn, path)
+        itemname, path = self._mkpath(key)
+        meta = self._get_meta(itemname, path)
+        data = self._get_data(itemname, path)
         return meta, data
 
--- a/MoinMoin/storage/stores/_tests/test_sqla.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/storage/stores/_tests/test_sqla.py	Tue Mar 27 23:48:23 2012 +0200
@@ -30,6 +30,6 @@
 
 @pytest.mark.multi(Store=[BytesStore, FileStore])
 def test_from_uri(tmpdir, Store):
-    store = Store.from_uri("sqlite://%s/test_base" % tmpdir)
-    assert store.db_uri == "sqlite://%s/test_base" % tmpdir
+    store = Store.from_uri("sqlite://%s::test_base" % tmpdir)
+    assert store.db_uri == "sqlite://%s" % tmpdir
     assert store.table_name == "test_base"
--- a/MoinMoin/storage/stores/_tests/test_sqlite.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/storage/stores/_tests/test_sqlite.py	Tue Mar 27 23:48:23 2012 +0200
@@ -48,12 +48,13 @@
 
 @pytest.mark.multi(Store=[BytesStore, FileStore])
 def test_from_uri(tmpdir, Store):
-    store = Store.from_uri("%s:test_table:0" % tmpdir)
+    store = Store.from_uri("%s::test_table::0" % tmpdir)
     assert store.db_name == tmpdir
     assert store.table_name == 'test_table'
     assert store.compression_level == 0
 
-    store = Store.from_uri("%s:test_table:2" % tmpdir)
+    store = Store.from_uri("%s::test_table::2" % tmpdir)
     assert store.db_name == tmpdir
     assert store.table_name == 'test_table'
     assert store.compression_level == 2
+
--- a/MoinMoin/storage/stores/sqla.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/storage/stores/sqla.py	Tue Mar 27 23:48:23 2012 +0200
@@ -33,11 +33,8 @@
         :param cls: Class to create
         :param uri: The database uri that we pass on to SQLAlchemy.
         """
-
-        params = [uri]
-        if '/' in uri.rsplit("//")[-1]:
-            table_name = uri.rsplit("/")[-1]
-            params.append(table_name)
+        params = uri.split("::") # using "::" to support windows pathnames that
+                                 # may include ":" after the drive letter.
         return cls(*params)
 
     def __init__(self, db_uri=None, table_name='store', verbose=False):
--- a/MoinMoin/storage/stores/sqlite.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/storage/stores/sqlite.py	Tue Mar 27 23:48:23 2012 +0200
@@ -32,10 +32,11 @@
 
         :param cls: Class to create
         :param uri: The URI should follow the following template
-                    db_name:table_name:compression_level
+                    db_name::table_name::compression_level
                     where table_name and compression level are optional
         """
-        params = uri.split(":")
+        params = uri.split("::") # using "::" to support windows pathnames that
+                                 # may include ":" after the drive letter.
         if len(params) == 3:
             params[2] = int(params[2])
         return cls(*params)
--- a/MoinMoin/templates/base.html	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/templates/base.html	Tue Mar 27 23:48:23 2012 +0200
@@ -15,6 +15,9 @@
         user.edit_on_doubleclick and user.may.write(item_name) -%}
             <meta name="edit_on_doubleclick" content="1" />
     {%- endif %}
+    {%- if user.show_comments -%}
+            <meta name="moin-show-comments" content="1" />
+    {%- endif %}
     {% for name, content in theme_supp.meta_items -%}
         <meta name="{{ name }}" content="{{ content }}" />
     {% endfor %}
--- a/MoinMoin/templates/itemviews.html	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/templates/itemviews.html	Tue Mar 27 23:48:23 2012 +0200
@@ -61,11 +61,17 @@
             {%- endif %}
 
             {%- if endpoint == 'special.comments' %}
-                <li class="toggleCommentsButton" style="display:none;">
+                <li class="moin-toggle-comments-button" style="display:none;">
                     <a href="#" onClick="toggleComments();return false;" title="{{ title }}">{{ label }}</a>
                 </li>
             {%- endif %}
 
+        {% if endpoint == 'special.transclusions' -%}
+            <li class="moin-transclusions-button" style="display:none;">
+            <a href="#" onClick="toggleTransclusionOverlays();return false;" title="{{ title }}">{{ label }}</a>
+            </li>
+        {%- endif %}
+
             {%- if endpoint == 'special.supplementation' %}
                 {%- for sub_item_name in cfg.supplementation_item_names %}
                     {%- set current_sub = item_name.rsplit('/', 1)[-1] %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/info.json	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,10 @@
+{
+    "identifier":   "foobar",
+    "application":  "MoinMoin",
+    "name":         "FooBar Theme",
+    "description":  "moin2's builtin sidebar theme",
+    "author":       "MoinMoin developers",
+    "website":      "http://moinmo.in/",
+    "license":      "see MoinMoin license",
+    "doctype":      "html5"
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/static/css/common.css	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,239 @@
+/* Important note: DO NOT EDIT THIS FILE!
+ *
+ * The CSS seen below is automatically generated using the "stylus" tool.
+ * To modify it, edit the files in the "stylus" directory and re-generate
+ * this file from them:
+ *
+ * stylus --include-css --compress < main.styl > ../common.css
+ */
+/*
+Copied from:  http://code.google.com/p/html5resetcss/
+
+html5doctor.com Reset Stylesheet
+v1.6.1
+Last Updated: 2010-09-17
+Author: Richard Clark - http: //richclarkdesign.com
+Twitter: @rich_clark
+*/
+html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p,
+blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins,
+kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, figcaption, figure, footer, header, hgroup,
+menu, nav, section, summary, time, mark, audio,
+video { margin: 0; padding: 0; border: 0; outline: 0;
+          font-size: 100%; vertical-align: baseline; background: transparent; }
+body { line-height: 1; }
+article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav,
+section { display: block; }
+nav ul { list-style: none; }
+blockquote, q { quotes: none; }
+blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
+a { margin: 0; padding: 0; font-size: 100%; vertical-align: baseline; background: transparent; }
+ins { background-color: #ff9; color: #000; text-decoration: none; }
+mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
+del { text-decoration: line-through; }
+abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
+table { border-collapse: collapse; border-spacing: 0; }
+hr { display: block; height: 1px; border: 0; border-top: 1px solid #cccccc; margin: 1em 0; padding: 0; }
+input, select { vertical-align: middle; }
+/* end HTML5 reset */
+.hll { background-color: #ffffcc }
+.c { color: #408080; font-style: italic } /* Comment */
+.err { border: 1px solid #FF0000 } /* Error */
+.k { color: #008000; font-weight: bold } /* Keyword */
+.o { color: #666666 } /* Operator */
+.cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.cp { color: #BC7A00 } /* Comment.Preproc */
+.c1 { color: #408080; font-style: italic } /* Comment.Single */
+.cs { color: #408080; font-style: italic } /* Comment.Special */
+.gd { color: #A00000 } /* Generic.Deleted */
+.ge { font-style: italic } /* Generic.Emph */
+.gr { color: #FF0000 } /* Generic.Error */
+.gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.gi { color: #00A000 } /* Generic.Inserted */
+.go { color: #808080 } /* Generic.Output */
+.gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.gs { font-weight: bold } /* Generic.Strong */
+.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.gt { color: #0040D0 } /* Generic.Traceback */
+.kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.kp { color: #008000 } /* Keyword.Pseudo */
+.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.kt { color: #B00040 } /* Keyword.Type */
+.m { color: #666666 } /* Literal.Number */
+.s { color: #BA2121 } /* Literal.String */
+.na { color: #7D9029 } /* Name.Attribute */
+.nb { color: #008000 } /* Name.Builtin */
+.nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.no { color: #880000 } /* Name.Constant */
+.nd { color: #AA22FF } /* Name.Decorator */
+.ni { color: #999999; font-weight: bold } /* Name.Entity */
+.ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.nf { color: #0000FF } /* Name.Function */
+.nl { color: #A0A000 } /* Name.Label */
+.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.nt { color: #008000; font-weight: bold } /* Name.Tag */
+.nv { color: #19177C } /* Name.Variable */
+.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.w { color: #bbbbbb } /* Text.Whitespace */
+.mf { color: #666666 } /* Literal.Number.Float */
+.mh { color: #666666 } /* Literal.Number.Hex */
+.mi { color: #666666 } /* Literal.Number.Integer */
+.mo { color: #666666 } /* Literal.Number.Oct */
+.sb { color: #BA2121 } /* Literal.String.Backtick */
+.sc { color: #BA2121 } /* Literal.String.Char */
+.sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.s2 { color: #BA2121 } /* Literal.String.Double */
+.se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.sh { color: #BA2121 } /* Literal.String.Heredoc */
+.si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.sx { color: #008000 } /* Literal.String.Other */
+.sr { color: #BB6688 } /* Literal.String.Regex */
+.s1 { color: #BA2121 } /* Literal.String.Single */
+.ss { color: #19177C } /* Literal.String.Symbol */
+.bp { color: #008000 } /* Name.Builtin.Pseudo */
+.vc { color: #19177C } /* Name.Variable.Class */
+.vg { color: #19177C } /* Name.Variable.Global */
+.vi { color: #19177C } /* Name.Variable.Instance */
+.il { color: #666666 } /* Literal.Number.Integer.Long */
+/* smileys -- <span class="moin-text-icon moin-smile">:-)</span> */
+.moin-text-icon { font-size: 0; color: transparent; }
+.moin-alert:before { content: url('../img/smileys/alert.png'); }
+.moin-angry:before { content: url('../img/smileys/angry.png'); }
+.moin-attention:before { content: url('../img/smileys/attention.png'); }
+.moin-biggrin:before { content: url('../img/smileys/biggrin.png'); }
+.moin-checkmark:before { content: url('../img/smileys/checkmark.png'); }
+.moin-devil:before { content: url('../img/smileys/devil.png'); }
+.moin-frown:before { content: url('../img/smileys/frown.png'); }
+.moin-icon-error:before { content: url('../img/smileys/icon-error.png'); }
+.moin-icon-info:before { content: url('../img/smileys/icon-info.png'); }
+.moin-idea:before { content: url('../img/smileys/idea.png'); }
+.moin-ohwell:before { content: url('../img/smileys/ohwell.png'); }
+.moin-prio1:before { content: url('../img/smileys/prio1.png'); }
+.moin-prio2:before { content: url('../img/smileys/prio2.png'); }
+.moin-prio3:before { content: url('../img/smileys/prio3.png'); }
+.moin-redface:before { content: url('../img/smileys/redface.png'); }
+.moin-sad:before { content: url('../img/smileys/sad.png'); }
+.moin-smile:before { content: url('../img/smileys/smile.png'); }
+.moin-smile2:before { content: url('../img/smileys/smile2.png'); }
+.moin-smile3:before { content: url('../img/smileys/smile3.png'); }
+.moin-smile4:before { content: url('../img/smileys/smile4.png'); }
+.moin-star_off:before { content: url('../img/smileys/star_off.png'); }
+.moin-star_on:before { content: url('../img/smileys/star_on.png'); }
+.moin-thumbs-up:before { content: url('../img/smileys/thumbs-up.png'); }
+.moin-tired:before { content: url('../img/smileys/tired.png'); }
+.moin-tongue:before { content: url('../img/smileys/tongue.png'); }
+#moin-content div.caution{background-image:url("../img/admonitions/caution.png")}
+#moin-content div.important{background-image:url("../img/admonitions/important.png")}
+#moin-content div.note{background-image:url("../img/admonitions/note.png")}
+#moin-content div.tip{background-image:url("../img/admonitions/tip.png")}
+#moin-content div.warning{background-image:url("../img/admonitions/warning.png")}
+#moin-content div.caution,#moin-content div.important,#moin-content div.note,#moin-content div.tip,#moin-content div.warning{color:#000;background-color:#f9f9ff;background-repeat:no-repeat;background-position:8px 8px;border:1px solid #e5e5e5;margin:10px 30px 10px 30px;min-height:64px;padding-left:64px;clear:both;}
+#moin-content div.caution p,#moin-content div.important p,#moin-content div.note p,#moin-content div.tip p,#moin-content div.warning p{margin-top:8px}
+/* wiki parser  - no moin- prefix added here, these classes are used within pages: {{{#!wiki solid  */
+.comment { color: #555; background-color: #DDF; }
+.red { background-color: #FCC; }
+.green { background-color: #CFC; }
+.blue { background-color: #CCF; }
+.yellow { background-color: #FFF29F; }
+.orange { background-color: #FFD59B; }
+.solid { border: 2px solid #000; padding: 2px; clear: both; }
+.dashed { border: 2px dashed #AEBDCC; padding: 2px; clear: both; }
+.dotted { border: 2px dotted #AEBDCC; padding: 2px; clear: both; }
+.left { text-align: left; }
+.center { text-align: center; }
+.right { text-align: right; }
+.justify { text-align: justify; }
+body{color:#444;background-color:#eee;font-family:sans-serif}
+#moin-global-tray{float:left;width:16.666666666666668%;padding:.5%;overflow:hidden}
+#moin-main-container{float:left;width:81.13333333333333%;padding:.5%}
+#moin-main-box{background-color:#fff;border:1px solid #ccc;border-radius:6px;box-shadow:2px 2px 4px #444;overflow:hidden}
+#moin-header{background-color:#efe;border-bottom:1px solid #ccc;padding:.2% .5%;overflow:auto}
+#moin-content-no-panel{float:left;width:98.56746096959736%;padding:.6162695152013148%;border-right:1px solid #ccc}
+#moin-content-with-panel{float:left;width:76.79260476581759%;padding:.6162695152013148%;border-right:1px solid #ccc}
+#moin-local-panel{float:left;width:20.54231717337716%;padding:.6162695152013148%;margin-left:-1px;border-left:1px solid #ccc}
+#moin-footer{clear:both;font-size:.8em;color:#888;padding:.5% .5%;overflow:auto}
+#moin-breadcrumbs-location{float:left;padding:.3em .5em .2em .5em;font-weight:bold}
+#moin-search{float:right;padding:.3em .5em .2em .5em}
+#moin-logo{width:100%;padding:0 0 1em 0;}
+#moin-logo a{display:block;width:100%;height:70px;background-repeat:no-repeat;background-position:center center}
+#moin-global-panel ul,#moin-local-panel ul{list-style-type:none;margin:0;}
+#moin-global-panel ul li,#moin-local-panel ul li{font-size:1em;color:#008;font-weight:bold;padding:.5em;border:1px solid #ccc;border-radius:4px;box-shadow:1px 1px 2px #444;margin-left:.5em;margin-bottom:.5em;overflow:hidden;word-wrap:break-word;}
+#moin-global-panel ul li ul,#moin-local-panel ul li ul{padding:.2em .1em;}
+#moin-global-panel ul li ul li,#moin-local-panel ul li ul li{font-size:.8em;color:#000;font-weight:normal;padding:.1em .1em .1em .1em;border:none;box-shadow:none;margin:0}
+#moin-footer ul,#moin-credits{float:left;list-style-type:none;}
+#moin-footer ul li,#moin-credits li{padding:.1em}
+#moin-footer-logos{float:right;}
+#moin-footer-logos ul li{display:inline}
+a{text-decoration:none;}
+a:link{color:#47f}
+a:visited{color:#04a}
+a:hover{color:#f00;text-decoration:underline}
+a:active{color:#008000;text-decoration:underline}
+a.moin-nonexistent:link{color:#666}
+a.moin-nonexistent:visited{color:#808080}
+a.moin-nonexistent:hover{color:#000}
+a.moin-nonexistent:active{color:#000}
+ul,dl{margin-left:1.5em}
+ol{margin-left:3em;}
+ol ol{margin-left:1.5em}
+li,dt{padding:.1em}
+dt{font-weight:bold}
+dd{margin-left:1.5em}
+ul.moin-nobullet-list{list-style-type:none}
+ol.moin-upperalpha-list{list-style-type:upper-alpha}
+ol.moin-loweralpha-list{list-style-type:lower-alpha}
+ol.moin-upperroman-list{list-style-type:upper-roman}
+ol.moin-lowerroman-list{list-style-type:lower-roman}
+ul.moin-tags{list-style:none;}
+ul.moin-tags li{display:inline;}
+ul.moin-tags li.weight0{font-size:48.22530864197532%}
+ul.moin-tags li.weight1{font-size:57.870370370370374%}
+ul.moin-tags li.weight2{font-size:69.44444444444446%}
+ul.moin-tags li.weight3{font-size:83.33333333333334%}
+ul.moin-tags li.weight4{font-size:100%}
+ul.moin-tags li.weight5{font-size:120%}
+ul.moin-tags li.weight6{font-size:144%}
+ul.moin-tags li.weight7{font-size:172.79999999999998%}
+ul.moin-tags li.weight8{font-size:207.35999999999999%}
+ul.moin-tags li.weight9{font-size:248.83199999999994%}
+h1{font-size:1.7279999999999998em;margin:.5787037037037038em 0;border-bottom:3px solid #4d7da9;padding-bottom:3px}
+h2{font-size:1.44em;margin:.6944444444444444em 0;border-bottom:3px solid #4d7da9;padding-bottom:3px}
+h3{font-size:1.2em;margin:.8333333333333334em 0;border-bottom:2px solid #4d7da9;padding-bottom:2px}
+h4{font-size:1em;margin:1em 0;border-bottom:2px solid #4d7da9;padding-bottom:2px}
+h5{font-size:.8333333333333334em;margin:1.2em 0;border-bottom:1px solid #4d7da9;padding-bottom:1px}
+h6{font-size:.6944444444444445em;margin:1.4399999999999997em 0;border-bottom:1px solid #4d7da9;padding-bottom:1px}
+a.permalink{display:none;cursor:pointer;margin-left:.1em;color:#888;}
+a.permalink:hover{color:#444}
+h1:hover .permalink,h2:hover .permalink,h3:hover .permalink,h4:hover .permalink,h5:hover .permalink,h6:hover .permalink{display:inline;text-decoration:none}
+hr{background-color:#444;border:0;margin:.9em 0;height:1px;}
+hr.moin-hr1{height:2px}
+hr.moin-hr2{height:3px}
+hr.moin-hr3{height:5px}
+hr.moin-hr4{height:7px}
+hr.moin-hr5{height:9px}
+hr.moin-hr6{height:12px}
+table{margin:.5em;border-collapse:collapse;}
+table th,table td{padding:.3em .4em;vertical-align:middle;text-align:left}
+table th{border:1px solid #4d7da9;background-color:#81bbf2}
+table td{border:1px solid #adb9cc}
+table.zebra{border:none;border-collapse:separate;border-spacing:1px;}
+table.zebra thead{background-color:#81bbf2}
+table.zebra tfoot{background-color:#c4d9ff}
+table.zebra tbody tr,table.zebra > tr{background-color:#eef1f5}
+table.zebra tbody tr:nth-child(odd),table.zebra > tr:nth-child(odd){background-color:#d9dfe8}
+table.zebra th,table.zebra td{border:none}
+pre{font-family:monospace;white-space:pre-wrap;word-wrap:break-word;border:1px solid #aebdcc;background-color:#f3f5f7;margin:.33em 0;padding:5px;clear:both;}
+pre.comment{background-color:#ccc;color:#f00;margin:0;padding:0;border:0;}
+pre.comment:before{content:url("../img/attention.png")}
+textarea{font-family:monospace;width:100%;border:1px solid #ccc}
+input#f_comment{width:100%;border:1px solid #ccc;margin:.3em 0}
+sub{vertical-align:sub}
+sup{vertical-align:super}
+.moin-big{font-size:1.17em}
+.moin-small{font-size:.83em}
+@media print{#moin-global-tray,#moin-local-panel,#moin-footer,#moin-search{display:none}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/static/css/msie.css	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,2 @@
+/* for now, don't add special workarounds for Internet Explorer */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/static/css/stylus/admonitions.styl	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,27 @@
+// admonitions  - no moin- prefix added  here, these classes are used within pages: {{{#!wiki caution
+
+#moin-content
+    div.caution
+        background-image url("../img/admonitions/caution.png")
+    div.important
+        background-image url("../img/admonitions/important.png")
+    div.note
+        background-image url("../img/admonitions/note.png")
+    div.tip
+        background-image url("../img/admonitions/tip.png")
+    div.warning
+        background-image url("../img/admonitions/warning.png")
+
+    div.caution, div.important, div.note, div.tip, div.warning
+        color black
+        background-color #F9F9FF
+        background-repeat no-repeat
+        background-position 8px 8px
+        border 1px solid #E5E5E5
+        margin 10px 30px 10px 30px
+        min-height 64px
+        padding-left 64px
+        clear both
+        p
+            margin-top 8px  // to align text with big graphic
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/static/css/stylus/main.styl	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,364 @@
+// moin2 foobar theme css
+
+// include a comment with a notice that the css file is automatically generated:
+@import "stylus_notice.css"
+
+// reset all browser-specific default to have common defaults everywhere:
+@import "reset.css"
+
+// auto-generated by pygmentize -S default -f html >pygments_default.css
+@import "pygments_default.css"
+
+// smileys used by moin wiki parser (and maybe others)
+@import "smileys.css"
+
+// admonitions used by moin wiki parser (and maybe others)
+@import "admonitions"
+
+// user styles used by moin wiki parser (and maybe others) like red/green/solid/dashed/comment...
+@import "userstyles.css"
+
+body_color = #444444
+body_bg_color = #eeeeee
+main_bg_color = #ffffff
+border_style = 1px solid #cccccc
+header_bg_color = #eeffee
+footer_color = #888888
+panel_titles_color = #000088
+panel_items_color = #000000
+heading_underline_color = #4D7DA9
+shadow_color = #444444
+
+font_family = sans-serif
+main_font_size = 1em
+small_font_size = main_font_size * 0.8
+heading_scale = 1.2  // font size factor for h1 .. h6
+
+dir = left  // 'left' means left-to-right (ltr), 'right' means right-to-left (rtl)
+
+scale = 1  // we have the whole screen width as base
+global_tray_width = 100% / 6 * scale
+global_padding_width = 0.5% * scale
+main_container_width = 99.8% - global_tray_width - (4 * global_padding_width)
+
+scale = 100% / main_container_width  // we have the main container width as base
+local_panel_width = 100% / 6 * scale
+local_padding_width = 0.5% * scale
+content_width_with_panel = 99.8% - local_panel_width - (4 * local_padding_width)
+content_width_no_panel = 99.8% - (2 * local_padding_width)
+
+body
+    color body_color
+    background-color body_bg_color
+    font-family font_family
+
+// the main elements - just the big picture first: panels, header, content, footer
+
+#moin-global-tray
+    float dir
+    width global_tray_width
+    padding global_padding_width
+    overflow hidden
+
+#moin-main-container
+    float dir
+    width main_container_width
+    padding global_padding_width
+
+// contains header and content, but not footer
+#moin-main-box
+    background-color main_bg_color
+    border border_style
+    border-radius 6px
+    box-shadow 2px 2px 4px shadow_color
+    overflow hidden
+
+#moin-header
+    background-color header_bg_color
+    border-bottom border_style
+    padding 0.2% 0.5%
+    overflow auto
+
+#moin-content-no-panel
+    float dir
+    width content_width_no_panel
+    padding local_padding_width
+    {'border-' + opposite-position(dir)} border_style
+
+#moin-content-with-panel
+    float dir
+    width content_width_with_panel
+    padding local_padding_width
+    {'border-' + opposite-position(dir)} border_style
+
+#moin-local-panel
+    float dir
+    width local_panel_width
+    padding local_padding_width
+    {'margin-' + dir} -1px  // make it overlap with content border, see border_style
+    {'border-' + dir} border_style
+
+#moin-footer
+    clear both
+    font-size small_font_size
+    color footer_color
+    padding 0.5% 0.5%
+    overflow auto
+
+// now the stuff inside the main elements
+
+// header elements
+#moin-breadcrumbs-location
+    float dir
+    padding 0.3em 0.5em 0.2em 0.5em
+    font-weight bold
+
+#moin-search
+    float opposite-position(dir)
+    padding 0.3em 0.5em 0.2em 0.5em
+
+// panels, footer
+#moin-logo
+    width 100%
+    padding 0 0 1em 0
+    a
+        display block
+        width 100%
+        height 70px
+        background-repeat no-repeat
+        background-position center center
+
+#moin-global-panel ul,
+#moin-local-panel ul
+    list-style-type none 
+    margin 0
+    li
+        font-size main_font_size
+        color panel_titles_color
+        font-weight bold
+        padding 0.5em
+        border border_style
+        border-radius 4px
+        box-shadow 1px 1px 2px shadow_color
+        margin-left 0.5em
+        margin-bottom 0.5em
+        overflow hidden
+        word-wrap break-word
+        ul
+            padding 0.2em 0.1em
+            li
+                font-size small_font_size
+                color panel_items_color
+                font-weight normal
+                padding 0.1em 0.1em 0.1em 0.1em
+                border none
+                box-shadow none
+                margin 0
+
+#moin-footer ul,
+#moin-credits
+    float dir
+    list-style-type none 
+    li
+        padding 0.1em
+
+#moin-footer-logos
+    float opposite-position(dir)
+    ul li
+        display inline
+
+
+// links
+a
+    text-decoration none
+    // order must be: link, visited, hover, active
+    &:link
+        color #47F
+    &:visited
+        color #04A
+    &:hover
+        color red
+        text-decoration underline
+    &:active
+        color green
+        text-decoration underline
+    &.moin-nonexistent:link
+        color #666
+    &.moin-nonexistent:visited
+        color grey
+    &.moin-nonexistent:hover
+        color black
+    &.moin-nonexistent:active
+        color black
+
+
+// lists
+ul, dl
+    margin-left 1.5em
+ol
+    // ordered list, first level needs big margin that will contain the number
+    margin-left 3em
+    ol
+        // for >= second level we need less
+        margin-left 1.5em
+
+li, dt
+    padding 0.1em
+
+dt
+    font-weight bold
+dd
+    margin-left 1.5em
+
+ul
+    &.moin-nobullet-list
+        list-style-type none
+
+ol
+    &.moin-upperalpha-list
+        list-style-type upper-alpha
+    &.moin-loweralpha-list
+        list-style-type lower-alpha
+    &.moin-upperroman-list
+        list-style-type upper-roman
+    &.moin-lowerroman-list
+        list-style-type lower-roman
+
+// tags list / tag cloud
+tag_scale = 1.2
+tag_font_size = 100%
+
+ul.moin-tags
+    list-style none
+    li
+        display inline
+        for n in 0 1 2 3 4 5 6 7 8 9
+            { '&.weight' + n }
+                scale_tag = tag_scale ** (n - 4)
+                font-size tag_font_size * scale_tag
+
+// headings
+for n in 1 2 3 4 5 6
+    {'h' + n}
+        scale_font = heading_scale ** (4 - n)
+        font-size main_font_size * scale_font
+        margin (1em / scale_font) 0
+        heading_underline_thickness = floor(4px - n / 2)
+        border-bottom heading_underline_thickness solid heading_underline_color
+        padding-bottom heading_underline_thickness
+
+// special style for heading with mouseover permalinks
+a.permalink
+    display none
+    cursor pointer
+    margin-left 0.1em
+    color footer_color
+    &:hover
+        color body_color
+
+h1:hover .permalink,
+h2:hover .permalink,
+h3:hover .permalink,
+h4:hover .permalink,
+h5:hover .permalink,
+h6:hover .permalink
+    display inline
+    text-decoration none
+
+// horizontal rule ---- and custom rules ----- to ----------
+hr
+    background-color body_color
+    border 0
+    margin .9em 0
+    height 1px
+    &.moin-hr1
+        height 2px
+    &.moin-hr2
+        height 3px
+    &.moin-hr3
+        height 5px
+    &.moin-hr4
+        height 7px
+    &.moin-hr5
+         height 9px
+    &.moin-hr6
+        height 12px
+
+// tables
+table
+    margin 0.5em
+    border-collapse collapse
+    th, td
+        padding 0.3em 0.4em
+        vertical-align middle
+        text-align left
+    th
+        border 1px solid #4D7DA9
+        background-color #81BBF2
+    td
+        border 1px solid #ADB9CC
+
+table.zebra
+    border none
+    border-collapse separate
+    border-spacing 1px
+    thead
+        background-color #81BBF2
+    tfoot
+        background-color #C4D9FF
+    tbody tr,
+    > tr
+        background-color #EEF1F5
+    tbody tr:nth-child(odd),
+    > tr:nth-child(odd)
+        background-color #D9DFE8
+    th,
+    td
+        border none
+
+pre
+    font-family monospace
+    white-space pre-wrap
+    word-wrap break-word
+    border 1px solid #AEBDCC
+    background-color #F3F5F7
+    margin .33em 0
+    padding 5px
+    clear both
+    &.comment
+        background-color #CCC
+        color red
+        margin 0
+        padding 0
+        border 0
+        &:before
+            content url(../img/attention.png)
+
+textarea
+    font-family monospace
+    width 100%
+    border border_style
+
+input#f_comment
+    width 100%
+    border border_style
+    margin .3em 0
+
+// text styles
+sub
+    vertical-align sub
+sup
+    vertical-align super
+.moin-big
+    font-size 1.17em
+.moin-small
+    font-size .83em
+
+/* fix tests -- currently checking <big> and <small> */
+@media print
+    #moin-global-tray
+    #moin-local-panel
+    #moin-footer
+    #moin-search
+        display none
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/static/css/stylus/pygments_default.css	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,61 @@
+.hll { background-color: #ffffcc }
+.c { color: #408080; font-style: italic } /* Comment */
+.err { border: 1px solid #FF0000 } /* Error */
+.k { color: #008000; font-weight: bold } /* Keyword */
+.o { color: #666666 } /* Operator */
+.cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.cp { color: #BC7A00 } /* Comment.Preproc */
+.c1 { color: #408080; font-style: italic } /* Comment.Single */
+.cs { color: #408080; font-style: italic } /* Comment.Special */
+.gd { color: #A00000 } /* Generic.Deleted */
+.ge { font-style: italic } /* Generic.Emph */
+.gr { color: #FF0000 } /* Generic.Error */
+.gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.gi { color: #00A000 } /* Generic.Inserted */
+.go { color: #808080 } /* Generic.Output */
+.gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.gs { font-weight: bold } /* Generic.Strong */
+.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.gt { color: #0040D0 } /* Generic.Traceback */
+.kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.kp { color: #008000 } /* Keyword.Pseudo */
+.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.kt { color: #B00040 } /* Keyword.Type */
+.m { color: #666666 } /* Literal.Number */
+.s { color: #BA2121 } /* Literal.String */
+.na { color: #7D9029 } /* Name.Attribute */
+.nb { color: #008000 } /* Name.Builtin */
+.nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.no { color: #880000 } /* Name.Constant */
+.nd { color: #AA22FF } /* Name.Decorator */
+.ni { color: #999999; font-weight: bold } /* Name.Entity */
+.ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.nf { color: #0000FF } /* Name.Function */
+.nl { color: #A0A000 } /* Name.Label */
+.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.nt { color: #008000; font-weight: bold } /* Name.Tag */
+.nv { color: #19177C } /* Name.Variable */
+.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.w { color: #bbbbbb } /* Text.Whitespace */
+.mf { color: #666666 } /* Literal.Number.Float */
+.mh { color: #666666 } /* Literal.Number.Hex */
+.mi { color: #666666 } /* Literal.Number.Integer */
+.mo { color: #666666 } /* Literal.Number.Oct */
+.sb { color: #BA2121 } /* Literal.String.Backtick */
+.sc { color: #BA2121 } /* Literal.String.Char */
+.sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.s2 { color: #BA2121 } /* Literal.String.Double */
+.se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.sh { color: #BA2121 } /* Literal.String.Heredoc */
+.si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.sx { color: #008000 } /* Literal.String.Other */
+.sr { color: #BB6688 } /* Literal.String.Regex */
+.s1 { color: #BA2121 } /* Literal.String.Single */
+.ss { color: #19177C } /* Literal.String.Symbol */
+.bp { color: #008000 } /* Name.Builtin.Pseudo */
+.vc { color: #19177C } /* Name.Variable.Class */
+.vg { color: #19177C } /* Name.Variable.Global */
+.vi { color: #19177C } /* Name.Variable.Instance */
+.il { color: #666666 } /* Literal.Number.Integer.Long */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/static/css/stylus/reset.css	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,33 @@
+/*
+Copied from:  http://code.google.com/p/html5resetcss/
+
+html5doctor.com Reset Stylesheet
+v1.6.1
+Last Updated: 2010-09-17
+Author: Richard Clark - http: //richclarkdesign.com
+Twitter: @rich_clark
+*/
+html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p,
+blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins,
+kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, figcaption, figure, footer, header, hgroup,
+menu, nav, section, summary, time, mark, audio,
+video { margin: 0; padding: 0; border: 0; outline: 0;
+            font-size: 100%; vertical-align: baseline; background: transparent; }
+body { line-height: 1; }
+article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav,
+section { display: block; }
+nav ul { list-style: none; }
+blockquote, q { quotes: none; }
+blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
+a { margin: 0; padding: 0; font-size: 100%; vertical-align: baseline; background: transparent; }
+ins { background-color: #ff9; color: #000; text-decoration: none; }
+mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
+del { text-decoration: line-through; }
+abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
+table { border-collapse: collapse; border-spacing: 0; }
+hr { display: block; height: 1px; border: 0; border-top: 1px solid #cccccc; margin: 1em 0; padding: 0; }
+input, select { vertical-align: middle; }
+/* end HTML5 reset */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/static/css/stylus/smileys.css	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,28 @@
+/* smileys -- <span class="moin-text-icon moin-smile">:-)</span> */
+.moin-text-icon { font-size: 0; color: transparent; }
+.moin-alert:before { content: url('../img/smileys/alert.png'); }
+.moin-angry:before { content: url('../img/smileys/angry.png'); }
+.moin-attention:before { content: url('../img/smileys/attention.png'); }
+.moin-biggrin:before { content: url('../img/smileys/biggrin.png'); }
+.moin-checkmark:before { content: url('../img/smileys/checkmark.png'); }
+.moin-devil:before { content: url('../img/smileys/devil.png'); }
+.moin-frown:before { content: url('../img/smileys/frown.png'); }
+.moin-icon-error:before { content: url('../img/smileys/icon-error.png'); }
+.moin-icon-info:before { content: url('../img/smileys/icon-info.png'); }
+.moin-idea:before { content: url('../img/smileys/idea.png'); }
+.moin-ohwell:before { content: url('../img/smileys/ohwell.png'); }
+.moin-prio1:before { content: url('../img/smileys/prio1.png'); }
+.moin-prio2:before { content: url('../img/smileys/prio2.png'); }
+.moin-prio3:before { content: url('../img/smileys/prio3.png'); }
+.moin-redface:before { content: url('../img/smileys/redface.png'); }
+.moin-sad:before { content: url('../img/smileys/sad.png'); }
+.moin-smile:before { content: url('../img/smileys/smile.png'); }
+.moin-smile2:before { content: url('../img/smileys/smile2.png'); }
+.moin-smile3:before { content: url('../img/smileys/smile3.png'); }
+.moin-smile4:before { content: url('../img/smileys/smile4.png'); }
+.moin-star_off:before { content: url('../img/smileys/star_off.png'); }
+.moin-star_on:before { content: url('../img/smileys/star_on.png'); }
+.moin-thumbs-up:before { content: url('../img/smileys/thumbs-up.png'); }
+.moin-tired:before { content: url('../img/smileys/tired.png'); }
+.moin-tongue:before { content: url('../img/smileys/tongue.png'); }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/static/css/stylus/stylus_notice.css	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,10 @@
+/* Important note: DO NOT EDIT THIS FILE!
+ *
+ * The CSS seen below is automatically generated using the "stylus" tool.
+ * To modify it, edit the files in the "stylus" directory and re-generate
+ * this file from them:
+ *
+ * stylus --include-css --compress < main.styl > ../common.css
+ */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/static/css/stylus/userstyles.css	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,15 @@
+/* wiki parser  - no moin- prefix added here, these classes are used within pages: {{{#!wiki solid  */
+.comment { color: #555; background-color: #DDF; }
+.red { background-color: #FCC; }
+.green { background-color: #CFC; }
+.blue { background-color: #CCF; }
+.yellow { background-color: #FFF29F; }
+.orange { background-color: #FFD59B; }
+.solid { border: 2px solid #000; padding: 2px; clear: both; }
+.dashed { border: 2px dashed #AEBDCC; padding: 2px; clear: both; }
+.dotted { border: 2px dotted #AEBDCC; padding: 2px; clear: both; }
+.left { text-align: left; }
+.center { text-align: center; }
+.right { text-align: right; }
+.justify { text-align: justify; }
+
Binary file MoinMoin/themes/foobar/static/img/admonitions/caution.png has changed
Binary file MoinMoin/themes/foobar/static/img/admonitions/important.png has changed
Binary file MoinMoin/themes/foobar/static/img/admonitions/note.png has changed
Binary file MoinMoin/themes/foobar/static/img/admonitions/tip.png has changed
Binary file MoinMoin/themes/foobar/static/img/admonitions/warning.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/alert.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/angry.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/attention.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/biggrin.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/checkmark.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/devil.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/frown.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/icon-error.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/icon-info.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/idea.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/ohwell.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/prio1.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/prio2.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/prio3.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/redface.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/sad.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/smile.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/smile2.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/smile3.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/smile4.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/star_off.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/star_on.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/thumbs-up.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/tired.png has changed
Binary file MoinMoin/themes/foobar/static/img/smileys/tongue.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/delete.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,18 @@
+{% import "forms.html" as forms %}
+{% extends theme("local.html") %}
+{% block content %}
+<h1>{{ _("Delete '%(item_name)s'", item_name=item.name) }}</h1>
+<div class="moin-form">
+{{ gen.form.open(form, method="post", action=url_for('frontend.delete_item', item_name=item.name)) }}
+  {{ forms.render_errors(form) }}
+  <dl>
+    {{ forms.render_field(gen, form['comment'], 'text') }}
+    {{ forms.render_textcha(gen, form) }}
+  </dl>
+  {{ gen.input(form['submit'], type='submit') }}
+{{ gen.form.close() }}
+</div>
+{% endblock %}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/destroy.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,34 @@
+{% import "forms.html" as forms %}
+{% extends theme("local.html") %}
+{% block content %}
+{% if rev_id == None %}
+    <h1>{{ _("DESTROY COMPLETE item '%(item_name)s'", item_name=item.name) }}</h1>
+    <div class="moin-form">
+    {{ gen.form.open(form, method="post", action=url_for('frontend.destroy_item', item_name=item.name)) }}
+      {{ forms.render_errors(form) }}
+      <dl>
+        {{ forms.render_field(gen, form['comment'], 'text') }}
+        {{ forms.render_textcha(gen, form) }}
+      </dl>
+      {{ gen.input(form['submit'], type='submit') }}
+    {{ gen.form.close() }}
+    </div>
+{% else %}
+    <h1>{{ _("DESTROY REVISION '%(item_name)s' (rev %(rev_id)s)", item_name=item.name, rev_id=rev_id) }}</h1>
+    <div class="moin-form">
+    {{ gen.form.open(form, method="post", action=url_for('frontend.destroy_item', item_name=item.name, rev=rev_id)) }}
+      {{ forms.render_errors(form) }}
+      <dl>
+        {{ forms.render_field(gen, form['comment'], 'text') }}
+        {{ forms.render_textcha(gen, form) }}
+      </dl>
+      {{ gen.input(form['submit'], type='submit') }}
+    {{ gen.form.close() }}
+    </div>
+{% endif %}
+{% endblock %}
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/global.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,11 @@
+{% extends theme("layout.html") %}
+{% import "utils.html" as utils %}
+
+{% block content_container %}
+<div id="moin-content-no-panel" lang="{{ theme_supp.content_lang }}" dir="{{ theme_supp.content_dir }}">
+    {% block content %}
+        {# All content templates should have implement this block. #}
+    {% endblock %}
+</div>
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/global_history.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,55 @@
+{% extends theme("global.html") %}
+{% import "utils.html" as utils %}
+
+{% block head %}
+{{ super() }}
+<link rel="alternate" title="Global History" href="{{ url_for('feed.atom') }}" type="application/atom+xml" />
+{% endblock %}
+
+{% block content %}
+<h1>{{ _("Global History") }}</h1>
+<div class='moin-clr'></div>
+    <div id="moin-global-history">
+        {% for day, revs in history %}
+           {% set latest_timestamp = revs[0].meta['mtime'] %}
+            <div class="moin-history-container"> 
+                <div class="moin-history-container-header">
+                    <h2>{{ day }}</h2>
+                    {% if user.valid %}
+                    <a class="bookmark-link" href="{{ url_for('frontend.bookmark', time=latest_timestamp+1) }}">{{ _("Set bookmark") }}</a>
+                    {% endif %}
+                </div>
+                <div class="moin-history-container-body">
+                    <table class="zebra">
+                    {% for rev in revs %}
+                        {% set meta = rev.meta %}
+                        <tr>
+                            <td class="moin-action">
+                                <span class="moin-history-{{ meta.action|lower }}"></span>
+                            </td>
+                            <td class="moin-history-links">
+                                <a href="{{ url_for('frontend.history', item_name=meta.name, bookmark=bookmark_time) }}">HIST</a>
+                                {% if bookmark_time -%}
+                                    <a href="{{ url_for('frontend.diff', item_name=meta.name, bookmark=bookmark_time) }}">DIFF</a>
+                                {%- endif %}
+                            </td>
+                            <td class="moin-history-time">{{ meta.mtime|timeformat }}</td>
+                            <td class="moin-history-item"><a class="{{ meta.contenttype|contenttype_to_class }}" href="{{ url_for('frontend.show_item', item_name=meta.name) }}" title="{{ meta.contenttype }}">{{ meta.name }}</a></td>
+                        </tr>
+                    {% endfor %}
+                    </table>
+                </div>
+            </div>
+        {% endfor %}
+        {% if bookmark_time %}
+        <div class="moin-history-container"> 
+            <div class="moin-history-container-header">
+                <span>
+                    <h2>{{ bookmark_time|datetimeformat }}</h2>
+                    <a href="{{ url_for('frontend.bookmark', time='del') }}">{{ _("Delete bookmark") }}</a>
+               </span>
+            </div>
+        </div>
+        {% endif %}
+    </div>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/global_tags.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,13 @@
+{% extends theme("global.html") %}
+{% block content %}
+{% if headline %}
+<h1>{{ headline }}</h1>
+{% endif %}
+{% if tags %}
+<ul class="moin-tags">
+    {% for cls, tag in tags %}
+    <li class="{{ cls }}"><a href="{{ url_for('frontend.tagged_items', tag=tag) }}">{{ tag }}</a></li>
+    {% endfor %}
+</ul>
+{% endif %}
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/history.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,74 @@
+{% extends theme("local.html") %}
+{% import "utils.html" as utils %}
+{% block content %}
+    {% set (history, next_offset, previous_offset) = history_page %}
+    {% if history %}
+    <div class='moin-offset-links'>
+        {% if previous_offset >= 0 %}
+            <a href="{{ url_for('frontend.history', item_name=item_name, offset=previous_offset) }}" title="{{ _("Previous") }}">&laquo;</a>
+        {% endif %}
+        {% if next_offset %}
+            <a href="{{ url_for('frontend.history', item_name=item_name, offset=next_offset) }}" title="{{ _("Next") }}">&raquo;</a>
+        {% endif %}
+    </div>
+    <h1>{{ _("History of '%(item_name)s'", item_name=item_name) }}</h1>
+    <div class="moin-clr"></div>
+    <form action="{{ url_for('frontend.diff', item_name=item_name) }}" method="GET">
+        <div id="moin-page-history">
+        <table class="zebra">
+            <thead>
+                <tr>
+                    <th>{{ _("Name") }}</th>
+                    <th>{{ _("Rev.") }}</th>
+                    <th>{{ _("Timestamp") }}</th>
+                    <th>{{ _("Size") }}</th>
+                    <th><input type="submit" value="Diff" /></th>
+                    <th>{{ _("Editor") }}</th>
+                    <th>{{ _("Content-Type") }}</th>
+                    <th>{{ _("Comment") }}</th>
+                    <th colspan="6">{{ _("Actions") }}</th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for doc in history %}
+                <tr>
+                    <td class="moin-wordbreak">{{ doc.name }}</td>
+                    <td class="moin-integer monospaced">{{ doc.revid | shorten_id }}</td>
+                    <td>{{ doc.mtime|datetimeformat }}</td>
+                    <td class="moin-integer">{{ doc.size }}</td>
+                    <td>
+                        <div class="moin-hist-rev">
+                            <input type="radio" name="rev1" value="{{ doc.revid }}" />
+                            <input type="radio" name="rev2" value="{{ doc.revid }}" />
+                        </div>
+                    </td>
+                    <td class="moin-wordbreak">{{ utils.editor_info(doc) }}</td>
+                    <td class="moin-wordbreak">{{ doc.contenttype }}</td>
+                    <td class="moin-wordbreak">{{ doc.comment }}</td>
+                    <td><a href="{{ url_for('frontend.show_item', item_name=doc.name, rev=doc.revid) }}">{{ _('show') }}</a></td>
+                    <td><a href="{{ url_for('frontend.show_item_meta', item_name=doc.name, rev=doc.revid) }}">{{ _('meta') }}</a></td>
+                    <td><a href="{{ url_for('frontend.download_item', item_name=doc.name, rev=doc.revid) }}">{{ _('download') }}</a></td>
+                    <td><a href="{{ url_for('frontend.highlight_item', item_name=doc.name, rev=doc.revid) }}">{{ _('highlight') }}</a></td>
+                    {% if user.may.write(item_name) -%}
+                    <td><a href="{{ url_for('frontend.revert_item', item_name=doc.name, rev=doc.revid) }}">{{ _('revert') }}</a></td>
+                    {%- endif %}
+                    {% if user.may.destroy(item_name) -%}
+                    <td><a href="{{ url_for('frontend.destroy_item', item_name=doc.name, rev=doc.revid) }}">{{ _('destroy') }}</a></td>
+                    {%- endif %}
+                </tr>
+                {% endfor %}
+            </tbody>
+            {% if bookmark_time %}
+            <tfoot>
+                <tr>
+                    <td colspan="2">Bookmark is set to</td>
+                    <td>{{ bookmark_time|datetimeformat }}</td>
+                    <td colspan="11"></td>
+                </tr>
+            </tfoot>
+            {% endif %}
+        </table>
+        </div>
+        </form>
+    {% endif %}
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/index.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,174 @@
+{% extends theme("global.html") %}
+{% import "forms.html" as forms %}
+{% block head_scripts %}
+{{ super() }}
+    <script src="{{ url_for('serve.files', name='jquery_multi_download', filename='jquery.multiDownload.js') }}"></script>
+    <script src="{{ url_for('static', filename='js/index_action.js') }}"></script>
+{% endblock %}
+
+{% block content %}
+    <div class="moin-index-message"><span></span></div>
+    <div class="moin-align-right">
+        <ul>
+            {% if index %}
+            <li class="action-bar"> 
+            <div class="moin-select-all">
+                <span class="moin-select-allitem allitem-toselect" title="{{ _("Select All") }}">{{ _("Select All") }}</span>
+            </div>
+            </li>
+            {% endif %}
+            <li class="action-bar">
+            <div class="moin-select-actions">
+                <div>
+                    <span class="show-action">Actions</span> 
+                </div>
+                <ul>
+                    <li id="moin-create-newitem">{{ _("New item") }}</li>
+                    <li id="moin-download-trigger">{{ _("Download") }}</li>
+                    <li class="moin-action-tab" 
+                        id="moin-delete-trigger" 
+                        actionurl="{{ url_for('frontend.ajaxdelete', item_name=item_name) }}">
+                        {{ _("Delete") }}
+                    </li>
+                    <li class="moin-action-tab" 
+                        id="moin-destroy-trigger" 
+                        actionurl="{{ url_for('frontend.ajaxdestroy', item_name=item_name) }}">
+                        {{ _("Destroy") }}
+                    </li>
+                </ul>
+            </div>
+            </li>
+            {% if index %}
+            <li class="action-bar">
+            <div class="moin-contenttypes-wrapper">
+                <div class="ct-hide">{{ _("Filter by content type") }}</div>
+                {% set unknown_items_label = _("items having unknown mime types") %}
+                {{ gen.form.open(form, method="post", action=url_for('frontend.index', item_name=item_name)) }}
+                <ul>
+                    <li>
+                        <a href="#" class="filter-toggle">&raquo; {{ _("Toggle") }}</a>
+                        <a href="#" class="filter-more">&raquo; {{ _("More") }}</a>
+                    </li>
+                    {{ forms.render_filter_field(gen, form['markup_text_items'], 'checkbox', contenttype_groups['markup text items']) }}
+                    {{ forms.render_filter_field(gen, form['other_text_items'], 'checkbox', contenttype_groups['other text items']) }}
+                    {{ forms.render_filter_field(gen, form['image_items'], 'checkbox', contenttype_groups['image items']) }}
+                    {{ forms.render_filter_field(gen, form['audio_items'], 'checkbox', contenttype_groups['audio items']) }}
+                    {{ forms.render_filter_field(gen, form['video_items'], 'checkbox', contenttype_groups['video items']) }}
+                    {{ forms.render_filter_field(gen, form['other_items'], 'checkbox', contenttype_groups['other items']) }}
+                    {{ forms.render_filter_field(gen, form['unknown_items'], 'checkbox', unknown_items_label) }}
+                    {{ gen.input(form['submit'], type='submit') }}
+                </ul>
+                {{ gen.form.close() }}
+            </div>
+            </li>
+            {% endif %}
+        </ul>
+    </div>
+    <div>
+    {% if item_name: %}
+        <h1>{{ _("Index of subitems of '%(item_name)s'", item_name=item_name) }}</h1>
+        <div class="moin-index-path">
+            <a href="{{ url_for('frontend.index') }}" title="{{ _("Global Index") }}">{{ ("..") }}</a>
+            <span class="moin-path-separator">{{ ("/") }}</span>
+            {% for i in range(0, item_names|count) %}
+                {% set fullname = item_names[:i+1]|join('/') %}
+                {% set relname = item_names[i] %}
+                <a href="{{ url_for('frontend.index', item_name=fullname) }}" title="{{ relname }}">{{ relname }}</a>
+                <span class="moin-path-separator">{{ ("/") }}</span>
+            {% endfor %}
+        </div>
+    {% else %}
+        <h1>{{ _("Global Index") }}</h1>
+    {% endif %}
+    </div>
+    <div class='moin-clr'></div>
+    <div id="moin-new-index" class="moin-item-index">
+        <h3 style="display: none;">{{ _("Recently uploaded items") }}</h3>
+        <div class="file_download_template" style="display: none;">
+            <a></a>
+        </div>
+    </div>
+    <div class="moin-index-separator"></div>
+    {% if index %}
+    <div id="moin-initials">
+        {% if not startswith %}
+            <a class="selected" href="{{ url_for('frontend.index', item_name=item_name) }}">{{ _("All") }}</a>
+        {% else %}
+            <a href="{{ url_for('frontend.index', item_name=item_name) }}">{{ _("All") }}</a>
+        {% endif %}
+        {% for initial in initials %}
+            {% if startswith == initial %}
+                <a class="selected" href="{{ url_for('frontend.index', item_name=item_name, startswith=initial) }}">{{ initial }}</a>
+            {% else %}
+                <a href="{{ url_for('frontend.index', item_name=item_name, startswith=initial) }}">{{ initial }}</a>
+            {% endif %}
+        {% endfor %}
+    </div>
+    <div class="moin-item-index">
+        {% set maxchars = 20 %}
+        {% for fullname, relname, contenttype, hassubitem in index %}
+            <div>
+                <span class="moin-select-item">&nbsp;</span>
+                {% set mimetype = "application/x.moin.download" %}
+                <a href="about:blank" title="{{ url_for('.download_item', item_name=fullname, mimetype=mimetype) }}"
+                   class="moin-download-link">
+                </a>
+                <a href="{{ url_for('.show_item', item_name=fullname) }}" 
+                   class="{{ contenttype|contenttype_to_class }} moin-item"
+                   title="{{ relname }}">
+                   {{ relname|truncate(maxchars, true, '..') }}
+                </a>
+                {% if hassubitem %}
+                    <a href="{{ url_for('frontend.index', item_name=fullname) }}" 
+                       title="{{ _("More") }}"
+                       class="moin-more-index">&nbsp;
+                </a>
+                {% endif %}
+            </div>
+        {% endfor %}
+    </div>
+    <div class="moin-clr"></div>
+    {% endif %}
+    <div id="popup">
+        <div id="popup-for-action" class="popup-container">
+            <div class="popup-header">
+                <div class="popup-closer popup-cancel" title="{{ _("Close") }}">x</div>
+                <span>{{ _("Please provide comment for this action") }}</span>
+            </div>
+            <div class="popup-body">
+                <input type="text" class="popup-comment" placeholder="{{ _("Enter your comment") }}"/>
+                <input type="hidden" class="popup-action" value=""/>
+                <br/>
+                <input type="button" class="popup-submit" value="{{ _("Submit") }}"/>
+                <input type="button" class="popup-cancel" value="{{ _("Cancel") }}"/>
+            </div>
+        </div>
+        <div id="popup-for-newitem" class="popup-container">
+            <div class="popup-header">
+                <div class="popup-closer popup-cancel" title="{{ _("Close") }}">x</div>
+                <span>{{ _("Create new item") }}</span>
+            </div>
+            <div class="popup-body">
+                <form action={{ url_for('.ajaxmodify') }} method="post">
+                    <label for="newitem">{{ _("Item name") }}</label>
+                    {% if item_name %}
+                        <input type="text" name="newitem" placeholder="{{ _("Enter item name here") }}" value="{{ item_name }}/" required="true"/>
+                    {% else %}
+                        <input type="text" name="newitem" placeholder="{{ _("Enter item name here") }}" required="true"/>
+                    {% endif %}
+                    <br/>
+                    <input type="submit" value="{{ _("Create") }}"/>
+                    <input type="button" class="popup-cancel" value="{{ _("Cancel") }}"/>
+                </form>
+            </div>
+        </div>
+    </div>
+
+    <div id="moin-upload-cont">
+    {% set submit_url = url_for('.jfu_server', item_name=item_name) %}
+    {{ forms.render_file_uploader(submit_url) }}
+    </div>
+    <span class="moin-drag">{{ _("(Drag and drop multiple files to this white area to upload them.)") }}</span>
+    <script src="{{ url_for('static', filename='js/jfu.js') }}"></script>
+    <div id="lightbox">&nbsp;</div>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/item_link_list.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,14 @@
+{% extends theme("local.html") %}
+{% block content %}
+{% if headline %}
+<h1>{{ headline }}</h1>
+{% endif %}
+{% if item_names %}
+Total: {{ item_names|count }}
+<ul>
+    {% for item_name in item_names|sort %}
+    <li><a href="{{ url_for('frontend.show_item', item_name=item_name) }}">{{ item_name }}</a></li>
+    {% endfor %}
+</ul>
+{% endif %}
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/itemviews.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,84 @@
+{% set exists = storage.has_item(item_name) %}
+<ul class="moin-itemviews">
+    {%- for endpoint, label, title, check_exists in cfg.item_views if not endpoint in cfg.endpoints_excluded %}
+        {%- if not check_exists or check_exists and exists %}
+            {%- if endpoint in [
+                'frontend.show_item', 'frontend.index', 'frontend.highlight_item',
+                'frontend.show_item_meta', 'frontend.download_item',
+                'frontend.history', 'frontend.backrefs', 'frontend.sitemap',
+                'frontend.similar_names', 'frontend.copy_item',
+            ] %}
+                <li>
+                    <a href="{{ url_for(endpoint, item_name=item_name) }}" title="{{ title }}" rel="nofollow">{{ label }}</a>
+                </li>
+            {%- endif %}
+
+            {%- if endpoint in [
+                'frontend.modify_item', 'frontend.rename_item', 'frontend.delete_item',
+            ] and user.may.write(item_name) %}
+                <li>
+                    <a href="{{ url_for(endpoint, item_name=item_name) }}" title="{{ title }}" rel="nofollow">{{ label }}</a>
+                </li>
+            {%- endif %}
+
+            {%- if endpoint == 'frontend.destroy_item' and user.may.destroy(item_name) %}
+                <li>
+                    <a href="{{ url_for(endpoint, item_name=item_name) }}" title="{{ title }}" rel="nofollow">{{ label }}</a>
+                </li>
+            {%- endif %}
+
+            {%- if endpoint in [
+                'frontend.global_history', 'frontend.global_index', 'frontend.global_tags',
+                'admin.index',
+            ] %}
+                <li>
+                    <a href="{{ url_for(endpoint) }}" title="{{ title }}" rel="nofollow">{{ label }}</a>
+                </li>
+            {%- endif %}
+
+            {%- if endpoint == 'frontend.quicklink_item' and user.valid %}
+                <li>
+                    <a href="{{ url_for(endpoint, item_name=item_name) }}" title="{{ title }}" rel="nofollow">
+                        {%- if user.is_quicklinked_to([item_name]) %}
+                            {{ _('Remove Link') }}
+                        {%- else %}
+                            {{ _('Add Link') }}
+                        {%- endif %}
+                    </a>
+                </li>
+            {%- endif %}
+
+            {%- if endpoint == 'frontend.subscribe_item' and user.valid %}
+                <li>
+                    <a href="{{ url_for(endpoint, item_name=item_name) }}" title="{{ title }}" rel="nofollow">
+                        {%- if user.is_subscribed_to([item_name]) %}
+                            {{ _('Unsubscribe') }}
+                        {%- else %}
+                            {{ _('Subscribe') }}
+                        {%- endif %}
+                    </a>
+                </li>
+            {%- endif %}
+
+            {%- if endpoint == 'special.comments' %}
+                <li class="toggleCommentsButton" style="display:none;">
+                    <a href="#" onClick="toggleComments();return false;" title="{{ title }}">{{ label }}</a>
+                </li>
+            {%- endif %}
+
+            {%- if endpoint == 'special.supplementation' %}
+                {%- for sub_item_name in cfg.supplementation_item_names %}
+                    {%- set current_sub = item_name.rsplit('/', 1)[-1] %}
+                    {%- if not current_sub in cfg.supplementation_item_names %}
+                        {%- set supp_name = '%s/%s' % (item_name, sub_item_name) %}
+                        {%- if storage.has_item(supp_name) or user.may.write(supp_name) %}
+                            <li>
+                                <a href="{{ url_for('frontend.show_item', item_name=supp_name) }}" rel="nofollow">{{ _(sub_item_name) }}</a>
+                            </li>
+                        {%- endif %}
+                    {%- endif %}
+                {%- endfor %}
+            {%- endif %}
+        {%- endif %}
+    {%- endfor %}
+</ul>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/layout.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,170 @@
+{% import "forms.html" as forms %}
+{% extends theme("base.html") %}
+
+{% import theme("snippets.html") as snippets with context %}
+{% set logo = snippets.logo() %}
+{% set footer_logos = snippets.creditlogos() %}
+{% set footer_items = '' %}
+{% set credits = snippets.credits() %}
+
+
+{% block layout %}
+
+<div id="moin-global-tray">
+
+{% if logo %}
+<div id="moin-logo">
+    <a style="background-image: url({{ '/static/logos/moinmoin.png' }});" href="{{ url_for('frontend.show_item', item_name=cfg.item_root) }}"></a>
+</div>
+{% endif %}
+
+<div id="moin-global-panel">
+    <ul>
+        {% set navibar_items = theme_supp.navibar(item_name) %}
+        {% if navibar_items %}
+            <li>Links
+            <ul>
+            {% for cls, url, text, title in navibar_items %}
+                <li class="{{ cls }}">
+                    <a href="{{ url }}" {% if title %}title="{{ title }}"{% endif %}>{{ text }}</a>
+                </li>
+            {% endfor %}
+            </ul>
+            </li>
+        {% endif %}
+
+        {% set trail_items = theme_supp.path_breadcrumbs() %}
+        {% if trail_items %}
+        <li>Trail
+            <ul>
+            {% for wiki_name, item_name, item_href, exists, err in trail_items %}
+                <li>
+                {%- if wiki_name -%}
+                    <a href="{{ item_href }}"{{ " " }}
+                       title="{{ wiki_name }}"
+                       class="{% if err %}moin-badinterwiki{% else %}moin-interwiki{% endif %}">
+                       {{ item_name|shorten_item_name }}
+                    </a>
+                {%- else -%}
+                    <a href="{{ url_for('frontend.show_item', item_name=item_name) }}"{{ " " }}
+                       {% if not exists -%}class="moin-nonexistent"{%- endif -%}>
+                       {{ item_name|shorten_item_name }}
+                    </a>
+                {%- endif %}
+                </li>
+            {% endfor %}
+            </ul>
+        </li>
+        {% endif %}
+        <li>User
+        <ul>
+        {% if user.valid -%}
+	    {% set avatar = user.avatar(20) %}
+            {% if avatar %}
+                <li><img id="moin-avatar" rel="noreferrer" src="{{ avatar }}" /></li>
+            {%- endif %}
+            {% if user.name -%}
+                {% set wiki_href, aliasname, title, exists = theme_supp.userhome() %}
+                <li>
+                <a href="{{ wiki_href }}" {% if not exists %}class="moin-nonexistent"{% endif %} rel="nofollow" title="{{ title }}">
+                    {{ aliasname }}
+                </a>
+                </li>
+                {% if 'frontend.usersettings' not in cfg.endpoints_excluded -%}
+                    <li>
+                    <a href="{{ url_for('frontend.usersettings') }}" class="moin-usersettings" rel="nofollow">{{ _('Settings') }}</a>
+                    </li>
+                {%- endif %}
+            {%- endif %}
+            {% if user.auth_method in cfg.auth_can_logout %}
+                <li>
+                <a href="{{ url_for('frontend.logout', logout_submit=1) }}" class="moin-logout" rel="nofollow">
+                    {{ _('Logout') }}
+                </a>
+                </li>
+            {% endif %}
+        {% else %}
+            {% set login_url = theme_supp.login_url() %}
+            {% if login_url %}
+                <li>
+                <a href="{{ login_url }}" class="moin-login" rel="nofollow">{{ _('Login') }}</a>
+                </li>
+            {% endif %}
+        {%- endif %}
+        </ul>
+    </ul>
+</div>
+</div>
+
+<div id="moin-main-container">
+<div id="moin-main-box">
+<div id="moin-header">
+    {% if search_form %} 
+    <div id="moin-search">
+    {{ gen.form.open(search_form, id='moin-searchform', method='get', action=url_for('frontend.search')) }}
+        {{ gen.input(search_form['q'], type='search', id='moin-search-query', size='40') }}
+        {{ gen.button(search_form['submit'], type='submit', id='moin-search-submit') }}
+        {{ forms.render_errors(search_form) }}
+    {{ gen.form.close() }}
+    </div>
+    {% endif %} 
+    <div id="moin-breadcrumbs-location">
+        {% if cfg.show_interwiki -%}
+        <span id="moin-interwiki">
+            <a href="{{ url_for('frontend.show_item', item_name=cfg.item_root) }}" rel="nofollow">
+                {% if cfg.interwikiname %}{{ cfg.interwikiname }}{% else %}Self{% endif %}
+            </a>
+            <span class="sep">: </span>
+        </span>
+        {%- endif %}
+        <span id="moin-pagelocation">
+            <span class="moin-pagepath">
+                {% for segment_name, segment_path, exists in theme_supp.location_breadcrumbs(item_name) -%}
+                    {% if not loop.last -%}
+                        <a href="{{ url_for('frontend.show_item', item_name=segment_path) }}" {% if not exists %}class="moin-nonexistent"{% endif %}>
+                            {{ segment_name|shorten_item_name }}
+                        </a>
+			<span class="sep">/</span>
+                    {% else %}
+		        {% if title_name %}
+                            {{ title_name }}
+                        {% else %}
+                        <a href="{{ url_for('frontend.show_item', item_name=segment_path) }}" {% if not exists %}class="moin-nonexistent"{% endif %}>
+                            {{ segment_name|shorten_item_name }}
+                        </a>
+		        {%- endif %}
+                    {%- endif %}
+                {%- endfor %}
+            </span>
+        </span>
+    </div>
+</div>
+
+<div id="moin-flash">
+{% for category, msg in get_flashed_messages(with_categories=true) %}
+    <p class="moin-flash moin-flash-{{ category }}">{{ msg }}</p>
+{% endfor %}
+</div>
+
+{% block content_container %}
+{% endblock %}
+</div>
+
+
+<div id="moin-footer">
+    {% block footer %}
+    <div id="moin-footer-logos">
+        {{ footer_logos }}
+    </div>
+    <div id="moin-footer-items">
+        {{ footer_items }}
+    </div>
+    <div id="moin-credits">
+        {{ credits }}
+    </div>
+{% endblock %}
+</div>
+</div>
+
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/local.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,127 @@
+{% extends theme("layout.html") %}
+{% import "utils.html" as utils %}
+
+{% block content_container %}
+<div id="moin-content-with-panel" lang="{{ theme_supp.content_lang }}" dir="{{ theme_supp.content_dir }}">
+    {% block item -%}
+        {# If you want itemviews in your template, extend from show.html, not from here. #}
+        {% block content %}
+            {# All content templates should have implement this block. #}
+        {% endblock %}
+    {%- endblock %}
+</div>
+
+<div id="moin-local-panel">
+<ul>
+    <li>Views
+        {% set exists = storage.has_item(item_name) %}
+        <ul class="moin-itemviews">
+            {%- for endpoint, label, title, check_exists in cfg.item_views if not endpoint in cfg.endpoints_excluded %}
+                {%- if not check_exists or check_exists and exists %}
+                    {%- if endpoint in [
+                        'frontend.show_item', 'frontend.index', 'frontend.highlight_item',
+                        'frontend.show_item_meta', 'frontend.download_item',
+                        'frontend.history', 'frontend.backrefs', 'frontend.sitemap',
+                        'frontend.similar_names', 'frontend.copy_item',
+                    ] %}
+                        <li>
+                            <a href="{{ url_for(endpoint, item_name=item_name) }}" title="{{ title }}" rel="nofollow">{{ label }}</a>
+                        </li>
+                    {%- endif %}
+
+                    {%- if endpoint in [
+                        'frontend.modify_item', 'frontend.rename_item', 'frontend.delete_item',
+                    ] and user.may.write(item_name) %}
+                        <li>
+                            <a href="{{ url_for(endpoint, item_name=item_name) }}" title="{{ title }}" rel="nofollow">{{ label }}</a>
+                        </li>
+                    {%- endif %}
+
+                    {%- if endpoint == 'frontend.destroy_item' and user.may.destroy(item_name) %}
+                        <li>
+                            <a href="{{ url_for(endpoint, item_name=item_name) }}" title="{{ title }}" rel="nofollow">{{ label }}</a>
+                        </li>
+                    {%- endif %}
+
+                    {%- if endpoint in [
+                        'frontend.global_history', 'frontend.global_index', 'frontend.global_tags',
+                        'admin.index',
+                    ] %}
+                        <li>
+                            <a href="{{ url_for(endpoint) }}" title="{{ title }}" rel="nofollow">{{ label }}</a>
+                        </li>
+                    {%- endif %}
+
+                    {%- if endpoint == 'frontend.quicklink_item' and user.valid %}
+                        <li>
+                            <a href="{{ url_for(endpoint, item_name=item_name) }}" title="{{ title }}" rel="nofollow">
+                                {%- if user.is_quicklinked_to([item_name]) %}
+                                    {{ _('Remove Link') }}
+                                {%- else %}
+                                    {{ _('Add Link') }}
+                                {%- endif %}
+                            </a>
+                        </li>
+                    {%- endif %}
+
+                    {%- if endpoint == 'frontend.subscribe_item' and user.valid %}
+                        <li>
+                            <a href="{{ url_for(endpoint, item_name=item_name) }}" title="{{ title }}" rel="nofollow">
+                                {%- if user.is_subscribed_to([item_name]) %}
+                                    {{ _('Unsubscribe') }}
+                                {%- else %}
+                                    {{ _('Subscribe') }}
+                                {%- endif %}
+                            </a>
+                        </li>
+                    {%- endif %}
+
+                    {%- if endpoint == 'special.comments' %}
+                        <li class="toggleCommentsButton" style="display:none;">
+                            <a href="#" onClick="toggleComments();return false;" title="{{ title }}">{{ label }}</a>
+                        </li>
+                    {%- endif %}
+
+                    {%- if endpoint == 'special.supplementation' %}
+                        {%- for sub_item_name in cfg.supplementation_item_names %}
+                            {%- set current_sub = item_name.rsplit('/', 1)[-1] %}
+                            {%- if not current_sub in cfg.supplementation_item_names %}
+                                {%- set supp_name = '%s/%s' % (item_name, sub_item_name) %}
+                                {%- if storage.has_item(supp_name) or user.may.write(supp_name) %}
+                                    <li>
+                                        <a href="{{ url_for('frontend.show_item', item_name=supp_name) }}" rel="nofollow">{{ _(sub_item_name) }}</a>
+                                    </li>
+                                {%- endif %}
+                            {%- endif %}
+                        {%- endfor %}
+                    {%- endif %}
+                {%- endif %}
+            {%- endfor %}
+        </ul>
+    </li>
+    {% if rev %}
+    <li>Metadata
+        <ul>
+            <li>{{ _("Revision:") }} {{rev.revid | shorten_id}}</li>
+            <li>({{ rev.meta['mtime']|datetimeformat }})</li>
+            <li>{{ _("By:") }} {{ utils.editor_info(rev.meta) }}</li>
+            <li>{{ _("Size:") }} {{ rev.meta['size'] }}</li>
+            <li>{{ _("Type:") }} {{ rev.meta['contenttype'] }}</li>
+            {% if rev.meta.tags %}
+            <li>
+            {{ _("Tags:") }}
+            {% for tag in rev.meta.tags -%}
+            <a href="{{ url_for('frontend.tagged_items', tag=tag) }}">{{ tag }}</a>{% if not loop.last %}, {% endif %}
+            {%- endfor -%}
+            </li>
+            {% endif %}
+        </ul>
+    </li>
+    {% endif %}
+    <li>
+        {{ utils.render_subitem_navigation(item_name, False) }}
+    </li>
+</ul>
+</div>
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/login.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,42 @@
+{% extends theme("global.html") %}
+{% import "forms.html" as forms %}
+
+{% block content %}
+<div class="moin-form">
+{{ forms.render_errors(form) }}
+
+{% if 'username' in login_inputs or 'password' in login_inputs %}
+<h2>{{ _('Moin login') }}</h2>
+{{ gen.form.open(form, method="post", action=url_for('frontend.login')) }}
+<dl>
+  {{ gen.input(form['submit'], type='hidden') }}
+
+  {% if 'username' in login_inputs %}
+  {{ forms.render_field(gen, form['username'], 'text') }}
+  {% endif %}
+  {% if 'password' in login_inputs %}
+  {{ forms.render_field(gen, form['password'], 'password') }}
+  {% endif %}
+
+  <input type="submit" value="{{ _('Log in') }}" />
+</dl>
+{{ gen.form.close() }}
+{% endif %}
+
+{% if 'openid' in login_inputs %}
+<br>
+<h2>{{ _('OpenID login') }}</h2>
+
+{{ gen.form.open(form, method="post", action=url_for('frontend.login')) }}
+<dl>
+  {{ gen.input(form['submit'], type='hidden') }}
+
+  {{ forms.render_field(gen, form['openid'], 'text') }}
+  <input type="submit" value="{{ _('Log in') }}" />
+</dl>
+{{ gen.form.close() }}
+{% endif %}
+
+</div>
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/lostpass.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,18 @@
+{% extends theme("global.html") %}
+{% import "forms.html" as forms %}
+
+{% block content %}
+<h1>{{ _("Lost Password") }}</h1>
+<div class="moin-form">
+{{ _("Please note that you only need to fill out one form field.") }}
+{{ gen.form.open(form, method="post", action=url_for('frontend.lostpass')) }}
+  {{ forms.render_errors(form) }}
+  <dl>
+    {{ forms.render_field(gen, form['username'], 'text') }}
+    {{ forms.render_field(gen, form['email'], 'text') }}
+  </dl>
+  {{ gen.input(form['submit'], type='submit') }}
+{{ gen.form.close() }}
+</div>
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/meta.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,10 @@
+{% extends theme("local.html") %}
+{% block content %}
+<h1>{{ _("Metadata of '%(item_name)s'", item_name=item.name) }}</h1>
+{% if meta_rendered %}
+<div id="moin-content-meta">
+    {{ meta_rendered }}
+</div>
+{% endif %}
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/modify_applet.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,17 @@
+{% import "forms.html" as forms %}
+{% extends theme("local.html") %}
+{% block content %}
+<h1>{{ _("Modifying %(item_name)s", item_name=item_name) }}</h1>
+<div class="moin-form">
+{{ gen.form.open(form, method='post', action='', enctype='multipart/form-data') }}
+{{ forms.render_errors(form) }}
+{% block extra_form %}{% endblock %}
+{% block data_editor %}{% endblock %}
+{{ forms.render_field(gen, form['data_file'], 'file') }}
+<pre>{{ help }}</pre>
+{{ 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 %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/modify_binary.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,7 @@
+{% import "forms.html" as forms %}
+{% extends theme("modify_applet.html") %}
+{% block extra_form %}
+{{ gen.input(form['submit'], class='button', type='submit') }}
+{{ forms.render_textcha(gen, form) }}
+{{ forms.render_field(gen, form['comment'], 'text') }}
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/modify_show_template_selection.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,16 @@
+{% extends theme("local.html") %}
+{% block content %}
+<h1>{{ _("Create new item?") }}</h1>
+<p>
+{{ _("You can either <a href='%(modifyhref)s'>create the item from scratch</a> or select a template.",
+modifyhref=url_for('frontend.modify_item', item_name=item_name, contenttype=contenttype, template='') ) }}
+</p>
+<h2>{{ _("Available template items") }}</h2>
+<ul>
+    {% for template in templates %}
+    <li>
+    <a href="{{ url_for('frontend.modify_item', item_name=item_name, contenttype=contenttype, template=template) }}">{{ template }}</a>
+    </li>
+    {% endfor %}
+</ul>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/modify_show_type_selection.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,21 @@
+{% extends theme("local.html") %}
+{% block content %}
+<h1>{{ _("Create new item?") }}</h1>
+<p>
+{{ _("This item does not exist (yet), but you can try creating it now. Please select the type of the item you want to create.") }}
+</p>
+<table class="zebra">
+    {% for gname, contenttypes in contenttype_groups %}
+    <tr>
+        <th>{{ gname }}</th>
+    </tr>
+    <tr>
+        <td>
+        {% for ctname, ctlabel in contenttypes %}
+            <a href="{{ url_for('frontend.modify_item', item_name=item_name, contenttype=ctname) }}">{{ ctlabel }}</a> -
+        {% endfor %}
+        </td>
+    </tr>
+    {% endfor %}
+</table>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/modify_text.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,19 @@
+{% extends theme("modify_binary.html") %}
+{% import "utils.html" as utils %}
+
+{% block subitem_navigation %}
+        {% call(fullname, shortname, contenttype, has_children) utils.render_subitem_navigation(item_name, True) %}
+            {% set shortname = shortname|json_dumps %}
+            {% set fullname = fullname|json_dumps %}
+            <button class="link-action" onclick='linkSubitem({{ shortname }}, {{ fullname }})'
+                title="{{ _('Link to Subitem') }}">{{ _('Link') }}</button>
+            <button class="transclude-action" 
+                onclick='transcludeSubitem({{ shortname }}, {{ fullname }})'
+                title="{{ _('Transclude Subitem') }}">{{ _('Transclude') }}</button>
+        {% endcall %}
+{% endblock %}
+
+{% block data_editor %}
+{{ gen.textarea(form['data_text'], lang=lang, dir=direction, rows=rows_data, cols=cols) }}
+<br />
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/modify_text_html.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,13 @@
+{% extends theme("modify_binary.html") %}
+
+{% block head %}
+{{ super() }}
+<script type="text/javascript" src="{{ url_for('serve.files', name='ckeditor', filename='ckeditor.js') }}"></script>
+<link rel="stylesheet" href="{{ url_for('serve.files', name='ckeditor', filename='contents.css') }}" />
+{% endblock %}
+
+{% block data_editor %}
+<p>
+{{ gen.textarea(form['data_text'], class='ckeditor', lang=lang, dir=direction, rows=rows_data, cols=cols) }}
+</p>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/recoverpass.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,17 @@
+{% extends theme("global.html") %}
+{% import "forms.html" as forms %}
+
+{% block content %}
+<h1>{{ _("Recover Password") }}</h1>
+{{ gen.form.open(form, method="post", action=url_for('frontend.recoverpass')) }}
+  {{ forms.render_errors(form) }}
+  <dl>
+    {{ forms.render_field(gen, form['username'], 'text') }}
+    {{ forms.render_field(gen, form['token'], 'text') }}
+    {{ forms.render_field(gen, form['password1'], 'password') }}
+    {{ forms.render_field(gen, form['password2'], 'password') }}
+  </dl>
+  {{ gen.input(form['submit'], type='submit') }}
+{{ gen.form.close() }}
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/register.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,21 @@
+{% extends theme("global.html") %}
+{% import "forms.html" as forms %}
+
+{% block content %}
+<h1>{{ _("Create Account") }}</h1>
+<div class="moin-form">
+{{ gen.form.open(form, method="post", action=url_for('frontend.register')) }}
+  {{ forms.render_errors(form) }}
+  <dl>
+    {{ forms.render_field(gen, form['username'], 'text') }}
+    {{ forms.render_field(gen, form['password1'], 'password') }}
+    {{ forms.render_field(gen, form['password2'], 'password') }}
+    {{ forms.render_field(gen, form['email'], 'email') }}
+    {{ forms.render_field(gen, form['openid'], 'url') }}
+    {{ forms.render_textcha(gen, form) }}
+  </dl>
+  {{ gen.input(form['submit'], type='submit') }}
+{{ gen.form.close() }}
+</div>
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/rename.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,16 @@
+{% import "forms.html" as forms %}
+{% extends theme("local.html") %}
+{% block content %}
+<h1>{{ _("Rename '%(item_name)s'", item_name=item.name) }}</h1>
+<div class="moin-form">
+{{ gen.form.open(form, method="post", action=url_for('frontend.rename_item', item_name=item.name)) }}
+  {{ forms.render_errors(form) }}
+  <dl>
+    {{ forms.render_field(gen, form['target'], 'text') }}
+    {{ forms.render_field(gen, form['comment'], 'text') }}
+    {{ forms.render_textcha(gen, form) }}
+  </dl>
+  {{ gen.input(form['submit'], type='submit') }}
+{{ gen.form.close() }}
+</div>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/show.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,21 @@
+{% extends theme("local.html") %}
+
+{% block head_links %}
+    {{ super() }}
+    <link rel="alternate" title="{{ item_name }} changes" href="{{ url_for('feed.atom', item_name=item_name) }}" type="application/atom+xml" />
+    {# universal edit button support #}
+    {%- if user.may.write(item_name) and 'frontend.modify_item' not in cfg.endpoints_excluded -%}
+    <link rel="alternate" type="application/wiki" title="{{ _('Modify') }}" href="{{ url_for('frontend.modify_item', item_name=item_name) }}" />
+    {%- endif %}
+{% endblock %}
+
+{% block content %}
+    {% block content_data %}
+    {% if data_rendered %}
+    <div id="moin-content-data">
+        {{ data_rendered }}
+    </div>
+    {% endif %}
+    {% endblock %}
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/sitemap.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,16 @@
+{% extends theme("local.html") %}
+{% block content %}
+<h1>{{ _("SiteMap of %(item_name)s", item_name=item_name) }}</h1>
+{% for entry in sitemap recursive %}
+    {% if isinstance(entry, list) %}
+        <ul>
+            {{ loop(entry) }}
+        </ul>
+    {% else %}
+        <li>
+        <a href="{{ url_for('frontend.sitemap', item_name=entry) }}">{{ entry }}</a>
+        </li>
+    {% endif %}
+{% endfor %}
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/themes/foobar/templates/snippets.html	Tue Mar 27 23:48:23 2012 +0200
@@ -0,0 +1,53 @@
+{# Use the template_dirs configuration option to override this template #}
+
+{# Logo in the header #}
+{% macro logo() -%}
+<img src="{{ url_for('static', filename='logos/moinmoin.png') }}" id="moin-img-logo" alt="Logo">
+{%- endmacro %}
+
+{# Additional HTML tags inside <head> #}
+{% macro head() -%}
+{%- endmacro %}
+
+{# Helper macro to create image links #}
+{% macro creditlogo(link, logo, alt, title) %}
+<a href="{{ link }}" title="{{ title }}"><img src="{{ logo }}" alt="{{ alt }}" /></a>
+{% endmacro %}
+
+{# Image links in the footer #}
+{% macro creditlogos(start='<ul><li>'|safe, end='</li></ul>'|safe, sep='</li><li>'|safe) %}
+{{ start }}
+{{ creditlogo('http://moinmo.in/', url_for('static', filename='logos/moinmoin_powered.png'),
+   'MoinMoin powered', 'This site uses the MoinMoin Wiki software.') }}
+{{ sep }}
+{{ creditlogo('http://moinmo.in/Python', url_for('static', filename='logos/python_powered.png'),
+   'Python powered', 'MoinMoin is written in Python.') }}
+{{ end }}
+{% endmacro %}
+
+{# Helper macro to generate text links #}
+{% macro credit(link, text, title) -%}
+<a href="{{ link }}" title="{{ title }}">{{ text }}</a>
+{%- endmacro %}
+
+{# Text links in the footer #}
+{% macro credits(start='<p id="moin-credits">'|safe, end='</p>'|safe, sep='<span>&bull;</span>'|safe) %}
+{{ start }}
+{{ credit('http://moinmo.in/', 'MoinMoin Powered', 'This site uses the MoinMoin Wiki software.') }}
+{{ sep }}
+{{ credit('http://moinmo.in/Python', 'Python Powered', 'MoinMoin is written in Python.') }}
+{{ sep }}
+{{ credit('http://moinmo.in/GPL', 'GPL licensed', 'MoinMoin is GPL licensed.') }}
+{{ sep }}
+{{ credit('http://validator.w3.org/check?uri=referer', 'Valid HTML 5', 'Click here to validate this page.') }}
+{{ end }}
+{% endmacro %}
+
+{# Additional Stylesheets (after theme css, before user css #}
+{% macro stylesheets() -%}
+{%- endmacro %}
+
+{# Additional Javascript #}
+{% macro scripts() -%}
+{%- endmacro %}
+
--- a/MoinMoin/themes/modernized/static/css/common.css	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/themes/modernized/static/css/common.css	Tue Mar 27 23:48:23 2012 +0200
@@ -646,16 +646,25 @@
 #moin-creditlogos { float: right; list-style: none; margin: 0 10px; }
 #moin-creditlogos li { display: inline-block; margin: 10px 0 10px 10px; }
 
-/* transclusion overlay */
-.page-object { margin: 0px; width: auto; height: auto; display: block; position: relative; }
-.object-overlay { background-color: black; position: absolute; padding: 5px; border-radius: 1em;
-            text-align: center; white-space: nowrap; font-size: 120%;
-            font-weight: bold; display: none; margin: 0; opacity: .5; }
-.object-overlay-wrapper { width: 20px; height: 20px; position: absolute; z-index: 100; top: 0px; left: 0px; margin: 0; }
-.object-overlay-wrapper:hover  .object-overlay { display: block; top: -20px; left: 0px; }
-.page-object:hover .object-overlay:hover { opacity: .8; filter: alpha(opacity=90); }
-.object-overlay a:link,
-.object-overlay a:visited { color: white; }
+/* Transcluded items are wrapped in a div or span and have two overlay siblings that link to the item page. */
+/* When a Transclusions button is clicked, a Javascript function will show/hide the corners of the overlay siblings. */
+.moin-item-wrapper { position: relative; display: inline-block; }
+.moin-item-wrapper > a:hover { color: blue; text-decoration: none; }
+a.moin-item-overlay-ul,
+a.moin-item-overlay-lr { display: none; position: absolute; color: transparent; background-color: transparent;
+            font-size: 120%; font-weight: bold; margin: 0; opacity: .5; filter: alpha(opacity=50);
+            padding: 1px; border-color: blue; border-style: double; }
+.moin-item-overlay-ul { top: -4px; left: -4px; border-width: 3px 0 0 3px; }
+.moin-item-overlay-lr { bottom: -4px; right: -4px;  border-width: 0 3px 3px 0; }
+/* On overlay mouseover (if Transclusions toggle state is "show"), the arrow and background are revealed. */
+.moin-item-overlay-ul:hover,
+.moin-item-overlay-lr:hover { opacity: .8; filter: alpha(opacity=80); background-color: #C4D9FF; color: blue; }
+/* Prevent double spacing in nested transclusions that consist of paragraphs of text */
+ div.moin-item-wrapper,
+ div.moin-item-wrapper > div,
+ div.moin-item-wrapper > div > p:first-child,
+ div.moin-item-wrapper > div > p:last-child { margin: 0px; }
+ div.moin-item-wrapper > div >  p:first-child ~ p:last-child { margin-top: 1em; }
 
 /* special style for heading with mouseover permalinks */
 .permalink { display: none; cursor: pointer; font-size: 80%; margin-left: 3px; }
--- a/MoinMoin/util/paramparser.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/MoinMoin/util/paramparser.py	Tue Mar 27 23:48:23 2012 +0200
@@ -564,7 +564,7 @@
     int, long, float or unicode object, then the given value
     is converted to the type of that default value before passing
     it to the macro function. That way, macros need not call the
-    wikiutil.get_* functions for any arguments that have a default.
+    get_* functions for any arguments that have a default.
 
     :param function: the function to invoke
     :param args: unicode string with arguments (or evaluating to False)
--- a/README.txt	Tue Mar 20 20:59:55 2012 -0300
+++ b/README.txt	Tue Mar 27 23:48:23 2012 +0200
@@ -11,6 +11,14 @@
 Documentation and Support
 =========================
 
+NOTE: moin2 is not released yet, so much information you find on the wiki
+(and elsewhere) will be about moin 1.x (and NOT applicable to moin2).
+
+There is one wiki page collecting all moin2 specific links and infos:
+
+http://moinmo.in/MoinMoin2.0 < READ THIS!
+
+
 Project homepage is at http://moinmo.in/ - there are also links to support
 resources and informations about MoinMoin development status and plans.
 
--- a/docs/admin/configure.rst	Tue Mar 20 20:59:55 2012 -0300
+++ b/docs/admin/configure.rst	Tue Mar 27 23:48:23 2012 +0200
@@ -1131,6 +1131,8 @@
 Features:
 
 * stores data into an (SQL) database / table
+* can either use 1 database per store or 1 table per store (you need to
+  give different table names then)
 * uses slqalchemy (without the ORM) for database abstraction
 * supports multiple types of databases. For example:
  
@@ -1141,15 +1143,45 @@
 
 `uri` for `create_simple_mapping` looks like e.g.::
 
-    stores:sqla:sqlite:////srv/mywiki/data/mywiki_%(nsname)s.db
-    stores:sqla:mysql://myuser:mypassword@localhost/mywiki_%(nsname)s
-    stores:sqla:postgres://myuser:mypassword@localhost/mywiki_%(nsname)s
+    stores:sqla:sqlite:////srv/mywiki/data/mywiki_%(nsname)s_%(kind).db
+    stores:sqla:sqlite:////srv/mywiki/data/mywiki_%(nsname)s.db::%(kind)s
+    stores:sqla:mysql://myuser:mypassword@localhost/mywiki_%(nsname)s::%(kind)s
+    stores:sqla:postgres://myuser:mypassword@localhost/mywiki_%(nsname)s::%(kind)s
 
-Please see the sqlalchemy docs about the part after `sqla:`.
+The uri part after "sqla:" is like::
+
+    DBURI::TABLENAME
+
+Please see the sqlalchemy docs about the DBURI part.
 
 Grant 'myuser' (his password: 'mypassword') full access to these databases.
 
 
+sqlite store
+------------
+Features:
+
+* directly talks to sqlite, not using sqlalchemy
+* stores data into an sqlite database, which is a single file
+* can either use 1 database per store or 1 table per store (you need to
+  give different table names then)
+* can optionally compress/decompress the data using zlib (default compression
+  level is 0, which means to not compress)
+ 
+`uri` for `create_simple_mapping` looks like e.g.::
+
+    stores:sqlite:/srv/mywiki/data/mywiki_%(nsname)s_%(kind)s.db
+    stores:sqlite:/srv/mywiki/data/mywiki_%(nsname)s.db::%(kind)s
+    stores:sqlite:/srv/mywiki/data/mywiki_%(nsname)s.db::%(kind)s::1
+
+The uri part after "sqlite:" is like::
+
+    PATH::TABLENAME::COMPRESSION
+
+It uses "::" as separator to support windows pathes which may have ":" after
+the drive letter.
+
+
 kc store
 --------
 Features:
--- a/docs/admin/install.rst	Tue Mar 20 20:59:55 2012 -0300
+++ b/docs/admin/install.rst	Tue Mar 27 23:48:23 2012 +0200
@@ -66,23 +66,45 @@
 For example, if you want to use `PyPy` and want to name the virtualenv directory `env-pypy`,
 use::
 
-    # for linux
-    DIR=env-pypy
-    PYTHON=/opt/pypy/bin/pypy
+ # for linux
+ DIR=env-pypy
+ PYTHON=/opt/pypy/bin/pypy
 
 That way, you can test with different versions of Python in different virtualenv directories within your moin2 workdir.
 
 Activating the virtual env
 --------------------------
 
+IMPORTANT: you always need to activate the virtual environment before running
+anything that executes moin code! Otherwise it won't find the moin command,
+nor the moin code nor the libraries it needs. Also, if you want to install
+additional software into the virtual environment, activate it before running pip!::
+
  source env/bin/activate  # for linux (or other posix OSes)
  # or
  env\Scripts\activate.bat  # for windows
 
-IMPORTANT: you always need to activate the virtual environment before running
-anything that executes moin code! Otherwise it won't find the moin command,
-nor the moin code nor the libraries it needs. Also, if you want to install
-additional software into the virtual environment, activate it before running pip!
+As you have activated the virtual env now, the moin command should be in your
+path now, so you can just invoke it using "moin".
+
+Letting moin find the wiki configuration
+----------------------------------------
+
+moin needs to find the wiki configuration. If you want it to run in the most
+simple way (without giving parameters to the moin command), it is easiest if
+you are in the same directory as the configuration files (e.g. wikiconfig.py).
+
+If you are working from a repository workdir, this is just the top level
+directory and there is already a ready-to-use wikiconfig.py.
+
+In case you want to just give the configuration file location, make sure you
+use an **absolute path**. moin will try to find its configuration in this
+order:
+
+- command line argument `--config /path/to/wikiconfig.py`
+- environment variable `MOINCFG=/path/to/wikiconfig.py`
+- current directory, file `wikiconfig_local.py`
+- current directory, file `wikiconfig.py`
 
 Initializing index and/or storage
 ---------------------------------
@@ -137,20 +159,29 @@
 PyPi down
 ~~~~~~~~~
 Now and then, PyPi might be down or unreachable.
+
 There are mirrors b.pypi.python.org, c.pypi.python.org, d.pypi.python.org
-you can use in such cases, you just need to tell pip to do so:
+you can use in such cases, you just need to tell pip to do so::
 
  # put this into ~/.pip/pip.conf
  [global]
  index-url = http://c.pypi.python.org/simple
 
+In case that doesn't work either, try our mini pypi that should have all
+packages you need for moin::
+
+ # put this into ~/.pip/pip.conf
+ [global]
+ index-url = http://pypi.moinmo.in/simple
+
 Bad Network Connection
 ~~~~~~~~~~~~~~~~~~~~~~
 If you have a poor or limited network connection, you may run into trouble with the commands issued by
 the quickinstall script.
 You may see tracebacks from pip, timeout errors, etc. (see the output of the quickinstall script).
 
-If this is the case, try it manually:
+If this is the case, try it manually::
+
  # enter your virtual environment:
  source env/bin/activate
 
--- a/docs/admin/serve.rst	Tue Mar 20 20:59:55 2012 -0300
+++ b/docs/admin/serve.rst	Tue Mar 27 23:48:23 2012 +0200
@@ -19,18 +19,16 @@
 ---------------------------
 Then you can run the moin built-in server by::
 
+ # easiest for debugging (single-process, single-threaded server):
  moin
+
+ # required for some browsers like IE9 or Chrome in incognito mode (try this
+ # in case you encounter a hanging browser / not responding server):
+ moin moin --threaded
+
  # or, if you need another ip/port:
  moin moin --config /path/to/wikiconfig.py --host 1.2.3.4 --port 7777
 
-MoinMoin will start the built-in server and try to locate the wiki configuration
-from one of the following: **NOTE: please use an absolute path**
-
-- command line argument `--config /path/to/wikiconfig.py`
-- environment variable `MOINCFG=/path/to/wikiconfig.py`
-- current directory, file `wikiconfig_local.py`
-- current directory, file `wikiconfig.py`
-
 While the moin server is starting up, you will see some log output, for example::
 
  2011-03-06 23:35:11,445 INFO werkzeug:116  * Running on http://127.0.0.1:8080/
--- a/docs/devel/development.rst	Tue Mar 20 20:59:55 2012 -0300
+++ b/docs/devel/development.rst	Tue Mar 27 23:48:23 2012 +0200
@@ -16,21 +16,34 @@
 
 * http://moinmo.in/
 
+Documentation:
+
+* http://readthedocs.org/docs/moin-20/en/latest/
+
 Issue tracker:
 
 * http://bitbucket.org/thomaswaldmann/moin-2.0/issues
 
-We use Mercurial DVCS (hg) for distributed version control.
-
-Repositories:
+Code Repositories:
 
 * http://hg.moinmo.in/moin/2.0 (main repository)
 * http://bitbucket.org/thomaswaldmann/moin-2.0 (bb mirror for your
   convenience, simplifying forking and contributing)
 
+We use Mercurial DVCS (hg) for distributed version control.
+
 If you are not using Mercurial, you can of course also just send us patches.
 In that case, open an issue in the issue tracker and attach the patch there.
 
+Code review:
+
+Please use http://codereview.appspot.com/ for getting feedback on moin-related
+code (especially if you want to contribute or publish that code).
+
+If you are using a local mercurial repository/workdir you can very easily
+upload your uncommitted workdir state to codereview (using their "upload.py").
+
+Then just ask on the IRC channel for review (give the codereview URL).
 
 MoinMoin architecture
 =====================
--- a/docs/devel/support.rst	Tue Mar 20 20:59:55 2012 -0300
+++ b/docs/devel/support.rst	Tue Mar 27 23:48:23 2012 +0200
@@ -3,20 +3,30 @@
 
 Free Support
 ------------
-.. todo::
-
-   copy stuff from MoinMoin:Support
+You can get free support and informations there:
+* on our chat channels, see http://moinmo.in/MoinMoinChat
+* on our wiki, see http://moinmo.in/ - please note that quite a lot of content
+  there is about moin 1.x and does not apply to moin2. One page has a lot
+  of information about moin2 and also links to all sorts of moin2 resources:
+  http://moinmo.in/MoinMoin2.0
+* on our mailing list, see http://moinmo.in/MoinMoinMailingLists
+* on our issue tracker: https://bitbucket.org/thomaswaldmann/moin-2.0/issues
+* from our repository: https://bitbucket.org/thomaswaldmann/moin-2.0/overview
 
 .. note::
+   All free support is done voluntarily by helpful MoinMoin community members.
+   Thanks to everyone who is helping!
 
    If you enjoyed / want to enjoy free community support, please also consider
-   being an active part of the community and giving support, see below.
+   being an active part of the community and also supporting it.
+
 
 Commercial Support
 ------------------
-.. todo::
+As MoinMoin 2.0 is not released yet, there is no support for production
+systems based on it (we do not recommend that and do not support that).
 
-   copy stuff from MoinMoin:Support
+If you want to talk about development topics, please contact the developers.
 
 
 You Support MoinMoin
@@ -35,7 +45,7 @@
 
 Have an idea?
 -------------
-* Discuss it on IRC and file a feature request on the wiki.
+* Discuss it on IRC and file a feature request (on bitbucket).
 * Even better: discuss + write some Python code implementing it.
 
 Born to code?
@@ -43,13 +53,9 @@
 * Help to work on moin2 core, so it gets finished faster.
 * Help maintaining moin 1.9 until moin2 is ready.
 
-No time, but money?
--------------------
-* If you use moin in your business and you would like some help from a moin
-  developer or administrator, consider buying some commercial support (see
-  above). It'll save you some of your precious time, likely improve your
-  moin experience and help moin administrators and developers to spend more
-  time on moin.
+Loving UI / UX design?
+----------------------
+* Help us making moin2 look and feel better!
 
 Have good language or documentation skills?
 -------------------------------------------
--- a/setup.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/setup.py	Tue Mar 27 23:48:23 2012 +0200
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 # Copyright: 2001 by Juergen Hermann <jh@web.de>
-# Copyright: 2011 MoinMoin:ThomasWaldmann
+# Copyright: 2001-2012 MoinMoin:ThomasWaldmann
 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
 
 import sys, os
@@ -12,7 +12,8 @@
     sys.stderr.write("%s %s requires Python 2.6 or greater.\n" % (project, str(version)))
     sys.exit(1)
 
-long_description = open('README.txt').read()
+with open('README.txt') as f:
+    long_description = f.read()
 
 from setuptools import setup, find_packages
 
@@ -55,6 +56,7 @@
     #package_dir={'MoinMoin.translations': 'MoinMoin/translations',
     #             'MoinMoin.static': 'MoinMoin/static',
     #             'MoinMoin.themes.modernized': 'MoinMoin/themes/modernized',
+    #             'MoinMoin.themes.foobar': 'MoinMoin/themes/foobar',
     #             'MoinMoin.templates': 'MoinMoin/templates',
     #             'MoinMoin.apps.admin.templates': 'MoinMoin/apps/admin/templates',
     #             'MoinMoin.apps.misc.templates': 'MoinMoin/apps/misc/templates',
@@ -63,6 +65,7 @@
     package_data={'MoinMoin.translations': ['MoinMoin.pot', '*.po', ],
                   'MoinMoin.static': ['*', ],
                   'MoinMoin.themes.modernized': ['*', ],
+                  'MoinMoin.themes.foobar': ['*', ],
                   'MoinMoin.templates': ['*.html', '*.xml', ],
                   'MoinMoin.apps.admin.templates': ['*.html', ],
                   'MoinMoin.apps.misc.templates': ['*.html', '*.txt', ],
@@ -70,11 +73,8 @@
     include_package_data=True,
     zip_safe=False,
     dependency_links = [
-        # hack needed as install from pypi fails for Werkzeug==dev due to
-        # wrong dev URL in the long description.
         #'https://github.com/mitsuhiko/werkzeug/tarball/master#egg=Werkzeug-0.7dev',
-        # no whoosh 2.3.1 on pypi yet:
-        'https://bitbucket.org/mchaput/whoosh/get/19c2df0a94ef.tar.gz#egg=Whoosh-2.3.1',
+        #'https://bitbucket.org/mchaput/whoosh/get/19c2df0a94ef.tar.gz#egg=Whoosh-2.3.1',
         # fixed flask-themes, 0.1.3 does not work for flask 0.8.x, thus we use a faked 0.1.3.1:
         'https://bitbucket.org/thomaswaldmann/flask-themes/get/24dcc703953f.tar.gz#egg=Flask-Themes-0.1.3.1',
     ],
@@ -84,7 +84,7 @@
         'Flask>=0.8', # micro framework
         'Flask-Babel>=0.7', # i18n support
         'Flask-Cache>=0.3.4', # caching support
-        'Flask-Script>=0.3.1', # scripting support
+        'Flask-Script>=0.3.3', # scripting support
         'Flask-Themes>=0.1.3.1', # theme support
         'emeraldtree>=0.9.0', # xml processing
         'flatland==dev', # repo checkout at revision 269:6c5d262d7eff works
@@ -92,10 +92,10 @@
         'pygments>=1.4', # src code / text file highlighting
         'Werkzeug>=0.8.1', # wsgi toolkit
         'pytest>=2.1', # pytest is needed by unit tests
-        'whoosh>=2.3.1', # needed for indexed search
+        'whoosh>=2.3.2', # needed for indexed search
         'sphinx>=1.1', # needed to build the docs
         'pdfminer', # pdf -> text/plain conversion
-        'XStatic>=0.0.2',
+        'XStatic>=0.0.2', # support for static file pypi packages
         'XStatic-CKEditor>=3.6.1.2',
         'XStatic-jQuery>=1.6.1.4',
         'XStatic-jQuery-File-Upload>=4.4.2',
--- a/wikiconfig.py	Tue Mar 20 20:59:55 2012 -0300
+++ b/wikiconfig.py	Tue Mar 27 23:48:23 2012 +0200
@@ -1,7 +1,11 @@
 # -*- coding: utf-8 -*-
-"""MoinMoin Wiki - Configuration"""
+"""
+MoinMoin Wiki - Configuration
 
-import sys, os
+Developers can use this configuration to run moin right from their mercurial workdir.
+"""
+
+import os
 
 from MoinMoin.config.default import DefaultConfig
 from MoinMoin.storage import create_simple_mapping
@@ -9,24 +13,23 @@
 
 
 class Config(DefaultConfig):
-    # vvv DON'T TOUCH THIS EXCEPT IF YOU KNOW WHAT YOU DO vvv
     # Directory containing THIS wikiconfig:
     wikiconfig_dir = os.path.abspath(os.path.dirname(__file__))
     # We assume this structure for a simple "unpack and run" scenario:
     # wikiconfig.py
     # wiki/
     #      data/
+    #      index/
     # contrib/
-    #      xml/
-    #          preloaded_items.xml
+    #      interwiki/
+    #          intermap.txt
     # If that's not true, feel free to adjust the pathes.
     instance_dir = os.path.join(wikiconfig_dir, 'wiki')
     data_dir = os.path.join(instance_dir, 'data') # Note: this used to have a trailing / in the past
     index_dir = os.path.join(instance_dir, "index")
 
     # This provides a simple default setup for your backend configuration.
-    # 'fs:' indicates that you want to use the filesystem backend. You can also use
-    # 'hg:' instead to indicate that you want to use the mercurial backend.
+    # 'stores:fs:...' indicates that you want to use the filesystem backend.
     # Alternatively you can set up the mapping yourself (see HelpOnStorageConfiguration).
     namespace_mapping, backend_mapping, acl_mapping = \
         create_simple_mapping(uri='stores:fs:{0}/%(backend)s/%(kind)s'.format(data_dir),
@@ -41,8 +44,10 @@
                                                     hierarchic=False, ),
                              )
 
+    #item_root = u'Home' # front page
+
+    # for display purposes:
     sitename = u'My MoinMoin'
-
     # it is required that you set this to a unique, stable and non-empty name:
     interwikiname = u'MyMoinMoin'
     # Load the interwiki map from intermap.txt:
@@ -51,27 +56,23 @@
     interwiki_map[interwikiname] = 'http://127.0.0.1:8080/'
     interwiki_map['Self'] = 'http://127.0.0.1:8080/'
 
-    # for now we load some 3rd party stuff from the place within moin where it is currently located,
-    # but soon we'll get rid of this stuff:
-    env_dir = 'env'
+    # setup static files' serving:
     serve_files = dict(
-        docs = os.path.join(wikiconfig_dir, 'docs', '_build', 'html'),
+        docs = os.path.join(wikiconfig_dir, 'docs', '_build', 'html'),  # html docs made by sphinx
     )
-
-    # we slowly migrate all stuff from above (old) method, to xstatic (new) method,
-    # see https://bitbucket.org/thomaswaldmann/xstatic for details:
+    # see https://bitbucket.org/thomaswaldmann/xstatic for infos about xstatic:
     from xstatic.main import XStatic
-    mod_names = ['jquery', 'jquery_file_upload', 'ckeditor', 'svgweb', 'svgedit_moin', 'twikidraw_moin', 'anywikidraw', 'jquery_multi_download', ]
+    mod_names = ['jquery', 'jquery_file_upload', 'jquery_multi_download',
+                 'ckeditor',
+                 'svgweb',
+                 'svgedit_moin', 'twikidraw_moin', 'anywikidraw',
+                ]
     pkg = __import__('xstatic.pkg', fromlist=mod_names)
     for mod_name in mod_names:
         mod = getattr(pkg, mod_name)
         xs = XStatic(mod, root_url='/static', provider='local', protocol='http')
         serve_files.update([(xs.name, xs.base_dir)])
 
-    # ^^^ DON'T TOUCH THIS EXCEPT IF YOU KNOW WHAT YOU DO ^^^
-
-    #item_root = u'Home' # change to some better value
-
 
 MOINCFG = Config # Flask only likes uppercase stuff
 # Flask settings - see the flask documentation about their meaning