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