paul@0 | 1 | # -*- coding: iso-8859-1 -*- |
paul@0 | 2 | |
paul@0 | 3 | """ |
paul@0 | 4 | MoinMoin - MinimalMoin theme |
paul@0 | 5 | @copyright: 2009, 2010 Paul Boddie <paul@boddie.org.uk> |
paul@0 | 6 | @copyright: (portions) 2003-2008 MoinMoin:ThomasWaldmann, 2003-2005 Nir Soffer |
paul@0 | 7 | @license: GNU GPL (v2 or later), see COPYING.txt for details. |
paul@0 | 8 | """ |
paul@0 | 9 | |
paul@0 | 10 | from MoinMoin.theme import ThemeBase |
paul@0 | 11 | from MoinMoin import i18n |
paul@0 | 12 | from MoinMoin import wikiutil |
paul@0 | 13 | from MoinMoin import version |
paul@0 | 14 | from MoinMoin.Page import Page |
paul@0 | 15 | import re |
paul@0 | 16 | |
paul@0 | 17 | class Theme(ThemeBase): |
paul@0 | 18 | |
paul@0 | 19 | name = "minimalmoin" |
paul@0 | 20 | |
paul@0 | 21 | # Icon definitions from the modernized theme... |
paul@0 | 22 | |
paul@0 | 23 | _ = lambda x: x # We don't have gettext at this moment, so we fake it |
paul@0 | 24 | icons = { |
paul@0 | 25 | # key alt icon filename w h |
paul@0 | 26 | # FileAttach |
paul@0 | 27 | 'attach': ("%(attach_count)s", "moin-attach.png", 16, 16), |
paul@0 | 28 | 'info': ("[INFO]", "moin-info.png", 16, 16), |
paul@0 | 29 | 'attachimg': (_("[ATTACH]"), "attach.png", 32, 32), |
paul@0 | 30 | # RecentChanges |
paul@0 | 31 | 'rss': (_("[RSS]"), "moin-rss.png", 16, 16), |
paul@0 | 32 | 'deleted': (_("[DELETED]"), "moin-deleted.png", 16, 16), |
paul@0 | 33 | 'updated': (_("[UPDATED]"), "moin-updated.png", 16, 16), |
paul@0 | 34 | 'renamed': (_("[RENAMED]"), "moin-renamed.png", 16, 16), |
paul@0 | 35 | 'conflict': (_("[CONFLICT]"), "moin-conflict.png", 16, 16), |
paul@0 | 36 | 'new': (_("[NEW]"), "moin-new.png", 16, 16), |
paul@0 | 37 | 'diffrc': (_("[DIFF]"), "moin-diff.png", 16, 16), |
paul@0 | 38 | # General |
paul@0 | 39 | 'bottom': (_("[BOTTOM]"), "moin-bottom.png", 16, 16), |
paul@0 | 40 | 'top': (_("[TOP]"), "moin-top.png", 16, 16), |
paul@0 | 41 | 'www': ("[WWW]", "moin-www.png", 16, 16), |
paul@0 | 42 | 'mailto': ("[MAILTO]", "moin-email.png", 16, 16), |
paul@0 | 43 | 'news': ("[NEWS]", "moin-news.png", 16, 16), |
paul@0 | 44 | 'telnet': ("[TELNET]", "moin-telnet.png", 16, 16), |
paul@0 | 45 | 'ftp': ("[FTP]", "moin-ftp.png", 16, 16), |
paul@0 | 46 | 'file': ("[FILE]", "moin-ftp.png", 16, 16), |
paul@0 | 47 | # search forms |
paul@0 | 48 | 'searchbutton': ("[?]", "moin-search.png", 16, 16), |
paul@0 | 49 | 'interwiki': ("[%(wikitag)s]", "moin-inter.png", 16, 16), |
paul@0 | 50 | |
paul@0 | 51 | # smileys (this is CONTENT, but good looking smileys depend on looking |
paul@0 | 52 | # adapted to the theme background color and theme style in general) |
paul@0 | 53 | #vvv == vvv this must be the same for GUI editor converter |
paul@0 | 54 | 'X-(': ("X-(", 'angry.png', 16, 16), |
paul@0 | 55 | ':D': (":D", 'biggrin.png', 16, 16), |
paul@0 | 56 | '<:(': ("<:(", 'frown.png', 16, 16), |
paul@0 | 57 | ':o': (":o", 'redface.png', 16, 16), |
paul@0 | 58 | ':(': (":(", 'sad.png', 16, 16), |
paul@0 | 59 | ':)': (":)", 'smile.png', 16, 16), |
paul@0 | 60 | 'B)': ("B)", 'smile2.png', 16, 16), |
paul@0 | 61 | ':))': (":))", 'smile3.png', 16, 16), |
paul@0 | 62 | ';)': (";)", 'smile4.png', 16, 16), |
paul@0 | 63 | '/!\\': ("/!\\", 'alert.png', 16, 16), |
paul@0 | 64 | '<!>': ("<!>", 'attention.png', 16, 16), |
paul@0 | 65 | '(!)': ("(!)", 'idea.png', 16, 16), |
paul@0 | 66 | ':-?': (":-?", 'tongue.png', 16, 16), |
paul@0 | 67 | ':\\': (":\\", 'ohwell.png', 16, 16), |
paul@0 | 68 | '>:>': (">:>", 'devil.png', 16, 16), |
paul@0 | 69 | '|)': ("|)", 'tired.png', 16, 16), |
paul@0 | 70 | ':-(': (":-(", 'sad.png', 16, 16), |
paul@0 | 71 | ':-)': (":-)", 'smile.png', 16, 16), |
paul@0 | 72 | 'B-)': ("B-)", 'smile2.png', 16, 16), |
paul@0 | 73 | ':-))': (":-))", 'smile3.png', 16, 16), |
paul@0 | 74 | ';-)': (";-)", 'smile4.png', 16, 16), |
paul@0 | 75 | '|-)': ("|-)", 'tired.png', 16, 16), |
paul@0 | 76 | '(./)': ("(./)", 'checkmark.png', 16, 16), |
paul@0 | 77 | '{OK}': ("{OK}", 'thumbs-up.png', 16, 16), |
paul@0 | 78 | '{X}': ("{X}", 'icon-error.png', 16, 16), |
paul@0 | 79 | '{i}': ("{i}", 'icon-info.png', 16, 16), |
paul@0 | 80 | '{1}': ("{1}", 'prio1.png', 15, 13), |
paul@0 | 81 | '{2}': ("{2}", 'prio2.png', 15, 13), |
paul@0 | 82 | '{3}': ("{3}", 'prio3.png', 15, 13), |
paul@0 | 83 | '{*}': ("{*}", 'star_on.png', 16, 16), |
paul@0 | 84 | '{o}': ("{o}", 'star_off.png', 16, 16), |
paul@0 | 85 | } |
paul@0 | 86 | del _ |
paul@0 | 87 | |
paul@5 | 88 | stylesheets = ( |
paul@5 | 89 | # media basename |
paul@5 | 90 | ('all', 'combined'), |
paul@5 | 91 | ) |
paul@5 | 92 | |
paul@0 | 93 | def header(self, d, **kw): |
paul@0 | 94 | """ Assemble page header |
paul@0 | 95 | |
paul@0 | 96 | @param d: parameter dictionary |
paul@0 | 97 | @rtype: unicode |
paul@0 | 98 | @return: page header html |
paul@0 | 99 | """ |
paul@0 | 100 | |
paul@0 | 101 | request = self.request |
paul@0 | 102 | fmt = request.formatter |
paul@0 | 103 | html = [] |
paul@0 | 104 | |
paul@0 | 105 | # NOTE: Some pages cause section numbers to be enabled, affecting the |
paul@0 | 106 | # NOTE: theme. |
paul@0 | 107 | |
paul@0 | 108 | show_section_numbers = fmt._show_section_numbers |
paul@0 | 109 | fmt._show_section_numbers = 0 |
paul@0 | 110 | |
paul@0 | 111 | # The header section. |
paul@0 | 112 | |
paul@0 | 113 | html.append(fmt.div(on=1, attr={"id" : "header"})) |
paul@0 | 114 | |
paul@0 | 115 | html.append(self.title(d)) |
paul@0 | 116 | html.append(self.about(d)) |
paul@2 | 117 | html.append(self.mainpages(d)) |
paul@0 | 118 | |
paul@0 | 119 | html.append(fmt.div(on=0)) |
paul@0 | 120 | |
paul@0 | 121 | # Show any pertinent message. |
paul@0 | 122 | |
paul@0 | 123 | html.append(self.msg(d)) |
paul@0 | 124 | |
paul@0 | 125 | # Complete the header. |
paul@0 | 126 | |
paul@0 | 127 | html.append(self.startPage()) |
paul@0 | 128 | |
paul@0 | 129 | # NOTE: Some pages cause section numbers to be enabled, affecting the |
paul@0 | 130 | # NOTE: theme. |
paul@0 | 131 | |
paul@0 | 132 | fmt._show_section_numbers = show_section_numbers |
paul@0 | 133 | |
paul@0 | 134 | return u''.join(html) |
paul@0 | 135 | |
paul@0 | 136 | editorheader = header |
paul@0 | 137 | |
paul@0 | 138 | def footer(self, d, **kw): |
paul@0 | 139 | """ Assemble page footer |
paul@0 | 140 | |
paul@0 | 141 | @param d: parameter dictionary |
paul@0 | 142 | @rtype: unicode |
paul@0 | 143 | @return: page footer html |
paul@0 | 144 | """ |
paul@0 | 145 | |
paul@0 | 146 | request = self.request |
paul@0 | 147 | fmt = request.formatter |
paul@0 | 148 | _ = request.getText |
paul@2 | 149 | page = d["page"] |
paul@0 | 150 | html = [] |
paul@0 | 151 | |
paul@0 | 152 | # NOTE: Some pages cause section numbers to be enabled, affecting the |
paul@0 | 153 | # NOTE: theme. |
paul@0 | 154 | |
paul@0 | 155 | show_section_numbers = fmt._show_section_numbers |
paul@0 | 156 | fmt._show_section_numbers = 0 |
paul@0 | 157 | |
paul@0 | 158 | # End the page. |
paul@0 | 159 | |
paul@0 | 160 | html.append(self.endPage()) |
paul@0 | 161 | |
paul@0 | 162 | # The footer section. |
paul@0 | 163 | |
paul@0 | 164 | html.append(fmt.div(on=1, attr={"id" : "footer"})) |
paul@0 | 165 | |
paul@2 | 166 | if self.shouldShowEditbar(page): |
paul@2 | 167 | html.append(self.menuholder(d, {"class" : "editing"}, _("Editing options"), self.editbar)) |
paul@2 | 168 | html.append(self.menuholder(d, {"id" : "navigation"}, _("Useful pages"), self.navibar)) |
paul@2 | 169 | html.append(self.menuholder(d, {"id" : "identity"}, _("User information"), self.username)) |
paul@0 | 170 | |
paul@0 | 171 | #html.append(self.trail(d)) |
paul@0 | 172 | |
paul@0 | 173 | html.append(fmt.div(on=0)) |
paul@0 | 174 | |
paul@0 | 175 | # NOTE: Some pages cause section numbers to be enabled, affecting the |
paul@0 | 176 | # NOTE: theme. |
paul@0 | 177 | |
paul@0 | 178 | fmt._show_section_numbers = show_section_numbers |
paul@0 | 179 | |
paul@0 | 180 | return u''.join(html) |
paul@0 | 181 | |
paul@2 | 182 | def mainpages(self, d, **kw): |
paul@2 | 183 | """ Link to the front page and potentially other pages. |
paul@2 | 184 | |
paul@2 | 185 | @param d: parameter dictionary |
paul@2 | 186 | @rtype: unicode |
paul@2 | 187 | @return: front page link html |
paul@2 | 188 | """ |
paul@2 | 189 | |
paul@2 | 190 | request = self.request |
paul@2 | 191 | fmt = request.formatter |
paul@2 | 192 | _ = request.getText |
paul@2 | 193 | html = [] |
paul@2 | 194 | |
paul@2 | 195 | page = wikiutil.getFrontPage(self.request) |
paul@2 | 196 | |
paul@2 | 197 | html.append(fmt.bullet_list(on=1, attr={"id" : "mainpages"})) |
paul@2 | 198 | html.append(fmt.listitem(on=1)) |
paul@2 | 199 | html.append(page.link_to(request, text=_("Front page"), rel='nofollow')) |
paul@2 | 200 | html.append(fmt.listitem(on=0)) |
paul@2 | 201 | html.append(fmt.bullet_list(on=0)) |
paul@2 | 202 | |
paul@2 | 203 | return u''.join(html) |
paul@2 | 204 | |
paul@0 | 205 | def about(self, d, **kw): |
paul@0 | 206 | """ Link to the controls in the footer. |
paul@0 | 207 | |
paul@0 | 208 | @param d: parameter dictionary |
paul@0 | 209 | @rtype: unicode |
paul@0 | 210 | @return: about link html |
paul@0 | 211 | """ |
paul@0 | 212 | |
paul@0 | 213 | request = self.request |
paul@0 | 214 | fmt = request.formatter |
paul@0 | 215 | _ = request.getText |
paul@0 | 216 | html = [] |
paul@0 | 217 | |
paul@0 | 218 | html.append(fmt.bullet_list(on=1, attr={"id" : "pageabout"})) |
paul@0 | 219 | html.append(fmt.listitem(on=1)) |
paul@0 | 220 | |
paul@0 | 221 | html.append(fmt.anchorlink(on=1, name="footer")) |
paul@0 | 222 | html.append(fmt.text(_("About this page"))) |
paul@0 | 223 | html.append(fmt.anchorlink(on=0)) |
paul@0 | 224 | |
paul@0 | 225 | html.append(fmt.listitem(on=0)) |
paul@0 | 226 | html.append(fmt.bullet_list(on=0)) |
paul@0 | 227 | |
paul@0 | 228 | return u''.join(html) |
paul@0 | 229 | |
paul@2 | 230 | def menuholder(self, d, menu_attr, menu_title, menu_fn): |
paul@2 | 231 | """ Wrap controls in a menu container. |
paul@2 | 232 | |
paul@2 | 233 | @param d: parameter dictionary |
paul@2 | 234 | @param menu_attr: menu container element attributes |
paul@2 | 235 | @param menu_title: the menu label text |
paul@2 | 236 | @param menu_fn: the function or method producing the controls |
paul@2 | 237 | @rtype: unicode |
paul@2 | 238 | @return: menu container html |
paul@2 | 239 | """ |
paul@2 | 240 | |
paul@2 | 241 | request = self.request |
paul@2 | 242 | fmt = request.formatter |
paul@2 | 243 | html = [] |
paul@2 | 244 | |
paul@2 | 245 | html.append(fmt.div(on=1, attr=menu_attr)) |
paul@2 | 246 | html.append(fmt.span(on=1, attr={"class" : "menutitleholder"})) |
paul@2 | 247 | html.append(fmt.span(on=1, attr={"class" : "menutitle"})) |
paul@2 | 248 | html.append(fmt.text(menu_title)) |
paul@2 | 249 | html.append(fmt.span(on=0)) |
paul@2 | 250 | html.append(menu_fn(d)) |
paul@2 | 251 | html.append(fmt.span(on=0)) |
paul@2 | 252 | html.append(fmt.div(on=0)) |
paul@2 | 253 | |
paul@2 | 254 | return u''.join(html) |
paul@2 | 255 | |
paul@0 | 256 | # Theme instantiation. |
paul@0 | 257 | |
paul@0 | 258 | def execute(request): |
paul@0 | 259 | """ |
paul@0 | 260 | Generate and return a theme object |
paul@0 | 261 | |
paul@0 | 262 | @param request: the request object |
paul@0 | 263 | @rtype: MoinTheme |
paul@0 | 264 | @return: Theme object |
paul@0 | 265 | """ |
paul@0 | 266 | return Theme(request) |
paul@0 | 267 | |
paul@0 | 268 | # vim: tabstop=4 expandtab shiftwidth=4 |