changeset 0:b57d88841bf6

Initial import
author Radomir Dopieralski <devel@sheep.art.pl>
date Wed, 14 May 2008 09:20:55 +0200
parents
children c4f16b220541
files css/common.css css/print.css css/projection.css css/screen.css img/alert.png img/angry.png img/attention.png img/biggrin.png img/cancel.gif img/checkmark.png img/devil.png img/draft.png img/err.gif img/frown.png img/icon-error.png img/icon-info.png img/idea.png img/lang.gif img/moin-attach.gif img/moin-bottom.png img/moin-delete.gif img/moin-deleted.png img/moin-diff.gif img/moin-edit.gif img/moin-email.png img/moin-ftp.png img/moin-help.png img/moin-home.png img/moin-icon.png img/moin-info.gif img/moin-inter.png img/moin-map.gif img/moin-new.png img/moin-news.png img/moin-parent.gif img/moin-print.gif img/moin-raw.gif img/moin-refresh.png img/moin-rss.png img/moin-search.png img/moin-show.gif img/moin-subscribe.gif img/moin-telnet.png img/moin-top.png img/moin-unsubscribe.gif img/moin-up.png img/moin-updated.png img/moin-www.png img/moin-xml.png img/moin-xml2.png img/moinmoin.png img/ohwell.png img/prio1.png img/prio2.png img/prio3.png img/redface.png img/sad.png img/smile.png img/smile2.png img/smile3.png img/smile4.png img/star_off.png img/star_on.png img/thumbs-up.png img/tired.png img/tongue.png img/warning.gif moose.py
diffstat 68 files changed, 881 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/css/common.css	Wed May 14 09:20:55 2008 +0200
@@ -0,0 +1,264 @@
+/*  common.css - MoinMoin Default Styles
+
+Copyright (c) 2001, 2002, 2003 by Juergen Hermann
+*/
+
+html, body {
+    font-size: normal;
+}
+a.www:before {content: url(../img/moin-www.png); margin: 0 0.2em;}
+a.http:before {content: url(../img/moin-www.png); margin: 0 0.2em;}
+a.https:before {content: url(../img/moin-www.png); margin: 0 0.2em;}
+a.file:before {content: url(../img/moin-ftp.png); margin: 0 0.2em;}
+a.ftp:before {content: url(../img/moin-ftp.png); margin: 0 0.2em;}
+a.nntp:before {content: url(../img/moin-news.png); margin: 0 0.2em;}
+a.news:before {content: url(../img/moin-news.png); margin: 0 0.2em;}
+a.telnet:before {content: url(../img/moin-telnet.png); margin: 0 0.2em;}
+a.irc:before {content: url(../img/moin-telnet.png); margin: 0 0.2em;}
+a.mailto:before {content: url(../img/moin-email.png); margin: 0 0.2em;}
+a.attachment:before {content: url(../img/moin-attach.png); margin: 0 0.2em;}
+a.badinterwiki:before {content: url(../img/moin-inter.png); margin: 0 0.2em;}
+a.interwiki:before {content: url(../img/moin-inter.png); margin: 0 0.2em;}
+
+p {
+    text-align: justify;
+    margin: 1em 0;
+}
+
+blockquote {
+    clear: both;
+    margin: 0.25em 1.5em;
+}
+
+/* Headings */
+
+h1, h2, h3, h4, h5, h6 {
+    font-weight: bold; 
+    padding: 0.25ex 0; 
+    font-size: normal;
+    border-bottom: 0.18ex solid #000;
+    margin: 0.25em 0;
+}
+h1 {font-size: x-large;}
+h2 {font-size: large;}
+h3 {font-size: normal;}
+h4 {font-size: small;}
+h5 {font-size: x-small;}
+h6 {font-size: xx-small;}
+
+li p {
+	margin: .25em 0;
+}
+
+ul li {
+    list-style: square outside;
+    margin: 0;
+    padding: 0;
+} 
+ul, ol { 
+    margin: 0.25em 0; 
+    padding: 0 0 0 1.5em; 
+}
+li.gap { margin-top: 0.5em; } 
+
+a img, a img.drawing { border: none; } 
+dt { font-weight: bold; }
+
+pre {
+    clear: both;
+	padding: 0.5em;
+	font-family: monospace;
+        font-weight: normal;
+        font-size: normal;
+	white-space: pre;
+	/* begin css 3 or browser specific rules - do not remove! Forcing long lines to wrap.
+	see: http://forums.techguy.org/archive/index.php/t-249849.html */
+    white-space: pre-wrap;
+    word-wrap: break-word;
+    white-space: -moz-pre-wrap;
+    white-space: -pre-wrap;
+    white-space: -o-pre-wrap;
+    /* end css 3 or browser specific rules */
+}
+
+table {
+	margin: 0.5em 0 0 0.5em;
+	border-collapse: collapse;
+        clear: both;
+}
+
+td {
+	padding: 0.25em 0.5em 0.25em 0.5em;
+	border: 1px solid #666;
+}
+
+td p {
+	margin: 0;
+	padding: 0;
+}
+
+/* standard rule ---- */
+hr {
+    clear: both;
+    height: 0.18ex;
+    background: #d00;
+    color: #d00;
+    border: none;
+    margin: 0.5em auto;
+}
+
+/* custom rules ----- to ---------- */
+.hr1 {height: 3px;}
+.hr2 {height: 4px;}
+.hr3 {height: 5px;}
+.hr4 {height: 6px;}
+.hr5 {height: 7px;}
+.hr6 {height: 8px;}
+
+/* Replacement for html 3 u tag */
+.u {text-decoration: underline;}
+
+.footnotes ul {
+	padding: 0 2em;
+	margin: 0 0 1em;
+	list-style: none;
+}
+
+.footnotes li {
+}
+
+
+/* eye catchers */
+.warning, .error { color: red; }
+
+strong.highlight 
+{
+	background-color: #f0ffbb;
+	padding: 0 0.2em;
+        font-style: normal;
+        font-weight: bold;
+        font-variant: normal;
+}
+
+
+/* Recent changes */
+
+div.recentchanges table {
+	border: 1px solid #e5e5e5; 
+}
+
+.recentchanges p {
+	margin: 0.25em;
+}
+
+.recentchanges td {
+	border: none;
+	border-top: 1px solid #e5e5e5;
+	vertical-align: top;
+}
+
+.rcdaybreak {
+	background-color: #f5f5f5;
+}
+
+.rcdaybreak td a {
+	font-size: small;
+        border: none;
+}
+
+.rcicon1, .rcicon2 {
+    text-align: center;
+}
+
+.rcicon1 a, .rcicon2 a {
+    border: none !important;
+}
+
+.rcpagelink {
+	width: 40%;
+}
+
+.rctime {
+	font-size: small;
+	white-space: nowrap;
+}
+
+.rceditor {
+	white-space: nowrap;
+	font-size: small;
+}
+
+.recentchanges td.rccomment {
+        border-top: 1px dashed #e5e5e5;
+        background-color: #f5f5f5;
+	font-size: small;
+        font-family: Verdana, sans-serif;
+}
+
+.rcrss {
+	float: right;
+}
+.rcrss a {
+        border: none !important;
+}
+
+.recentchanges[dir="rtl"] .rcrss {
+	float: left;
+}
+
+/* User Preferences */
+
+.userpref table, .userpref td {
+	border: none;
+}
+
+/* CSS for new code_area markup used by Colorizer and ParserBase */
+
+div.codearea { /* the div makes the border */
+	margin: 0.5em 0;
+	padding: 0;
+/*	background-color: #F3F5F7;
+        border: 1px dashed #ccc;*/
+	color: black;
+        clear: both;
+}
+
+div.codearea pre { /* the pre has no border and is inside the div */
+	margin: 0;
+	padding: 0.5em;
+	border: none;
+        clear: none;
+}
+
+a.codenumbers { /* format of the line numbering link */
+	margin: 0 10pt;
+	font-size: 0.85em;
+	color: gray;
+}
+
+/* format of certain syntax spans */
+div.codearea pre span.LineNumber {color: gray;}
+div.codearea pre span.ID         {color: #000000;}
+div.codearea pre span.Operator   {color: #0000C0;}
+div.codearea pre span.Char       {color: #004080; font-style: oblique;}
+div.codearea pre span.Comment    {color: #008000; font-style: oblique;}
+div.codearea pre span.Number     {color: #0080C0; font-style: oblique;}
+div.codearea pre span.String     {color: #004080; font-style: oblique;}
+div.codearea pre span.SPChar     {color: #0000C0;}
+div.codearea pre span.ResWord    {color: #A00000; font-weight: bold; }
+div.codearea pre span.ConsWord   {color: #008080; font-weight: bold;}
+div.codearea pre span.Error      {background: transparent url(../img/err.gif) repeat-x bottom center;}
+div.codearea pre span.ResWord2   {color: #0080ff; font-weight: bold; font-style: oblique;}
+div.codearea pre span.Special    {color: #0000ff;}
+div.codearea pre span.Preprc     {color: #803999;}
+
+
+/* Page info */
+#pageinfo {
+    font-size: small;
+    text-align: right;
+    font-style: italic;
+}
+
+
+span.anchor { display: none; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/css/print.css	Wed May 14 09:20:55 2008 +0200
@@ -0,0 +1,84 @@
+/*  print.css - MoinMoin Default Styles
+
+Copyright (c) 2001, 2002, 2003 by Juergen Hermann
+*/
+
+/* content styles */
+
+html {
+	font-family: Times, serif;
+	font-size: 12pt;
+}
+
+body {
+    /* Give about 3.4cm in Mozilla/Firefox and about 2.2cm in Safari */
+	margin: 1.5cm;
+}
+
+a, a:visited, a.nonexistent, a.badinterwiki {
+	color: black;
+	text-decoration: none;
+}
+
+a:hover {
+	text-decoration: underline;
+}
+
+pre {
+	font-size: 10pt;
+}
+
+a.interwiki:before, a.badinterwiki:before {
+	content: attr(title) ":";
+}
+
+a.interwiki img, a.badinterwiki img {
+	display: none;
+}
+
+.footnotes div {
+	width: 5em;
+	border-top: 1pt solid gray;
+}
+
+/* user interface styles */
+
+#header, #sidebar, #footer, #timings, #credits, #interwiki, #pagelocation {
+	display: none;
+}
+
+#interwiki {
+    float: left;
+    margin: 0;
+    padding: 0;
+    font-size: 0.4em;
+    display: none;
+}
+
+*[dir="rtl"] #interwiki {
+    float: right;
+}
+
+#interwiki span:after {
+    content: ": ";
+}
+
+#pagelocation {
+    clear: right;
+    display: block;
+    margin: 0;
+    padding: 0;
+    font-size: 0.4em;
+    display: none;
+}
+
+*[dir="rtl"] #pagelocation {
+    clear: left;
+}
+
+#pagelocation li {
+    display: inline;
+    padding: 0 0.3em;
+    margin: 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/css/projection.css	Wed May 14 09:20:55 2008 +0200
@@ -0,0 +1,27 @@
+/*  projection.css - MoinMoin Slide Styles
+
+Copyright (c) 2003 by Juergen Hermann
+*/
+
+@import url(screen.css);
+
+html { line-height: 1.8em; }
+
+body, b, em, a, span, div, p, td { font-size: 22pt; }
+
+h1 { font-size: 28pt; }
+h2 { font-size: 24pt; }
+h3 { font-size: 22pt; }
+h4 { font-size: 20pt; }
+h5 { font-size: 18pt; }
+h6 { font-size: 16pt; }
+
+tt,pre { font-size: 18pt; }
+sup, sub { font-size: 14pt; }
+
+.navigation {
+	font-size: 16pt;
+	padding-top: 8pt;
+	padding-bottom: 8pt;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/css/screen.css	Wed May 14 09:20:55 2008 +0200
@@ -0,0 +1,114 @@
+/* Formatting of the content */
+
+body { color: #000; background: #fff; }
+
+a { color: #d00; text-decoration: none; }
+a.nonexistent, a.badinterwiki { color: #e80; }
+a:visited { color: #d66; }
+a:visited:hover, a:hover { color: #fff; background: #000; }
+
+h1, h2, h3, h4, h5, h6 { color: #666; }	
+#pagelocation { 
+    color: #666;
+    font-size: xx-large; 
+    margin: 0.25em 0 0 0;
+    font-weight: bold;
+}
+
+#header, #page, #footer {
+    margin: 1em 2em;
+    border-bottom: 0.25em solid black;
+/*    width: 40em;
+    margin: 1em auto;  */
+}
+
+.clear {
+    height: 0;
+    clear: both;
+}
+
+#logo { display:block; float: right; padding: 0.25ex; } 
+#logo img {
+    vertical-align: middle;
+    border: none;
+    display: block;
+} 
+#logo a {
+    color: black;  
+    text-decoration: none;
+    white-space: nowrap;
+    border: none;
+    display: block;
+    margin: 0;
+    padding: 0;
+}
+#logo a:hover {
+    background: none;
+}
+
+#credits {
+    display: block;
+    text-align: center;
+    font-size: small;
+}
+#credits li {
+    display: inline;
+    padding: 0 0.5ex;
+}
+
+#username form { display: inline; } 
+#username { margin: 0.25em 0; }
+
+#message, pre {
+    background: #eee;
+    padding: 0.25em;
+    margin: 1em 0;    
+}
+#message .buttons { text-align: right; }
+
+#footer {
+    background: #eee;
+    padding: 0.25em;
+    margin-top: 0;
+}
+#footer a { white-space: nowrap; }
+#footer p { text-align: left; }
+#page { margin-bottom: 0; }
+
+.editbar { display: inline; padding: 0; margin: 0;}
+.editbar li { display: inline; padding: 0; margin: 0;}
+
+/* Get rid of those stupid lists... */
+#pagetrail, #navibar, .editbar { display: inline; padding: 0; margin: 0; }
+#iconbar li, #pagetrail li, #navibar li { display: inline; padding: 0; margin: 0; }
+#navibar li { padding: 0 1ex 0 0; }
+#iconbar { display block; float: right; width: 118px; }
+#iconbar a:hover { background: none; }
+#pagetrail li:after { content: " ยป "; }
+#pagetrail li:last-child { font-weight: bold; }
+#pagetrail li:last-child:after { content: ""; }
+/*#pagetrail, #navibar { font-size: small; } */
+#navibar span a { padding: 0 0.25ex; }
+#navibar .current { font-weight: bold; }
+#navibar .userlink { font-style: italic; }
+
+.codenumbers {
+    display: block;
+    float: right;
+    font-size: small;
+}
+
+abbr { cursor: help; }
+
+img { border: none; }
+
+textarea {
+    display: block;
+    width: 100%;
+}
+
+#editor-help {
+    font-size: x-small; 
+    font-family: monospace;
+    color: #666;
+}
Binary file img/alert.png has changed
Binary file img/angry.png has changed
Binary file img/attention.png has changed
Binary file img/biggrin.png has changed
Binary file img/cancel.gif has changed
Binary file img/checkmark.png has changed
Binary file img/devil.png has changed
Binary file img/draft.png has changed
Binary file img/err.gif has changed
Binary file img/frown.png has changed
Binary file img/icon-error.png has changed
Binary file img/icon-info.png has changed
Binary file img/idea.png has changed
Binary file img/lang.gif has changed
Binary file img/moin-attach.gif has changed
Binary file img/moin-bottom.png has changed
Binary file img/moin-delete.gif has changed
Binary file img/moin-deleted.png has changed
Binary file img/moin-diff.gif has changed
Binary file img/moin-edit.gif has changed
Binary file img/moin-email.png has changed
Binary file img/moin-ftp.png has changed
Binary file img/moin-help.png has changed
Binary file img/moin-home.png has changed
Binary file img/moin-icon.png has changed
Binary file img/moin-info.gif has changed
Binary file img/moin-inter.png has changed
Binary file img/moin-map.gif has changed
Binary file img/moin-new.png has changed
Binary file img/moin-news.png has changed
Binary file img/moin-parent.gif has changed
Binary file img/moin-print.gif has changed
Binary file img/moin-raw.gif has changed
Binary file img/moin-refresh.png has changed
Binary file img/moin-rss.png has changed
Binary file img/moin-search.png has changed
Binary file img/moin-show.gif has changed
Binary file img/moin-subscribe.gif has changed
Binary file img/moin-telnet.png has changed
Binary file img/moin-top.png has changed
Binary file img/moin-unsubscribe.gif has changed
Binary file img/moin-up.png has changed
Binary file img/moin-updated.png has changed
Binary file img/moin-www.png has changed
Binary file img/moin-xml.png has changed
Binary file img/moin-xml2.png has changed
Binary file img/moinmoin.png has changed
Binary file img/ohwell.png has changed
Binary file img/prio1.png has changed
Binary file img/prio2.png has changed
Binary file img/prio3.png has changed
Binary file img/redface.png has changed
Binary file img/sad.png has changed
Binary file img/smile.png has changed
Binary file img/smile2.png has changed
Binary file img/smile3.png has changed
Binary file img/smile4.png has changed
Binary file img/star_off.png has changed
Binary file img/star_on.png has changed
Binary file img/thumbs-up.png has changed
Binary file img/tired.png has changed
Binary file img/tongue.png has changed
Binary file img/warning.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/moose.py	Wed May 14 09:20:55 2008 +0200
@@ -0,0 +1,392 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin moose theme
+
+    Based on the classic theme.
+
+    @copyright: 2006 by RadomirDopieralski (moose@sheep.prv.pl)
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin import wikiutil, version
+from MoinMoin import caching
+from MoinMoin.theme import ThemeBase
+from MoinMoin.Page import Page
+
+
+class Theme(ThemeBase):
+    """ here are the functions generating the html responsible for
+        the look and feel of your wiki site
+    """
+    
+    name = "moose"
+
+    # fake _ function to get gettext recognize those texts:
+    _ = lambda x: x
+
+    # TODO: remove icons that are not used any more.
+    icons = {
+        # key         alt                        icon filename      w   h
+        # ------------------------------------------------------------------
+        # navibar
+        'help':       ("%(page_help_contents)s", "moin-help.gif",   24, 24),
+        'find':       ("%(page_find_page)s",     "moin-search.gif", 24, 24),
+        'diff':       (_("Diffs"),               "moin-diff.gif",   24, 24),
+        'info':       (_("Info"),                "moin-info.gif",   24, 24),
+        'edit':       (_("Edit"),                "moin-edit.gif",   24, 24),
+        'unsubscribe':(_("Unsubscribe"),         "moin-unsubscribe.gif",  24, 24),
+        'subscribe':  (_("Subscribe"),           "moin-subscribe.gif", 24, 24),
+        'raw':        (_("Raw"),                 "moin-raw.gif",    24, 24),
+        'xml':        (_("XML"),                 "moin-xml.gif",    24, 24),
+        'print':      (_("Print"),               "moin-print.gif",  24, 24),
+        'view':       (_("View"),                "moin-show.gif",   24, 24),
+        'home':       (_("Home"),                "moin-home.gif",   24, 24),
+        'up':         (_("Up"),                  "moin-parent.gif", 23, 23),
+        # FileAttach
+        'attach':     ("%(attach_count)s",       "moin-attach.gif", 24, 24),
+        # RecentChanges
+        'rss':        (_("[RSS]"),               "moin-rss.png",    36, 14),
+        'deleted':    (_("[DELETED]"),           "moin-delete.gif", 24, 24),
+        'updated':    (_("[UPDATED]"),           "moin-show.gif",24, 24),
+        'new':        (_("[NEW]"),               "moin-edit.gif",    24, 24),
+        'diffrc':     (_("[DIFF]"),              "moin-diff.gif",   24, 24),
+        # General
+        'bottom':     (_("[BOTTOM]"),            "moin-bottom.gif", 14, 10),
+        'top':        (_("[TOP]"),               "moin-top.gif",    14, 10),
+        'www':        ("[WWW]",                  "moin-www.gif",    11, 11),
+        'mailto':     ("[MAILTO]",               "moin-email.gif",  14, 10),
+        'news':       ("[NEWS]",                 "moin-news.gif",   10, 11),
+        'telnet':     ("[TELNET]",               "moin-telnet.gif", 10, 11),
+        'ftp':        ("[FTP]",                  "moin-ftp.gif",    11, 11),
+        'file':       ("[FILE]",                 "moin-ftp.gif",    11, 11),
+        # search forms
+        'searchbutton': ("[?]",                  "moin-search.gif", 12, 12),
+        'interwiki':  ("[%(wikitag)s]",          "moin-inter.gif",  16, 16),
+    }
+    del _
+
+    def footer(self, d, **keywords):
+        """ Assemble wiki footer
+        
+        @param d: parameter dictionary
+        @keyword ...:...
+        @rtype: unicode
+        @return: page footer html
+        """
+        page = d['page']
+        dict = {
+            'search_form_html': self.searchform(d),
+            'username_html':  self.username(d),
+            'iconbar_html': self.iconbar(d),
+            'page_footer1': self.emit_custom_html(self.cfg.page_footer1),
+            'page_footer2': self.emit_custom_html(self.cfg.page_footer2),
+            'page_info': self.pageinfo(page),
+            'end_page': self.endPage(),
+            'editbar': self.editbar(d, **keywords),
+            'credits': self.credits(d),
+            'version': self.showversion(d, **keywords),
+        }
+        return u'''
+%(page_info)s
+%(end_page)s
+<div id="footer">
+    %(page_footer1)s
+    %(iconbar_html)s
+    %(editbar)s
+    %(search_form_html)s
+    %(username_html)s
+    %(page_footer2)s
+</div>
+%(credits)s
+%(version)s
+'''%dict
+
+    def editbar(self, d, **keywords):
+        if not self.shouldShowEditbar(d['page']):
+            return ''
+        parts = [ self.edit_link(d, **keywords), self.availableactions(d), ]
+        return ''.join(parts)
+
+    def iconbar(self, d):
+        """
+        Assemble the iconbar
+        
+        @param d: parameter dictionary
+        @rtype: string
+        @return: iconbar html
+        """
+        iconbar = []
+        if self.cfg.page_iconbar and self.request.user.show_toolbar and d['page_name']:
+            iconbar.append('<ul id="iconbar">\n')
+            icons = self.cfg.page_iconbar[:]
+            for icon in icons:
+                if icon == "up":
+                    if d['page_parent_page']:
+                        iconbar.append('<li>%s</li>\n' % self.make_iconlink(icon, d))
+                elif icon == "subscribe" and self.cfg.mail_enabled:
+                    iconbar.append('<li>%s</li>\n' % self.make_iconlink(
+                        ["subscribe", "unsubscribe"][self.request.user.isSubscribedTo([d['page_name']])], d))
+                else:
+                    iconbar.append('<li>%s</li>\n' % self.make_iconlink(icon, d))
+            iconbar.append('</ul>\n')
+        return ''.join(iconbar)
+    
+    def header(self, d):
+        """
+        Assemble page header
+        
+        @param d: parameter dictionary
+        @rtype: string
+        @return: page header html
+        """
+        dict = {
+            'config_header1_html': self.emit_custom_html(self.cfg.page_header1),
+            'config_header2_html': self.emit_custom_html(self.cfg.page_header2),
+            'logo_html':  self.logo(),
+            'title_html':  self.title(d),
+            'navibar_html': self.navibar(d),
+            'msg_html': self.msg(d),
+            'trail_html': self.trail(d),
+            'startpage_html': self.startPage(),
+            'interwiki_html':  self.interwiki(d),
+        }
+        dict.update(d)
+
+        html = """
+%(config_header1_html)s
+<div id="header"> 
+%(logo_html)s
+<div id="navidiv">%(navibar_html)s</div>
+<div id="traildiv">%(trail_html)s</div>
+<div id="locationline">%(interwiki_html)s%(title_html)s</div>
+%(msg_html)s
+<div class="clear"></div>
+</div>
+
+%(config_header2_html)s
+
+%(startpage_html)s
+""" % dict
+        return html
+
+    def editorheader(self, d):
+        """
+        Assemble page header for editor
+        
+        @param d: parameter dictionary
+        @rtype: string
+        @return: page header html
+        """
+        dict = {
+            'config_header1_html': self.emit_custom_html(self.cfg.page_header1),
+            'config_header2_html': self.emit_custom_html(self.cfg.page_header2),
+            'title_html': self.title(d),
+            'msg_html': self.msg(d),
+            'startpage_html': self.startPage(),
+        }
+        dict.update(d)
+
+        html = """
+%(config_header1_html)s
+
+%(title_html)s
+%(msg_html)s
+
+%(config_header2_html)s
+
+%(startpage_html)s
+""" % dict
+        return html
+
+    def navibar(self, d):
+        """ Assemble the navibar
+
+        @param d: parameter dictionary
+        @rtype: unicode
+        @return: navibar html
+        """
+        request = self.request
+        found = {} # pages we found. prevent duplicates
+        items = [] # navibar items
+        item = u'<li class="%s">%s</li>'
+        current = d['page_name']
+
+        # Process config navi_bar
+        if request.cfg.navi_bar:
+            for text in request.cfg.navi_bar:
+                pagename, link = self.splitNavilink(text)
+                if pagename == current:
+                    cls = 'wikilink current'
+                else:
+                    cls = 'wikilink'
+                items.append(item % (cls, link))
+                found[pagename] = 1
+
+        # Add user links to wiki links, eliminating duplicates.
+        userlinks = request.user.getQuickLinks()
+        for text in userlinks:
+            # Split text without localization, user knows what he wants
+            pagename, link = self.splitNavilink(text, localize=0)
+            if not pagename in found:
+                if pagename == current:
+                    cls = 'userlink current'
+                else:
+                    cls = 'userlink'
+                items.append(item % (cls, link))
+                found[pagename] = 1
+
+        # Add current page at end
+#        if not current in found:
+#            title = d['page'].split_title(request)
+#            title = self.shortenPagename(title)
+#            link = d['page'].link_to(request, title)
+#            cls = 'current'
+#            items.append(item % (cls, link))
+
+        # Assemble html
+        items = u''.join(items)
+        html = u'''
+<ul id="navibar">
+%s
+</ul>
+''' % items
+        return html
+
+    def username(self, d):
+        """ Assemble the username / userprefs link
+        
+        @param d: parameter dictionary
+        @rtype: unicode
+        @return: username html
+        """
+        request = self.request
+        _ = request.getText
+        preferencesPage = wikiutil.getSysPage(request, 'UserPreferences')
+        
+        userlinks = []
+        # Add username/homepage link for registered users. We don't care
+        # if it exists, the user can create it.
+        if request.user.valid and request.user.name:
+            interwiki = wikiutil.getInterwikiHomePage(request)
+            name = request.user.name
+            aliasname = request.user.aliasname
+            if not aliasname:
+                aliasname = name
+            title = "%s @ %s" % (aliasname, interwiki[0])
+            homelink = (request.formatter.interwikilink(1, title=title, *interwiki) +
+                        request.formatter.text(name) +
+                        request.formatter.interwikilink(0))
+            userlinks.append(homelink)        
+            # Set pref page to localized Preferences page
+            title = preferencesPage.split_title(request)
+            userlinks.append(preferencesPage.link_to(request, text=title))
+            
+        if request.cfg.show_login:
+            if request.user.valid:
+                userlinks.append("""\
+<form action="" method="POST">
+<input type="hidden" name="action" value="userform">
+<input type="submit" name="logout" value="%(logout)s">
+</form>
+""" % { 'logout': _('Logout') })
+            else:
+                userlinks.append(preferencesPage.link_to(request, text=_("Login")))
+
+        userlinks = [u'<span>%s</span>' % link for link in userlinks]
+        html = u'<div id="username">%s</div>' % ', '.join(userlinks)
+        return html
+
+    def title(self, d):
+        """ Assemble the title (not using breadcrumbs)
+        
+        @param d: parameter dictionary
+        @rtype: string
+        @return: title html
+        """
+        _ = self.request.getText
+        content = []
+        if d['title_link']: # having a link means we have a (linked) pagename ONLY as title, not a message title
+                            # XXX this method is rather ugly and should be improved
+            curpage = ''
+            segments = d['page_name'].split('/') # was: title_text
+            for s in segments[:-1]:
+                curpage += s
+                content.append("<span>%s</span>" % Page(self.request, curpage).link_to(self.request, s))
+                curpage += '/'
+            content.append(('<span><a class="backlink" title="%(title)s" href="%(href)s">%(text)s</a></span>') % {
+                'title': _('Click to do a full-text search for this title'),
+                'href': d['title_link'],
+                'text': wikiutil.escape(segments[-1]),
+                })
+        else:
+            content.append('<span>%s</span>' % wikiutil.escape(d['title_text']))
+
+        html = '''
+<div id="pagelocation">
+%s
+</div>
+''' % "".join(content)
+        return html
+
+    # Footer stuff #######################################################
+    
+    def edit_link(self, d, **keywords):
+        """
+        Assemble EditText link (or indication that page cannot be edited)
+        
+        @param d: parameter dictionary
+        @rtype: string
+        @return: edittext link html
+        """
+        page = d['page']
+        return  u'<ul class="editbar"><li>%s, </li>' % self.editorLink(page)
+
+    def availableactions(self, d):    
+        """
+        assemble HTML code for the available actions
+        
+        @param d: parameter dictionary
+        @rtype: string
+        @return: available actions html
+        """
+        request = self.request
+        _ = request.getText
+        html = []
+        page = d['page']
+        available = request.getAvailableActions(page)
+        if available:
+            available = available.keys()
+            available.sort()
+            for action in available:
+                # Always add spaces: AttachFile -> Attach File 
+                # XXX TODO do not make a page object just for split_title
+                title = Page(request, action).split_title(request, force=1)
+                # Use translated version if available
+                title = _(title, formatted=False)
+                params = '%s?action=%s' % (d['q_page_name'], action)
+                link = wikiutil.link_tag(request, params, title)
+                html.append(link)
+                
+        title = _("DeleteCache", formatted=False)
+        params = '%s?action=%s' % (d['page_name'], 'refresh')
+        link = wikiutil.link_tag(request, params, title)
+        
+        cache = caching.CacheEntry(request, page, page.getFormatterName())
+        date = request.user.getFormattedDateTime(cache.mtime())
+        deletecache = u' <li>%s %s</li>' % (link, _('(cached %s)') % date)
+
+        html = deletecache + u'</ul><p>%s %s</p>\n' % (_('Or try one of these actions:'),
+                                       u', '.join(html))
+        return html
+
+
+def execute(request):
+    """
+    Generate and return a theme object
+        
+    @param request: the request object
+    @rtype: MoinTheme
+    @return: Theme object
+    """
+    return Theme(request)
+