site: Redo the menu generation.
[matthijs/projects/wipi.git] / plugin / theme / site.py
1 # -*- coding: iso-8859-1 -*-
2 """
3     MoinMoin - Generic website theme.
4
5     @copyright: 2009+ Matthijs Kooijman
6     @license: GNU GPL, see COPYING for details.
7
8     This theme is meant for wiki's that are meant to function as a website,
9     meaning nothing fancy and wiki-ish (at least when you're not logged in).
10
11     This theme is meant to be subclassed. Subclasses should at least define a
12     name, and possibly override other stuff.
13 """
14
15 from MoinMoin.theme import ThemeBase
16 from MoinMoin.Page import Page
17 from MoinMoin import wikiutil
18 from StringIO import StringIO
19
20 class SiteTheme(ThemeBase):
21
22     def editbar(self, d):
23         if self.request.user.valid:
24             return ThemeBase.editbar(self, d)
25         else:
26             return ''
27
28     def searchform(self, d):
29         if self.request.user.valid:
30             return ThemeBase.searchform(self, d)
31         else:
32             return ''
33     
34     def navibar(self, d):
35         if self.request.user.valid:
36             return ThemeBase.navibar(self, d)
37         else:
38             return ''
39
40     def header(self, d, **kw):
41         """ Assemble wiki header
42         
43         @param d: parameter dictionary
44         @rtype: unicode
45         @return: page header html
46         """
47         html = [
48             # Pre header custom html
49             self.emit_custom_html(self.cfg.page_header1),
50
51             # Header
52             u'<div id="header">',
53             self.logo(),
54             self.menu(d),
55             #self.username(d),
56             #u'<div id="locationline">',
57             #self.interwiki(d),
58             #self.title(d),
59             #u'</div>',
60             #self.navibar(d),
61             #u'<hr id="pageline">',
62             #u'<div id="pageline"><hr style="display:none;"></div>',
63             ##self.trail(d),
64             u'</div>',
65
66             # Post header custom html (not recommended)
67             self.emit_custom_html(self.cfg.page_header2),
68
69             self.msg(d),
70             self.editbar(d),
71
72             # Start of page
73             self.startPage(d),
74         ]
75         return u'\n'.join(html)
76
77     def editorheader(self, d, **kw):
78         """ Assemble wiki header for editor
79         
80         @param d: parameter dictionary
81         @rtype: unicode
82         @return: page header html
83         """
84         html = [
85             # Pre header custom html
86             self.emit_custom_html(self.cfg.page_header1),
87
88             # Header
89             u'<div id="header">',
90             self.logo(),
91             self.menu(d),
92             u'</div>',
93
94             # Post header custom html (not recommended)
95             self.emit_custom_html(self.cfg.page_header2),
96
97             # Start of page
98             self.startPage(d),
99             self.msg(d),
100         ]
101         return u'\n'.join(html)
102
103     def footer(self, d, **keywords):
104         """ Assemble wiki footer
105         
106         @param d: parameter dictionary
107         @keyword ...:...
108         @rtype: unicode
109         @return: page footer html
110         """
111         page = d['page']
112         html = [
113             # End of page
114             self.endPage(d),
115
116             # Pre footer custom html (not recommended!)
117             self.emit_custom_html(self.cfg.page_footer1),
118
119             # Footer
120             u'<div id="footer">',
121             self.username(d),
122             self.pageinfo(page),
123             self.searchform(d),
124             #self.editbar(d),
125             #self.credits(d),
126             #self.showversion(d, **keywords),
127             u'<div id="footerbottom"></div>',
128             u'</div>',
129
130             # Post footer custom html
131             self.emit_custom_html(self.cfg.page_footer2),
132             ]
133         return u'\n'.join(html)
134
135     def menu(self, d):
136         """ Assemble a "main" menu
137             
138             @param d: parameter dictionary
139             @rtype:   unicode
140             @return: menu html
141         """
142         menu = Page(self.request, 'Site/Menu')
143         return u'<div id="menubar">%s</div>' % parse_wiki_page(self.request, menu)
144
145     def theme_script(self, name):
146         """ Format script html from this theme's static dir """
147         src = '%s/%s/js/%s.js' % (self.request.cfg.url_prefix_static, self.name, name)
148         return '<script type="text/javascript" src="%s"></script>' % src
149
150     def pageinfo(self, page):
151         """ Output page name and "last modified". This overwrites the pageinfo
152         from ThemeBase to hide the username, which is useless and always
153         produces a link to the non-existing homepage of the last editor. """
154         _ = self.request.getText
155         html = ''
156         if self.shouldShowPageinfo(page):
157             info = page.lastEditInfo()
158             if info:
159                 info = _("last modified %(time)s") % info
160                 pagename = page.page_name
161                 info = "%s  (%s)" % (wikiutil.escape(pagename), info)
162                 html = '<p id="pageinfo" class="info"%(lang)s>%(info)s</p>\n' % {
163                     'lang': self.ui_lang_attr(),
164                     'info': info
165                     }
166         return html
167
168     def startPage(self, d):
169         # This opens up #page
170         html = ThemeBase.startPage(self)
171         html += u'<div id="pagetop"></div>\n'
172         html += u'<div id="pagemiddle">\n'
173         return html
174
175     def endPage(self, d):
176         html = u'</div><!-- #pagemiddle -->\n'
177         html += ThemeBase.endPage(self)
178         # This adds #pagebottom and closes #page
179         return html
180
181 def parse_wiki_page(request, page):
182     """
183     This is an ugly hack to render a page into a string. By default,
184     formatters render using request.write automatically, which prevents us
185     from capturing the output. By disguising a StringIO buffer as a request
186     object, we manage to get at the rendered contents.
187
188     However, when {{{#!wiki or similar blocks are used, stuff breaks (since
189     that creates a second parser that doesn't get our StringIO buffer).
190     """
191     Parser = wikiutil.searchAndImportPlugin(request.cfg, "parser", 'wiki')
192     # Create a stringIO buffer, to capture the output
193     buffer = StringIO()
194     # Make the buffer look like the request, since the parser writes
195     # directly to the request
196     buffer.form = request.form
197     buffer.getText = request.getText
198     buffer.cfg = request.cfg
199     # Create a new formatter. Since we need to set its page, we can't use
200     # request.formatter.
201     from MoinMoin.formatter.text_html import Formatter
202     formatter = Formatter(request)
203     formatter.setPage(page)
204
205     # Create the parser and parse the page
206     parser = Parser(page.data, buffer)
207     parser.format(formatter)
208     # Return the captured buffer
209     return buffer.getvalue()
210
211 # vim: set sw=4 sts=4 expandtab: