1 """MoinMoin theme "err404" by Boris Ganne.
   2 Inspired by MoinMoin theme "Mandarin" by Radomir Dopieralski. (SideBar)
   3 Inspired by MoinMoin theme "sinorca4moin" by David Linke.
   4 
   5 MoinMoin theme "sinorca4moin" by David Linke.
   6 See MoinMoin:DavidLinke/Sinorca4Moin for more infos.
   7 
   8 Version 0.5b   : changing css a bit (also made css2.1. compatible) and 
   9                  updating the theme for MoinMoin Version 1.8 
  10                  Attention: this is not an official release, more a
  11                  personal update (Marcel Haefner)!
  12 Version 0.5    : Version adjusted for moin-1.6.x (2007-12-29)
  13 Version 0.4    : Extended version adjusted for moin-1.5.x (2006-08-13)
  14 Version 0.1-0.3: Initial version for moin-1.3.x (2005)
  15 
  16 Inspired by Haran's sinorca-design published at www.oswd.org.
  17 
  18 $Id: sinorca4moin.py 159 2007-12-29 21:43:07Z linke $
  19 """
  20 
  21 import os
  22 from MoinMoin.theme import ThemeBase
  23 from MoinMoin.Page import Page
  24 from MoinMoin.config.multiconfig import _url_re_list, _makeConfig, _getConfigName
  25 from MoinMoin import wikiutil, error
  26 
  27 class Theme(ThemeBase):
  28 
  29     name = "err404"
  30 
  31     def farmWikiList(self):
  32         """Generate list of links pointing to the wikis of the farm
  33 
  34         Fore each Subwiki a link to Frontpage and RecentChanges (image) is
  35         created. If interwiki_preferred is specified in the farmconfig the
  36         links will be created only for these wikis else links to all wikis
  37         in farmconfig.wiki will be created.
  38         """
  39         _ = self.request.getText
  40         farmwikis =  [wiki_name for wiki_name, reg in _url_re_list()]
  41         if self.request.cfg.interwiki_preferred:
  42             wikis = self.request.cfg.interwiki_preferred
  43             # remove everything that is not a wiki of the farm
  44             wikis = [w for w in wikis if w in farmwikis]
  45         else:
  46             wikis = farmwikis
  47 
  48         if len(wikis) < 2: return []  # creating links is useless for one wiki
  49 
  50         linkList = []
  51         for wiki_name in wikis:
  52             cfg = _makeConfig(wiki_name)
  53             highlight = u''
  54             if wiki_name == _getConfigName(self.request.url):
  55                 highlight = u' class="highlight"'
  56             try:
  57                 interwiki_list = wikiutil.load_wikimap(self.request)
  58                 wiki_url = interwiki_list[cfg.interwikiname]
  59                 rc = _("RecentChanges", formatted=False)
  60                 linkList.append( ''.join([
  61                     u' <a title="%s" href="%s"%s>%s</a>' %
  62                         (cfg.sitename, wiki_url, highlight, cfg.interwikiname),
  63                     u'<a title="%s" href="%s%s">' %
  64                         (rc, wiki_url, wikiutil.quoteWikinameURL(rc)),
  65                     u'<img src="%s/sinorca4moin/img/moin-diff.png" alt="%s"' %
  66                             (cfg.url_prefix_static, rc),
  67                     u' height="11" width="15"></a>'
  68                     ]))
  69             except KeyError: # probably no interwikiname in config
  70                 msg = """
  71 Missing the wiki '%s' in the interwiki list.
  72 
  73 Please add the interwiki-name and the url of this wiki to 'intermap.txt'.
  74 """%wiki_name
  75                 #raise error.ConfigurationError(msg)
  76                 pass
  77         return linkList
  78 
  79     def subheader(self):
  80         """Make subheader
  81 
  82         Links to subwikis if it's a farm else uses page_header2.
  83         """
  84         linkList = self.farmWikiList()
  85         if len(linkList) > 1:
  86             subheader = ' |\n'.join(linkList)
  87         else:
  88             subheader = self.request.cfg.page_header2
  89         return '\n'.join([
  90             u'<div class="subHeader">',
  91             subheader,
  92             u'</div>',
  93             ])
  94 
  95     def title(self, d):
  96         """ Assemble the title (not as html list as in standard method!)
  97 
  98         Code copied from title-method in __init__.py
  99         Only one line was changed.
 100 
 101         @param d: parameter dictionary
 102         @rtype: string
 103         @return: title html
 104         """
 105         _ = self.request.getText
 106         content = []
 107         if d['title_text'] == d['page'].split_title(): # just showing a page,
 108             curpage = ''                               # no action
 109             segments = d['page_name'].split('/') # was: title_text
 110             for s in segments[:-1]:
 111                 curpage += s
 112                 # next line is modified compared to method in _init__.py
 113                 content.append("%s&nbsp;/ " % Page(self.request,
 114                     curpage).link_to(self.request, s))
 115                 curpage += '/'
 116             link_text = segments[-1]
 117             link_title = _('Click to do a full-text search for this title',
 118                            formatted=False)
 119             link_query = {
 120                 'action': 'fullsearch',
 121                 'value': 'linkto:"%s"' % d['page_name'],
 122                 'context': '180',
 123             }
 124             # we dont use d['title_link'] any more, but make it ourselves:
 125             link = d['page'].link_to(self.request, link_text,
 126                                      querystr=link_query,
 127                                      title=link_title, css_class='backlink',
 128                                      rel='nofollow')
 129             content.append(('<li>%s</li>') % link)
 130         else:
 131             content.append('<li>%s</li>' % wikiutil.escape(d['title_text']))
 132 
 133         html = '''
 134 <ul id="pagelocation">
 135 %s
 136 </ul>
 137 ''' % "".join(content)
 138         return html
 139 
 140     def iconbar(self, d):
 141         """
 142         Assemble the iconbar
 143         
 144         @param d: parameter dictionary
 145         @rtype: string
 146         @return: iconbar html
 147         """
 148         iconbar = []
 149         if self.cfg.page_iconbar and self.request.user.show_toolbar and d['page_name']:
 150             iconbar.append('<ul id="iconbar">\n')
 151             icons = self.cfg.page_iconbar[:]
 152             for icon in icons:
 153                 if icon == "up":
 154                     if d['page_parent_page']:
 155                         iconbar.append('<li>%s</li>\n' % self.make_iconlink(icon, d))
 156                 elif icon == "subscribe" and self.cfg.mail_enabled:
 157                     iconbar.append('<li>%s</li>\n' % self.make_iconlink(
 158                         ["subscribe", "unsubscribe"][self.request.user.isSubscribedTo([d['page_name']])], d))
 159                 else:
 160                     iconbar.append('<li>%s</li>\n' % self.make_iconlink(icon, d))
 161             iconbar.append('</ul>\n')
 162         return ''.join(iconbar)
 163 
 164     def wikipanel(self, d):
 165         """ Create wiki panel """
 166         _ = self.request.getText
 167         html = [
 168             u'<div class="sidepanel">',
 169             u'<h1>%s</h1>' % _("Wiki"),
 170             self.navibar(d),
 171             u'</div>',
 172             ]
 173         return u'\n'.join(html)
 174 
 175     def pagepanel(self, d):
 176         """ Create page panel """
 177         _ = self.request.getText
 178         if self.shouldShowEditbar(d['page']):
 179             html = [
 180                 u'<div class="sidepanel">',
 181                 u'<h1>%s</h1>' % _("Page"),
 182                 self.editbar(d),
 183                 u'</div>',
 184                 ]
 185             return u'\n'.join(html)
 186         return ''
 187 
 188     def userpanel(self, d):
 189         """ Create user panel """
 190         _ = self.request.getText
 191 
 192         html = [
 193             u'<div class="sidepanel">',
 194             u'<h1>%s</h1>' %  _("User"),
 195             self.username(d),
 196             u'</div>'
 197             ]
 198         return u'\n'.join(html)
 199 
 200     def linkedSitename(self):
 201         """Create title from sitename and link to FrontPage"""
 202         frontpage = wikiutil.getFrontPage(self.request).page_name
 203         html = wikiutil.link_tag(self.request,
 204                                  wikiutil.quoteWikinameURL(frontpage),
 205                                  self.request.cfg.sitename)
 206         return html
 207 
 208     def flexible_userhome(self, d):
 209         """Determine content in superheader and sidebar based on page_header1
 210         """
 211         if self.cfg.page_header1:
 212             superheader = self.cfg.page_header1
 213             userpanel = self.userpanel(d)
 214         else:
 215             #superheader = self.username(d)
 216             superheader = '\n'.join([
 217                 u'  <div class="right">',
 218                 self.username(d),
 219                 u'  </div>',
 220                 ])
 221             userpanel = ''
 222         return superheader, userpanel
 223 
 224     def shortenPagename(self, name):
 225         """ Shorten page names (overrides default method)
 226 
 227         changed compared to default: for hierarchical names a part of
 228         the first level is always shown.
 229 
 230         @param name: page name, unicode
 231         @rtype: unicode
 232         @return: shortened version of page name
 233         """
 234         l1Length = 8   # length to which level1 of page name will be truncated
 235         maxLength = self.maxPagenameLength()
 236         if len(name) > maxLength:
 237             half, left = divmod(maxLength, 2)
 238             name = name.split('/')
 239             parts = len(name)
 240             # select separator based on number of levels
 241             if parts > 2:
 242                 nameStart, nameEnd = name[0], name[-1]
 243                 if (len(nameStart) + len(nameEnd) > maxLength-4
 244                     and len(nameStart) > l1Length):
 245                     # cut from start
 246                     if len(nameEnd) > maxLength-6-l1Length:
 247                         name = u'%s../../%s..' % (nameStart[:l1Length],
 248                                 nameEnd[:maxLength-8-l1Length])
 249                     else:
 250                         lenStart = max(maxLength-len(nameEnd)-6, l1Length)
 251                         name = u'%s../../%s' % (nameStart[:lenStart],
 252                                 nameEnd[:maxLength-6-lenStart])
 253                 elif len(nameStart) + len(nameEnd) > maxLength-4:
 254                     # cut form end only
 255                     name = u'%s/../%s..' % (nameStart,
 256                             nameEnd[:maxLength-6-len(nameStart)])
 257                 else:
 258                     name = u'%s/../%s' % (nameStart, nameEnd)
 259             elif parts == 2:
 260                 nameStart, nameEnd = name[0], name[-1]
 261                 if (len(nameStart) + len(nameEnd) > maxLength-1
 262                     and len(nameStart) > l1Length):
 263                     # cut from start
 264                     if len(nameEnd) > maxLength-3-l1Length:
 265                         name = u'%s../%s..' % (nameStart[:l1Length],
 266                                 nameEnd[:maxLength-5-l1Length])
 267                     else:
 268                         lenStart = max(maxLength-len(nameEnd)-3, l1Length)
 269                         name = u'%s../%s' % (nameStart[:lenStart],
 270                                 nameEnd[:maxLength-3-lenStart])
 271                 elif len(nameStart) + len(nameEnd) > maxLength-1:
 272                     # cut from end only
 273                     name = u'%s/%s..' % (nameStart,
 274                             nameEnd[:maxLength-3-len(nameStart)])
 275                 else:
 276                     name = u'%s/%s' % (nameStart, nameEnd)
 277             else:
 278                 # simply replace middle with '...' for long pagenames
 279                 half, left = divmod(maxLength-3, 2)
 280                 name = name[0]
 281                 name = u'%s...%s' % (name[:half + left], name[-half:])
 282         return name
 283 # viens de mandarin.py
 284     def sidebar(self, d, **keywords):
 285         """ Display page called SideBar as an additional element on every page
 286 
 287         @param d: parameter dictionary
 288         @rtype: string
 289         @return: sidebar html
 290         """
 291         request = self.request
 292         _ = self.request.getText
 293         sidebar = request.getPragma('sidebar') or u'SideBar';
 294         page = Page(request, sidebar)
 295         if not page.exists():
 296             return u""
 297         import StringIO
 298         buff = StringIO.StringIO()
 299         request.redirect(buff)
 300         try:
 301             try:
 302                 page.send_page(content_only=1, content_id="sidebar")
 303             except TypeError:
 304                 page.send_page(request, content_only=1, content_id="sidebar")
 305         finally:
 306             request.redirect()
 307 #        return u'<div class="sidebar">%s</div>' % buff.getvalue()
 308         return u'<div class="sidepanel">%s</div>' % buff.getvalue()        
 309 
 310 
 311 
 312     def header(self, d):
 313         """
 314         Assemble page header
 315 
 316         @param d: parameter dictionary
 317         @rtype: string
 318         @return: page header html
 319         """
 320         _ = self.request.getText
 321 
 322         superheader, userpanel = self.flexible_userhome(d)
 323 
 324         html = [
 325             # Header
 326             u'<div id="header" class="header">',
 327 
 328             # super-header
 329             u' <div class="superHeader">',
 330             superheader,
 331             u' </div>',
 332             self.searchform(d),
 333 
 334             # middle header
 335             u' <div class="midHeader">',
 336             u'  <div id="locationline">',
 337             self.logo(),
 338             #self.interwiki(d), # makes no sense in this theme
 339             self.linkedSitename(),
 340             u'  </div>',
 341             u' </div>',
 342 
 343             # we display all wikis of the farm as links in one line
 344             # err404: annulation de l'affichage
 345             #self.emit_custom_html(self.subheader()),
 346 
 347             # Custom html below header (not recomended!)
 348             #self.emit_custom_html(self.cfg.page_header2),
 349 
 350             self.trail(d),
 351             u'</div>',
 352 
 353             # Sidebar
 354             #u'<div id="sidebar" class="sidebar">',
 355             u'<div class="sidebar">',
 356             self.wikipanel(d),
 357             self.pagepanel(d),
 358 # ajout de sidebar:
 359             self.sidebar(d),
 360 
 361             userpanel,
 362             u'</div>',
 363 
 364             self.msg(d),
 365 
 366             # Page
 367             self.startPage(),
 368 
 369             # Iconbar
 370             self.iconbar(d),
 371 
 372             self.title(d),
 373             ]
 374         return u'\n'.join(html)
 375 
 376     def editorheader(self, d):
 377         """
 378         Assemble page header for editor
 379 
 380         @param d: parameter dictionary
 381         @rtype: unicode
 382         @return: page header html
 383         """
 384         _ = self.request.getText
 385         superheader, userpanel = self.flexible_userhome(d)
 386 
 387         html = [
 388             # Header
 389             u' <div id="header" class="header">',
 390 
 391             # super-header
 392             u' <div class="superHeader">',
 393             superheader,
 394             u' </div>',
 395 
 396             # middle header
 397             u' <div class="midHeader">',
 398             self.searchform(d),
 399             u'  <div id="locationline">',
 400             self.logo(),
 401             #self.interwiki(d), # makes no sense in this theme
 402             self.linkedSitename(),
 403             u'  </div>',
 404             u' </div>',
 405 
 406             # we display all wikis of the farm as links in one line
 407             # err404: annulation de l'affichage
 408 #            self.emit_custom_html(self.subheader()),
 409             u'</div>',
 410 
 411             # Sidebar
 412             #u'<div id="sidebar" class="sidebar">',
 413             u'<div class="sidebar">',
 414             self.wikipanel(d),
 415             self.pagepanel(d),
 416 # ajout de sidebar:
 417             self.sidebar(d),            
 418             
 419             userpanel,
 420             u'</div>',
 421 
 422             self.msg(d),
 423 
 424             # Page
 425             self.startPage(),
 426             ]
 427         return u'\n'.join(html)
 428 
 429     def footer(self, d, **keywords):
 430         """ Assemble page footer
 431 
 432         @param d: parameter dictionary
 433         @keyword ...:...
 434         @rtype: unicode
 435         @return: page footer html
 436         """
 437         page = d['page']
 438         html = [
 439             # End of page
 440 #?            # Used to extend the page to the bottom of the sidebar
 441 #?            u'<div id="pagebottom"></div>',
 442             self.pageinfo(page),
 443             self.endPage(),
 444 
 445             # Pre footer custom html (not recommended!)
 446             #self.emit_custom_html(self.cfg.page_footer1),
 447 
 448             # Footer
 449             u'<div id="footer">',
 450             self.credits(d),
 451             self.showversion(d, **keywords),
 452             u'</div>',
 453 
 454             # Post footer custom html
 455             #self.emit_custom_html(self.cfg.page_footer2),
 456             ]
 457         return u'\n'.join(html)
 458 
 459     def splitNavilink_off(self, text, localize=1):
 460         """ Split navibar links into pagename, link to page
 461 
 462         This overrides the defaut method. In contrast to default quicklinks
 463         are cut down to a maximum length
 464 
 465         @param text: the text used in config or user preferences
 466         @rtype: tuple
 467         @return: pagename or url, link to page or url
 468         """
 469         request = self.request
 470 
 471         # Handle [pagename title] or [url title] formats
 472         if text.startswith('[') and text.endswith(']'):
 473             try:
 474                 pagename, title = text[1:-1].strip().split(' ', 1)
 475                 title = title.strip()
 476                 localize = 0
 477             except (ValueError, TypeError):
 478                 # Just use the text as is.
 479                 pagename = title = text
 480 
 481         # Handle regular pagename like "FrontPage"
 482         else:
 483             # Use localized pages for the current user
 484             if localize:
 485                 page = wikiutil.getLocalizedPage(request, text)
 486             else:
 487                 page = Page(request, text)
 488             pagename = page.page_name
 489             title = page.split_title(request)
 490             title = self.shortenPagename(title)
 491             link = page.link_to(request, title)
 492 
 493 
 494         from MoinMoin import config
 495         for scheme in self.linkSchemas:
 496             if pagename.startswith(scheme):
 497                 title = self.shortenPagename(wikiutil.escape(title))  # DL change
 498                 link = '<a href="%s">%s</a>' % (pagename, title)
 499                 return pagename, link
 500 
 501         # remove wiki: url prefix
 502         if pagename.startswith("wiki:"):
 503             pagename = pagename[5:]
 504 
 505         # try handling interwiki links
 506         try:
 507             interwiki, page = pagename.split(':', 1)
 508             thiswiki = request.cfg.interwikiname
 509             if interwiki == thiswiki:
 510                 pagename = page
 511                 title = self.shortenPagename(page)  # DL change
 512             else:
 513                 return (pagename,
 514                         self.request.formatter.interwikilink(True, interwiki, page) +
 515                         page +
 516                         self.request.formatter.interwikilink(False, interwiki, page)
 517                         )
 518 
 519         except ValueError:
 520             pass
 521 
 522         # Normalize page names, replace '_' with ' '. Usually
 523         # all names use spaces internally, but for
 524         # [name_with_spaces label] we must save the underscores
 525         # until this point.
 526         pagename = request.normalizePagename(pagename)
 527         link = Page(request, pagename).link_to(request, title)
 528 
 529         return pagename, link
 530 
 531 def execute(request):
 532     """ Generate and return a theme object
 533 
 534     @param request: the request object
 535     @rtype: MoinTheme
 536     @return: Theme object
 537     """
 538     return Theme(request)
 539 

Err404Wiki: Doc/Wiki/MoinMoin/Contrib/CssInWikiPage/err404.py (last edited 2009-12-04 22:30:42 by Err404)