changeset 616:3b08d9413589

move send_title/footer from wikiutil to theme.__init__
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Fri, 05 May 2006 12:41:10 +0200
parents fb4240ec8361
children cf420addd95c
files MoinMoin/Page.py MoinMoin/PageEditor.py MoinMoin/PageGraphicalEditor.py MoinMoin/action/AttachFile.py MoinMoin/action/Despam.py MoinMoin/action/LikePages.py MoinMoin/action/LocalSiteMap.py MoinMoin/action/MyPages.py MoinMoin/action/SubscribeUser.py MoinMoin/action/backup.py MoinMoin/action/fullsearch.py MoinMoin/action/links.py MoinMoin/action/login.py MoinMoin/request.py MoinMoin/theme/__init__.py MoinMoin/wikiaction.py MoinMoin/wikiutil.py
diffstat 17 files changed, 321 insertions(+), 338 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/Page.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/Page.py	Fri May 05 12:41:10 2006 +0200
@@ -1181,7 +1181,7 @@
                     request.user.addTrail(self.page_name)
                     trail = request.user.getTrail()
 
-                wikiutil.send_title(request, title,  page=self, link=link, msg=msg,
+                request.theme.send_title(title,  page=self, link=link, msg=msg,
                                     pagename=self.page_name, print_mode=print_mode,
                                     media=media, pi_refresh=pi_refresh,
                                     allow_doubleclick=1, trail=trail,
@@ -1248,7 +1248,7 @@
         if not content_only:
             # send the page footer
             if self.default_formatter:
-                wikiutil.send_footer(request, self.page_name, print_mode=print_mode)
+                request.theme.send_footer(self.page_name, print_mode=print_mode)
 
             request.write(doc_trailer)
 
--- a/MoinMoin/PageEditor.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/PageEditor.py	Fri May 05 12:41:10 2006 +0200
@@ -243,7 +243,7 @@
         status = ' '.join(status)
         status = Status(self.request, content=status)
         
-        wikiutil.send_title(self.request,
+        self.request.theme.send_title(
             title % {'pagename': self.split_title(self.request),},
             page=self,
             pagename=self.page_name, msg=status,
@@ -428,7 +428,7 @@
                            hilite_re=badwords_re)
 
         self.request.write(self.request.formatter.endContent())
-        wikiutil.send_footer(self.request, self.page_name)
+        self.request.theme.send_footer(self.page_name)
         
     def sendCancel(self, newtext, rev):
         """
--- a/MoinMoin/PageGraphicalEditor.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/PageGraphicalEditor.py	Fri May 05 12:41:10 2006 +0200
@@ -150,7 +150,7 @@
         status = ' '.join(status)
         status = Status(self.request, content=status)
         
-        wikiutil.send_title(self.request,
+        self.request.theme.send_title(
             title % {'pagename': self.split_title(self.request),},
             page=self,
             pagename=self.page_name, msg=status,
@@ -352,5 +352,5 @@
                            hilite_re=badwords_re)
 
         self.request.write(self.request.formatter.endContent()) # end content div
-        wikiutil.send_footer(self.request, self.page_name)
+        self.request.theme.send_footer(self.page_name)
 
--- a/MoinMoin/action/AttachFile.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/action/AttachFile.py	Fri May 05 12:41:10 2006 +0200
@@ -502,11 +502,11 @@
     request.http_headers()
     # Use user interface language for this generated page
     request.setContentLanguage(request.lang)
-    wikiutil.send_title(request, _('Attachments for "%(pagename)s"') % {'pagename': pagename}, pagename=pagename, msg=msg)
+    request.theme.send_title(_('Attachments for "%(pagename)s"') % {'pagename': pagename}, pagename=pagename, msg=msg)
     request.write('<div id="content">\n') # start content div
     send_uploadform(pagename, request)
     request.write('</div>\n') # end content div
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
 
 
 def do_upload(pagename, request):
@@ -817,7 +817,7 @@
     request.setContentLanguage(request.lang)
     title = _('attachment:%(filename)s of %(pagename)s', formatted=True) % {
         'filename': filename, 'pagename': pagename}
-    wikiutil.send_title(request, title, pagename=pagename)
+    request.theme.send_title(title, pagename=pagename)
 
     # send body
     # TODO: use formatter startContent?
@@ -827,7 +827,7 @@
     request.write('</div>\n') # end content div
 
     # send footer
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
 
 
 #############################################################################
--- a/MoinMoin/action/Despam.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/action/Despam.py	Fri May 05 12:41:10 2006 +0200
@@ -171,7 +171,7 @@
     ok = request.form.get('ok', [0])[0]
 
     request.http_headers()
-    wikiutil.send_title(request, "Despam", pagename=pagename)    
+    request.theme.send_title("Despam", pagename=pagename)    
     # Start content (important for RTL support)
     request.write(request.formatter.startContent("content"))
     
@@ -184,5 +184,5 @@
 
     # End content and send footer
     request.write(request.formatter.endContent())
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
 
--- a/MoinMoin/action/LikePages.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/action/LikePages.py	Fri May 05 12:41:10 2006 +0200
@@ -44,8 +44,7 @@
     # This action generate data using the user language
     request.setContentLanguage(request.lang)
 
-    wikiutil.send_title(request, _('Pages like "%s"') % (pagename),
-                        pagename=pagename)
+    request.theme.send_title(_('Pages like "%s"') % (pagename), pagename=pagename)
         
     # Start content - IMPORTANT - without content div, there is no
     # direction support!
@@ -55,7 +54,7 @@
 
     # End content and send footer
     request.write(request.formatter.endContent())
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
         
 
 def findMatches(pagename, request, s_re=None, e_re=None,):
--- a/MoinMoin/action/LocalSiteMap.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/action/LocalSiteMap.py	Fri May 05 12:41:10 2006 +0200
@@ -33,8 +33,7 @@
     # This action generate data using the user language
     request.setContentLanguage(request.lang)
 
-    wikiutil.send_title(request, _('Local Site Map for "%s"') % (pagename),  
-        pagename=pagename)
+    request.theme.send_title(_('Local Site Map for "%s"') % (pagename), pagename=pagename)
 
     # Start content - IMPORTANT - witout content div, there is no
     # direction support!
@@ -42,10 +41,8 @@
 
     request.write(LocalSiteMap(pagename).output(request))
 
-    # End content
     request.write(request.formatter.endContent()) # end content div
-    # Footer
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
 
 
 class LocalSiteMap:
--- a/MoinMoin/action/MyPages.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/action/MyPages.py	Fri May 05 12:41:10 2006 +0200
@@ -65,8 +65,7 @@
     
     # This action generate data using the user language
     request.setContentLanguage(request.lang)
-
-    wikiutil.send_title(request, _('MyPages management'), pagename=pagename)
+    request.theme.send_title(_('MyPages management'), pagename=pagename)
         
     # Start content - IMPORTANT - without content div, there is no
     # direction support!
@@ -86,8 +85,7 @@
     else:
         request.formatter = reqformatter
 
-    # End content and send footer
     request.write(request.formatter.endContent())
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
 
 
--- a/MoinMoin/action/SubscribeUser.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/action/SubscribeUser.py	Fri May 05 12:41:10 2006 +0200
@@ -18,7 +18,7 @@
 def show_form(pagename, request):
     _ = request.getText
     request.http_headers()
-    wikiutil.send_title(request, _("Subscribe users to the page %s") % pagename, pagename=pagename)
+    request.theme.send_title(_("Subscribe users to the page %s") % pagename, pagename=pagename)
 
     request.write("""
 <form action="" method="POST" enctype="multipart/form-data">
@@ -27,13 +27,13 @@
 <input type="submit" value="Subscribe">
 </form>
 """)
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
 
 def show_result(pagename, request):
     _ = request.getText
     request.http_headers()
 
-    wikiutil.send_title(request, _("Subscribed for %s:") % pagename, pagename=pagename)
+    request.theme.send_title(_("Subscribed for %s:") % pagename, pagename=pagename)
 
     from MoinMoin.formatter.text_html import Formatter
     formatter = Formatter(request)
@@ -41,7 +41,7 @@
     result = subscribe_users(request, request.form['users'][0].split(","), pagename, formatter)
     request.write(result)
 
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
 
 
 def subscribe_users(request, usernamelist, pagename, formatter):
@@ -86,7 +86,7 @@
     _ = request.getText
     if not request.user.may.admin(pagename):
         request.http_headers()
-        wikiutil.send_title(request, _("You are not allowed to perform this action."), pagename=pagename)
+        request.theme.send_title(_("You are not allowed to perform this action."), pagename=pagename)
     elif not request.form.has_key('users'):
         show_form(pagename, request)
     else:
--- a/MoinMoin/action/backup.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/action/backup.py	Fri May 05 12:41:10 2006 +0200
@@ -75,7 +75,7 @@
     request.http_headers()
     request.setContentLanguage(request.lang)
     title = _('Wiki Backup / Restore')
-    wikiutil.send_title(request, title, form=request.form, pagename=pagename)
+    request.theme.send_title(title, form=request.form, pagename=pagename)
     request.write(request.formatter.startContent("content"))
     
     request.write(_("""Some hints:
@@ -112,7 +112,7 @@
 })
     
     request.write(request.formatter.endContent())
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
 
 def sendMsg(request, pagename, msg):
     from MoinMoin import Page
--- a/MoinMoin/action/fullsearch.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/action/fullsearch.py	Fri May 05 12:41:10 2006 +0200
@@ -89,8 +89,7 @@
         title = _('Full Text Search: "%s"')
         results.sortByWeight() 
 
-    wikiutil.send_title(request, title % needle, form=request.form,
-                        pagename=pagename)
+    request.theme.send_title(title % needle, form=request.form, pagename=pagename)
     
     # Start content (important for RTL support)
     request.write(request.formatter.startContent("content"))
@@ -109,5 +108,5 @@
 
     # End content and send footer
     request.write(request.formatter.endContent())
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
 
--- a/MoinMoin/action/links.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/action/links.py	Fri May 05 12:41:10 2006 +0200
@@ -25,8 +25,7 @@
     request.http_headers(["Content-Type: %s; charset=%s" % (mimetype,config.charset)])
 
     if mimetype == "text/html":
-        wikiutil.send_title(request,
-                            _('Full Link List for "%s"') % request.cfg.sitename)
+        request.theme.send_title(_('Full Link List for "%s"') % request.cfg.sitename)
         request.write('<pre>')
 
     # Get page dict readable by current user
@@ -52,7 +51,7 @@
 
     if mimetype == "text/html":
         request.write('</pre>')
-        wikiutil.send_footer(request, pagename)
+        request.theme.send_footer(pagename)
     else:
         raise MoinMoinNoFooter
 
--- a/MoinMoin/action/login.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/action/login.py	Fri May 05 12:41:10 2006 +0200
@@ -61,7 +61,7 @@
         
         else: # show login form
             request.http_headers()
-            wikiutil.send_title(request, _("Login"), pagename=self.pagename)
+            request.theme.send_title(_("Login"), pagename=self.pagename)
             # Start content (important for RTL support)
             request.write(request.formatter.startContent("content"))
             
@@ -69,5 +69,5 @@
             
             # End content and send footer
             request.write(request.formatter.endContent())
-            wikiutil.send_footer(request, self.pagename)
+            request.theme.send_footer(self.pagename)
 
--- a/MoinMoin/request.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/request.py	Fri May 05 12:41:10 2006 +0200
@@ -735,8 +735,7 @@
         sys.stderr.write(msg)
     
     def write(self, *data):
-        """ Write to output stream.
-        """
+        """ Write to output stream. """
         raise NotImplementedError
 
     def encode(self, data):
@@ -841,13 +840,11 @@
         return name
         
     def read(self, n):
-        """ Read n bytes from input stream.
-        """
+        """ Read n bytes from input stream. """
         raise NotImplementedError
 
     def flush(self):
-        """ Flush output stream.
-        """
+        """ Flush output stream. """
         raise NotImplementedError
 
     def check_spider(self):
@@ -1110,24 +1107,9 @@
                     handler = getHandler(self, action)
                     handler(self.page.page_name, self)
 
-            # generate page footer (actions that do not want this footer use
-            # raise util.MoinMoinNoFooter to break out of the default execution
-            # path, see the "except MoinMoinNoFooter" below)
-
-            self.clock.stop('run')
-            self.clock.stop('total')
+            # XXX temporary, to be removed later
+            self.theme.send_closing_html()
 
-            # Close html code
-            if not self.no_closing_html_code:
-                if (self.cfg.show_timings and
-                    self.form.get('action', [None])[0] != 'print'):
-                    self.write('<ul id="timings">\n')
-                    for t in self.clock.dump():
-                        self.write('<li>%s</li>\n' % t)
-                    self.write('</ul>\n')
-                #self.write('<!-- auth_method == %s -->' % repr(self.user.auth_method))
-                self.write('</body>\n</html>\n\n')
-            
         except MoinMoinNoFooter:
             pass
         except Exception, err:
--- a/MoinMoin/theme/__init__.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/theme/__init__.py	Fri May 05 12:41:10 2006 +0200
@@ -1379,3 +1379,284 @@
         lang = self.request.content_lang
         return ' lang="%s" dir="%s"' % (lang, i18n.getDirection(lang))
 
+    # stuff moved from request.py
+    def send_closing_html(self):
+        """ generate timing info html and closing html tag """
+        request = self.request
+
+        # as this is the last chance to emit some html, we stop the clocks:
+        request.clock.stop('run')
+        request.clock.stop('total')
+
+        # Close html code
+        if not request.no_closing_html_code:
+            if (request.cfg.show_timings and
+                request.form.get('action', [None])[0] != 'print'):
+                request.write('<ul id="timings">\n')
+                for t in request.clock.dump():
+                    request.write('<li>%s</li>\n' % t)
+                request.write('</ul>\n')
+            #request.write('<!-- auth_method == %s -->' % repr(request.user.auth_method))
+            request.write('</body>\n</html>\n\n')
+
+    # stuff from wikiutil.py
+    def send_title(self, text, **keywords):
+        """
+        Output the page header (and title).
+
+        TODO: check all code that call us and add page keyword for the
+        current page being rendered.
+        
+        @param text: the title text
+        @keyword link: URL for the title
+        @keyword msg: additional message (after saving)
+        @keyword pagename: 'PageName'
+        @keyword page: the page instance that called us.
+        @keyword print_mode: 1 (or 0)
+        @keyword editor_mode: 1 (or 0)
+        @keyword media: css media type, defaults to 'screen'
+        @keyword allow_doubleclick: 1 (or 0)
+        @keyword html_head: additional <head> code
+        @keyword body_attr: additional <body> attributes
+        @keyword body_onload: additional "onload" JavaScript code
+        """
+        request = self.request
+        _ = request.getText
+        
+        if keywords.has_key('page'):
+            page = keywords['page']
+            pagename = page.page_name
+        else:
+            pagename = keywords.get('pagename', '')
+            page = Page(request, pagename)
+        
+        scriptname = request.getScriptname()
+        pagename_quoted = wikiutil.quoteWikinameURL(pagename)
+
+        # get name of system pages
+        page_front_page = wikiutil.getFrontPage(request).page_name
+        page_help_contents = wikiutil.getSysPage(request, 'HelpContents').page_name
+        page_title_index = wikiutil.getSysPage(request, 'TitleIndex').page_name
+        page_site_navigation = wikiutil.getSysPage(request, 'SiteNavigation').page_name
+        page_word_index = wikiutil.getSysPage(request, 'WordIndex').page_name
+        page_user_prefs = wikiutil.getSysPage(request, 'UserPreferences').page_name
+        page_help_formatting = wikiutil.getSysPage(request, 'HelpOnFormatting').page_name
+        page_find_page = wikiutil.getSysPage(request, 'FindPage').page_name
+        home_page = wikiutil.getInterwikiHomePage(request) # XXX sorry theme API change!!! Either None or tuple (wikiname,pagename) now.
+        page_parent_page = getattr(page.getParentPage(), 'page_name', None)
+        
+        # Prepare the HTML <head> element
+        user_head = [request.cfg.html_head]
+
+        # include charset information - needed for moin_dump or any other case
+        # when reading the html without a web server
+        user_head.append('''<meta http-equiv="Content-Type" content="text/html;charset=%s">\n''' % config.charset)
+
+        meta_keywords = request.getPragma('keywords')
+        meta_desc = request.getPragma('description')
+        if meta_keywords:
+            user_head.append('<meta name="keywords" content="%s">\n' % escape(meta_keywords, 1))
+        if meta_desc:
+            user_head.append('<meta name="description" content="%s">\n' % escape(meta_desc, 1))
+
+        # search engine precautions / optimization:
+        # if it is an action or edit/search, send query headers (noindex,nofollow):
+        if request.query_string:
+            user_head.append(request.cfg.html_head_queries)
+        elif request.request_method == 'POST':
+            user_head.append(request.cfg.html_head_posts)
+        # if it is a special page, index it and follow the links - we do it
+        # for the original, English pages as well as for (the possibly
+        # modified) frontpage:
+        elif pagename in [page_front_page, request.cfg.page_front_page,
+                          page_title_index, 'TitleIndex',
+                          page_find_page, 'FindPage',
+                          page_site_navigation, 'SiteNavigation',
+                          'RecentChanges',]:
+            user_head.append(request.cfg.html_head_index)
+        # if it is a normal page, index it, but do not follow the links, because
+        # there are a lot of illegal links (like actions) or duplicates:
+        else:
+            user_head.append(request.cfg.html_head_normal)
+
+        if keywords.has_key('pi_refresh') and keywords['pi_refresh']:
+            user_head.append('<meta http-equiv="refresh" content="%(delay)d;URL=%(url)s">' % keywords['pi_refresh'])
+        
+        # output buffering increases latency but increases throughput as well
+        output = []
+        # later: <html xmlns=\"http://www.w3.org/1999/xhtml\">
+        output.append("""\
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+%s
+%s
+%s
+""" % (
+            ''.join(user_head),
+            self.html_head({
+                'page': page,
+                'title': wikiutil.escape(text),
+                'sitename': wikiutil.escape(request.cfg.html_pagetitle or request.cfg.sitename),
+                'print_mode': keywords.get('print_mode', False),
+                'media': keywords.get('media', 'screen'),
+            }),
+            keywords.get('html_head', ''),
+        ))
+
+        # Links
+        output.append('<link rel="Start" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_front_page)))
+        if pagename:
+            output.append('<link rel="Alternate" title="%s" href="%s/%s?action=raw">\n' % (
+                _('Wiki Markup'), scriptname, pagename_quoted,))
+            output.append('<link rel="Alternate" media="print" title="%s" href="%s/%s?action=print">\n' % (
+                _('Print View'), scriptname, pagename_quoted,))
+
+            # !!! currently disabled due to Mozilla link prefetching, see
+            # http://www.mozilla.org/projects/netlib/Link_Prefetching_FAQ.html
+            #~ all_pages = request.getPageList()
+            #~ if all_pages:
+            #~     try:
+            #~         pos = all_pages.index(pagename)
+            #~     except ValueError:
+            #~         # this shopuld never happend in theory, but let's be sure
+            #~         pass
+            #~     else:
+            #~         request.write('<link rel="First" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[0]))
+            #~         if pos > 0:
+            #~             request.write('<link rel="Previous" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[pos-1])))
+            #~         if pos+1 < len(all_pages):
+            #~             request.write('<link rel="Next" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[pos+1])))
+            #~         request.write('<link rel="Last" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[-1])))
+
+            if page_parent_page:
+                output.append('<link rel="Up" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_parent_page)))
+
+        # write buffer because we call AttachFile
+        request.write(''.join(output))
+        output = []
+
+        if pagename:
+            from MoinMoin.action import AttachFile
+            AttachFile.send_link_rel(request, pagename)
+
+        output.extend([
+            '<link rel="Search" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_find_page)),
+            '<link rel="Index" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_title_index)),
+            '<link rel="Glossary" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_word_index)),
+            '<link rel="Help" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_help_formatting)),
+                      ])
+        
+        output.append("</head>\n")
+        request.write(''.join(output))
+        output = []
+        request.flush()
+
+        # start the <body>
+        bodyattr = []
+        if keywords.has_key('body_attr'):
+            bodyattr.append(' ')
+            bodyattr.append(keywords['body_attr'])
+
+        # Add doubleclick edit action
+        if (pagename and keywords.get('allow_doubleclick', 0) and
+            not keywords.get('print_mode', 0) and
+            request.user.edit_on_doubleclick):
+            if request.user.may.write(pagename): # separating this gains speed
+                querystr = wikiutil.escape(makeQueryString({'action': 'edit'}))
+                # TODO: remove escape=0 in 2.0
+                url = page.url(request, querystr, escape=0)
+                bodyattr.append(''' ondblclick="location.href='%s'" ''' % url)
+
+        # Set body to the user interface language and direction
+        bodyattr.append(' %s' % self.ui_lang_attr())
+        
+        body_onload = keywords.get('body_onload', '')
+        if body_onload:
+            bodyattr.append(''' onload="%s"''' % body_onload)
+        output.append('\n<body%s>\n' % ''.join(bodyattr))
+
+        # Output -----------------------------------------------------------
+
+        # If in print mode, start page div and emit the title
+        if keywords.get('print_mode', 0):
+            d = {'title_text': text, 'title_link': None, 'page': page,}
+            request.themedict = d
+            output.append(self.startPage())
+            output.append(self.interwiki(d))      
+            output.append(self.title(d))      
+
+        # In standard mode, emit theme.header
+        else:
+            # prepare dict for theme code:
+            d = {
+                'theme': self.name,
+                'script_name': scriptname,
+                'title_text': text,
+                'title_link': keywords.get('link', ''),
+                'logo_string': request.cfg.logo_string,
+                'site_name': request.cfg.sitename,
+                'page': page,
+                'pagesize': pagename and page.size() or 0,
+                'last_edit_info': pagename and page.lastEditInfo() or '',
+                'page_name': pagename or '',
+                'page_find_page': page_find_page,
+                'page_front_page': page_front_page,
+                'home_page': home_page,
+                'page_help_contents': page_help_contents,
+                'page_help_formatting': page_help_formatting,
+                'page_parent_page': page_parent_page,
+                'page_title_index': page_title_index,
+                'page_word_index': page_word_index,
+                'page_user_prefs': page_user_prefs,
+                'user_name': request.user.name,
+                'user_valid': request.user.valid,
+                'user_prefs': (page_user_prefs, request.user.name)[request.user.valid],
+                'msg': keywords.get('msg', ''),
+                'trail': keywords.get('trail', None),
+                # Discontinued keys, keep for a while for 3rd party theme developers
+                'titlesearch': 'use self.searchform(d)',
+                'textsearch': 'use self.searchform(d)',
+                'navibar': ['use self.navibar(d)'],
+                'available_actions': ['use self.request.availableActions(page)'],
+            }
+
+            # add quoted versions of pagenames
+            newdict = {}
+            for key in d:
+                if key.startswith('page_'):
+                    if not d[key] is None:
+                        newdict['q_'+key] = wikiutil.quoteWikinameURL(d[key])
+                    else:
+                        newdict['q_'+key] = None
+            d.update(newdict)
+            request.themedict = d
+
+            # now call the theming code to do the rendering
+            if keywords.get('editor_mode', 0):
+                output.append(self.editorheader(d))
+            else:
+                output.append(self.header(d))
+        
+        # emit it
+        request.write(''.join(output))
+        output = []
+        request.flush()
+
+    def send_footer(self, pagename, **keywords):
+        """
+        Output the page footer.
+
+        @param pagename: WikiName of the page
+        @keyword print_mode: true, when page is displayed in Print mode
+        """
+        request = self.request
+        d = request.themedict
+
+        # Emit end of page in print mode, or complete footer in standard mode
+        if keywords.get('print_mode', 0):
+            request.write(self.pageinfo(d['page']))
+            request.write(self.endPage())
+        else:
+            request.write(self.footer(d, **keywords))
+
--- a/MoinMoin/wikiaction.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/wikiaction.py	Fri May 05 12:41:10 2006 +0200
@@ -113,7 +113,7 @@
     request.setContentLanguage(request.lang)
 
     request.http_headers()
-    wikiutil.send_title(request, _('Diff for "%s"') % (pagename,), pagename=pagename, allow_doubleclick=1)
+    request.theme.send_title(_('Diff for "%s"') % (pagename,), pagename=pagename, allow_doubleclick=1)
   
     if (rev1>0 and rev2>0 and rev1>rev2) or (rev1==0 and rev2>0):
         rev1,rev2 = rev2,rev1
@@ -197,7 +197,7 @@
             request.write('</pre>')
 
     request.write('</div>\n') # end content div
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
 
 
 def do_info(pagename, request):
@@ -402,7 +402,7 @@
     lang = page.language or request.cfg.language_default
     request.setContentLanguage(lang)
     
-    wikiutil.send_title(request, _('Info for "%s"') % (title,), pagename=pagename)
+    request.theme.send_title(_('Info for "%s"') % (title,), pagename=pagename)
 
     historylink =  wikiutil.link_tag(request, '%s?action=info' % qpagename,
         _('Show "%(title)s"') % {'title': _('Revision History')})
@@ -426,7 +426,7 @@
         history(page, pagename, request)
         
     request.write('</div>\n') # end content div
-    wikiutil.send_footer(request, pagename)
+    request.theme.send_footer(pagename)
 
 
 def do_recall(pagename, request):
--- a/MoinMoin/wikiutil.py	Fri May 05 10:40:13 2006 +0200
+++ b/MoinMoin/wikiutil.py	Fri May 05 12:41:10 2006 +0200
@@ -1211,278 +1211,6 @@
     return lines
  
 
-#############################################################################
-### Page header / footer
-#############################################################################
-
-# FIXME - this is theme code, move to theme
-# Could be simplified by using a template
-
-def send_title(request, text, **keywords):
-    """
-    Output the page header (and title).
-
-    TODO: check all code that call us and add page keyword for the
-    current page being rendered.
-    
-    @param request: the request object
-    @param text: the title text
-    @keyword link: URL for the title
-    @keyword msg: additional message (after saving)
-    @keyword pagename: 'PageName'
-    @keyword page: the page instance that called us.
-    @keyword print_mode: 1 (or 0)
-    @keyword editor_mode: 1 (or 0)
-    @keyword media: css media type, defaults to 'screen'
-    @keyword allow_doubleclick: 1 (or 0)
-    @keyword html_head: additional <head> code
-    @keyword body_attr: additional <body> attributes
-    @keyword body_onload: additional "onload" JavaScript code
-    """
-    from MoinMoin.Page import Page
-    _ = request.getText
-    
-    if keywords.has_key('page'):
-        page = keywords['page']
-        pagename = page.page_name
-    else:
-        pagename = keywords.get('pagename', '')
-        page = Page(request, pagename)
-    
-    scriptname = request.getScriptname()
-    pagename_quoted = quoteWikinameURL(pagename)
-
-    # get name of system pages
-    page_front_page = getFrontPage(request).page_name
-    page_help_contents = getSysPage(request, 'HelpContents').page_name
-    page_title_index = getSysPage(request, 'TitleIndex').page_name
-    page_site_navigation = getSysPage(request, 'SiteNavigation').page_name
-    page_word_index = getSysPage(request, 'WordIndex').page_name
-    page_user_prefs = getSysPage(request, 'UserPreferences').page_name
-    page_help_formatting = getSysPage(request, 'HelpOnFormatting').page_name
-    page_find_page = getSysPage(request, 'FindPage').page_name
-    home_page = getInterwikiHomePage(request) # XXX sorry theme API change!!! Either None or tuple (wikiname,pagename) now.
-    page_parent_page = getattr(page.getParentPage(), 'page_name', None)
-    
-    # Prepare the HTML <head> element
-    user_head = [request.cfg.html_head]
-
-    # include charset information - needed for moin_dump or any other case
-    # when reading the html without a web server
-    user_head.append('''<meta http-equiv="Content-Type" content="text/html;charset=%s">\n''' % config.charset)
-
-    meta_keywords = request.getPragma('keywords')
-    meta_desc = request.getPragma('description')
-    if meta_keywords:
-        user_head.append('<meta name="keywords" content="%s">\n' % escape(meta_keywords, 1))
-    if meta_desc:
-        user_head.append('<meta name="description" content="%s">\n' % escape(meta_desc, 1))
-
-    # search engine precautions / optimization:
-    # if it is an action or edit/search, send query headers (noindex,nofollow):
-    if request.query_string:
-        user_head.append(request.cfg.html_head_queries)
-    elif request.request_method == 'POST':
-        user_head.append(request.cfg.html_head_posts)
-    # if it is a special page, index it and follow the links - we do it
-    # for the original, English pages as well as for (the possibly
-    # modified) frontpage:
-    elif pagename in [page_front_page, request.cfg.page_front_page,
-                      page_title_index, 'TitleIndex',
-                      page_find_page, 'FindPage',
-                      page_site_navigation, 'SiteNavigation',
-                      'RecentChanges',]:
-        user_head.append(request.cfg.html_head_index)
-    # if it is a normal page, index it, but do not follow the links, because
-    # there are a lot of illegal links (like actions) or duplicates:
-    else:
-        user_head.append(request.cfg.html_head_normal)
-
-    if keywords.has_key('pi_refresh') and keywords['pi_refresh']:
-        user_head.append('<meta http-equiv="refresh" content="%(delay)d;URL=%(url)s">' % keywords['pi_refresh'])
-    
-    # output buffering increases latency but increases throughput as well
-    output = []
-    # later: <html xmlns=\"http://www.w3.org/1999/xhtml\">
-    output.append("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-%s
-%s
-%s
-""" % (
-        ''.join(user_head),
-        request.theme.html_head({
-            'page': page,
-            'title': escape(text),
-            'sitename': escape(request.cfg.html_pagetitle or request.cfg.sitename),
-            'print_mode': keywords.get('print_mode', False),
-            'media': keywords.get('media', 'screen'),
-        }),
-        keywords.get('html_head', ''),
-    ))
-
-    # Links
-    output.append('<link rel="Start" href="%s/%s">\n' % (scriptname, quoteWikinameURL(page_front_page)))
-    if pagename:
-        output.append('<link rel="Alternate" title="%s" href="%s/%s?action=raw">\n' % (
-            _('Wiki Markup'), scriptname, pagename_quoted,))
-        output.append('<link rel="Alternate" media="print" title="%s" href="%s/%s?action=print">\n' % (
-            _('Print View'), scriptname, pagename_quoted,))
-
-        # !!! currently disabled due to Mozilla link prefetching, see
-        # http://www.mozilla.org/projects/netlib/Link_Prefetching_FAQ.html
-        #~ all_pages = request.getPageList()
-        #~ if all_pages:
-        #~     try:
-        #~         pos = all_pages.index(pagename)
-        #~     except ValueError:
-        #~         # this shopuld never happend in theory, but let's be sure
-        #~         pass
-        #~     else:
-        #~         request.write('<link rel="First" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[0]))
-        #~         if pos > 0:
-        #~             request.write('<link rel="Previous" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[pos-1])))
-        #~         if pos+1 < len(all_pages):
-        #~             request.write('<link rel="Next" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[pos+1])))
-        #~         request.write('<link rel="Last" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[-1])))
-
-        if page_parent_page:
-            output.append('<link rel="Up" href="%s/%s">\n' % (scriptname, quoteWikinameURL(page_parent_page)))
-
-    # write buffer because we call AttachFile
-    request.write(''.join(output))
-    output = []
-
-    if pagename:
-        from MoinMoin.action import AttachFile
-        AttachFile.send_link_rel(request, pagename)
-
-    output.extend([
-        '<link rel="Search" href="%s/%s">\n' % (scriptname, quoteWikinameURL(page_find_page)),
-        '<link rel="Index" href="%s/%s">\n' % (scriptname, quoteWikinameURL(page_title_index)),
-        '<link rel="Glossary" href="%s/%s">\n' % (scriptname, quoteWikinameURL(page_word_index)),
-        '<link rel="Help" href="%s/%s">\n' % (scriptname, quoteWikinameURL(page_help_formatting)),
-                  ])
-    
-    output.append("</head>\n")
-    request.write(''.join(output))
-    output = []
-    request.flush()
-
-    # start the <body>
-    bodyattr = []
-    if keywords.has_key('body_attr'):
-        bodyattr.append(' ')
-        bodyattr.append(keywords['body_attr'])
-
-    # Add doubleclick edit action
-    if (pagename and keywords.get('allow_doubleclick', 0) and
-        not keywords.get('print_mode', 0) and
-        request.user.edit_on_doubleclick):
-        if request.user.may.write(pagename): # separating this gains speed
-            querystr = escape(makeQueryString({'action': 'edit'}))
-            # TODO: remove escape=0 in 2.0
-            url = page.url(request, querystr, escape=0)
-            bodyattr.append(''' ondblclick="location.href='%s'" ''' % url)
-
-    # Set body to the user interface language and direction
-    bodyattr.append(' %s' % request.theme.ui_lang_attr())
-    
-    body_onload = keywords.get('body_onload', '')
-    if body_onload:
-        bodyattr.append(''' onload="%s"''' % body_onload)
-    output.append('\n<body%s>\n' % ''.join(bodyattr))
-
-    # Output -----------------------------------------------------------
-
-    theme = request.theme
-    
-    # If in print mode, start page div and emit the title
-    if keywords.get('print_mode', 0):
-        d = {'title_text': text, 'title_link': None, 'page': page,}
-        request.themedict = d
-        output.append(theme.startPage())
-        output.append(theme.interwiki(d))      
-        output.append(theme.title(d))      
-
-    # In standard mode, emit theme.header
-    else:
-        # prepare dict for theme code:
-        d = {
-            'theme': theme.name,
-            'script_name': scriptname,
-            'title_text': text,
-            'title_link': keywords.get('link', ''),
-            'logo_string': request.cfg.logo_string,
-            'site_name': request.cfg.sitename,
-            'page': page,
-            'pagesize': pagename and page.size() or 0,
-            'last_edit_info': pagename and page.lastEditInfo() or '',
-            'page_name': pagename or '',
-            'page_find_page': page_find_page,
-            'page_front_page': page_front_page,
-            'home_page': home_page,
-            'page_help_contents': page_help_contents,
-            'page_help_formatting': page_help_formatting,
-            'page_parent_page': page_parent_page,
-            'page_title_index': page_title_index,
-            'page_word_index': page_word_index,
-            'page_user_prefs': page_user_prefs,
-            'user_name': request.user.name,
-            'user_valid': request.user.valid,
-            'user_prefs': (page_user_prefs, request.user.name)[request.user.valid],
-            'msg': keywords.get('msg', ''),
-            'trail': keywords.get('trail', None),
-            # Discontinued keys, keep for a while for 3rd party theme developers
-            'titlesearch': 'use self.searchform(d)',
-            'textsearch': 'use self.searchform(d)',
-            'navibar': ['use self.navibar(d)'],
-            'available_actions': ['use self.request.availableActions(page)'],
-        }
-
-        # add quoted versions of pagenames
-        newdict = {}
-        for key in d:
-            if key.startswith('page_'):
-                if not d[key] is None:
-                    newdict['q_'+key] = quoteWikinameURL(d[key])
-                else:
-                    newdict['q_'+key] = None
-        d.update(newdict)
-        request.themedict = d
-
-        # now call the theming code to do the rendering
-        if keywords.get('editor_mode', 0):
-            output.append(theme.editorheader(d))
-        else:
-            output.append(theme.header(d))
-    
-    # emit it
-    request.write(''.join(output))
-    output = []
-    request.flush()
-
-
-def send_footer(request, pagename, **keywords):
-    """
-    Output the page footer.
-
-    @param request: the request object
-    @param pagename: WikiName of the page
-    @keyword print_mode: true, when page is displayed in Print mode
-    """
-    d = request.themedict
-    theme = request.theme
-
-    # Emit end of page in print mode, or complete footer in standard mode
-    if keywords.get('print_mode', 0):
-        request.write(theme.pageinfo(d['page']))
-        request.write(theme.endPage())
-    else:
-        request.write(theme.footer(d, **keywords))
-
-    
 ########################################################################
 ### Tickets - used by RenamePage and DeletePage
 ########################################################################