# -*- coding: iso-8859-1 -*-
"""
MoinMoin tagol theme (bassed on classic theme by Thomas Waldmann)
@copyright: 2004 by NiklasGidion (niklas.gidion@web.de)
@license: GNU GPL, see COPYING for details.
"""
import urllib, re
from MoinMoin import config, i18n, wikiutil, version
from MoinMoin.Page import Page
class Theme:
""" here are the functions generating the html responsible for
the look and feel of your wiki site
"""
name = "tagol"
icons = {
# key alt icon filename w h
# ------------------------------------------------------------------
# navibar
#'help': ("%(page_help_contents)s", "moin-help.png", 22, 22),
#'find': ("%(page_find_page)s", "moin-search-big.png", 22, 22),
#'diff': ("Diffs", "moin-diff.png", 25, 22),
#'info': ("Info", "moin-info.png", 22, 22),
#'edit': ("Edit", "moin-edit.png", 22, 22),
#'unsubscribe':("Unsubscribe", "moin-unsubscribe.png", 22, 22),
#'subscribe': ("Subscribe", "moin-subscribe.png",22, 22),
#'raw': ("Raw", "moin-raw.png", 22, 22),
#'xml': ("XML", "moin-xml2.png", 36, 14),
#'print': ("Print", "moin-print.png", 22, 22),
#'view': ("View", "moin-show.png", 22, 22),
#'home': ("Home", "moin-home.png", 22, 22),
#'up': ("Up", "moin-parent.png", 22, 22),
# FileAttach (is this used?)
'attach': ("%(attach_count)s", "moin-attach.png", 22, 22),
# RecentChanges
'rss': ("[RSS]", "moin-rss.png", 36, 14),
'deleted': ("[DELETED]", "moin-deleted.png",22, 22),
'updated': ("[UPDATED]", "moin-updated.png",25, 22),
'new': ("[NEW]", "moin-new.png", 22, 22),
'diffrc': ("[DIFF]", "moin-diff.png", 25, 22),
# General
'bottom': ("[BOTTOM]", "moin-bottom.png", 14, 10),
'top': ("[TOP]", "moin-top.png", 14, 10),
'www': ("[WWW]", "moin-www.png", 16, 16),
'mailto': ("[MAILTO]", "moin-email.png", 16, 16),
'news': ("[NEWS]", "moin-news.png", 10, 11),
'telnet': ("[TELNET]", "moin-telnet.png", 10, 11),
'ftp': ("[FTP]", "moin-ftp.png", 11, 11),
'file': ("[FILE]", "moin-ftp.png", 11, 11),
# search forms
#'searchbutton': ("[?]", "moin-search.png", 12, 12),
'interwiki': ("[%(wikitag)s]", "moin-inter.png", 15, 15),
}
# ??? Why do we need stylesheet_print? the standard stylesheets
# provide a print version?
stylesheets_print = (
# theme charset media basename
(name, 'iso-8859-1', 'all', 'common'),
(name, 'iso-8859-1', 'all', 'print'),
)
stylesheets = (
# theme charset media basename
(name, 'iso-8859-1', 'all', 'common'),
(name, 'iso-8859-1', 'screen', 'screen'),
(name, 'iso-8859-1', 'print', 'print'),
)
def __init__(self, request):
"""
Initialize the theme object.
@param request: the request object
"""
self.request = request
def img_url(self, img):
"""
generate an img url
@param img: the image filename
@rtype: string
@return: the image url
"""
return "%s/%s/img/%s" % (config.url_prefix, self.name, img)
def css_url(self, basename, theme = None):
"""
generate the css url
@param basename: the css media type (base filename w/o .css)
@param theme: theme name
@rtype: string
@return: the css url
"""
if not theme:
theme = self.name
return "%s/%s/css/%s.css" % (config.url_prefix, theme, basename)
def emit_custom_html(self, html):
"""
generate custom HTML code in `html`
@param html: a string or a callable object, in which case
it is called and its return value is used
@rtype: string
@return: string with html
"""
if html:
if callable(html): html = html(self.request)
return html
# Header stuff #######################################################
def logo(self, d):
"""
Assemble the logo
@param d: parameter dictionary
@rtype: string
@return: logo html
"""
html = ''
# insert Header tag #######
html += '
'
#
if d['logo_string']:
html += '
%s
' % wikiutil.link_tag(
self.request, wikiutil.quoteWikiname(d['page_front_page']), d['logo_string'])
else:
html += ''
return html
def title(self, d):
"""
Assemble the title
@param d: parameter dictionary
@rtype: string
@return: title html
"""
_ = self.request.getText
html = ['
')
return ''.join(html)
def username(self, d):
"""
Assemble the username / userprefs link
@param d: parameter dictionary
@rtype: string
@return: username html
"""
_ = self.request.getText
html = '
\n'
html += ('%s: \n' % _("User"))
html += '%s
\n' % wikiutil.link_tag(
self.request, wikiutil.quoteWikiname(d['page_user_prefs']),
wikiutil.escape(d['user_prefs']))
return html
def navibar(self, d):
"""
Assemble the navibar
@param d: parameter dictionary
@rtype: string
@return: navibar html
"""
_ = self.request.getText
html = []
# insert Menu tag ##########
html.append('
\n')
html.append('%s: \n' % _("Page"))
if d['navibar']:
# Print site name in first field of navibar
# html.append(('
%(site_name)s
\n') % d)
for (link, navi_link) in d['navibar']:
html.append((
'%(navi_link)s \n') % {
'link': link,
'navi_link': navi_link,
})
html.append('
')
# ??? make sure to close all
with an extra
# ??? html.append('
')
html.append('
\n')
return ''.join(html)
def get_icon(self, icon):
try:
ret = self.icons[icon]
except KeyError: # if called from [[Icon(file)]] we have a filename, not a key
# using filenames is deprecated, but for now, we simulate old behaviour!
# please use only the icon *key* in future, not the filename any more.
icon = icon.replace('.gif','.png') # no gifs any more!
for i in self.icons.keys():
ret = self.icons[i]
if ret[1] == icon: # found the file name?
break
else:
ret = ("", icon, "", "")
return (ret[0], self.img_url(ret[1])) + ret[2:]
def make_icon(self, icon, vars=None):
"""
This is the central routine for making tags for icons!
All icons stuff except the top left logo, smileys and search
field icons are handled here.
@param icon: icon id (dict key)
@param vars: ...
@rtype: string
@return: icon html (img tag)
"""
if vars is None:
vars = {}
alt, img, w, h = self.get_icon(icon)
try:
alt = alt % vars
except KeyError, err:
alt = 'KeyError: %s' % str(err)
if self.request:
alt = self.request.getText(alt)
try:
tag = self.request.formatter.image(src=img, alt=alt, width=w, height=h)
except AttributeError: # XXX FIXME if we have no formatter or no request
tag = '' % (
img, alt, w, h)
import warnings
warnings.warn("calling themes without correct request", DeprecationWarning)
return tag
def make_iconlink(self, which, d):
"""
Make a link with an icon
@param which: icon id (dictionary key)
@param d: parameter dictionary
@rtype: string
@return: html link tag
"""
page_params, title, icon = config.page_icons_table[which]
d['title'] = title % d
d['i18ntitle'] = self.request.getText(d['title'])
img_src = self.make_icon(icon, d)
return wikiutil.link_tag(self.request, page_params % d, d['i18ntitle'], attrs='title="%(title)s"' % d)
#return wikiutil.link_tag(self.request, page_params % d, img_src, attrs='title="%(i18ntitle)s"' % d)
def iconbar(self, d):
"""
Assemble the iconbar
@param d: parameter dictionary
@rtype: string
@return: iconbar html
"""
_ = self.request.getText
iconbar = []
if config.page_iconbar and self.request.user.show_toolbar and d['page_name']:
iconbar.append('
')
nearpages = ''.join(html)
indentation = re.compile(r'\[.+?\]||\?action=LocalSiteMap')
while indentation.search(nearpages):
nearpages = indentation.sub(r'', nearpages, 0)
indentation = re.compile(r'.+? \n', nearpages, 0)
indentation = re.compile(r' ')
while indentation.search(nearpages):
nearpages = indentation.sub(r' ', nearpages, 0)
indentation = re.compile(r'">([^<]+?)([a-zäöüß])([A-ZÄÖÜ])')
while indentation.search(nearpages):
nearpages = indentation.sub(r'">\1\2 \3', nearpages, 0)
indentation = re.compile(r'([^<]+?)([a-zäöüß])([A-ZÄÖÜ])')
while indentation.search(nearpages):
nearpages = indentation.sub(r'\1\2 \3', nearpages, 0)
return nearpages
def msg(self, d):
"""
Assemble the msg display
@param d: parameter dictionary
@rtype: string
@return: msg display html
"""
html = ''
if d['msg']:
_ = self.request.getText
d.update({'link_text': _('Clear message'),})
clear_msg_link = '%(link_text)s' % d
d.update({'clear_msg_link': clear_msg_link,})
html += ('\n
\n'
'%(msg)s %(clear_msg_link)s
') % d
#'
%(msg)s
%(clear_msg_link)s
') % d
# close "content" div
else:
pass
return html
def trail(self, d):
"""
Assemble page trail
@param d: parameter dictionary
@rtype: string
@return: trail html
"""
_ = self.request.getText
html = []
if d['trail']:
pagetrail = d['trail']
# insert lastpages tag (trailer)
html.append('
\n')
html.append('
\n')
html.append(' %s: \n' % _("Trail"))
for p in pagetrail[:-1]:
html.append('%s \n' % (Page(p).link_to(self.request),))
# close lastpages tag
html.append('
\n')
else:
# ??? close possibly remaining "content" div ?!
# ??? html.append('\n')
pass
splittedtrailer = ''.join(html)
workinprogress = re.compile(r'">([^<]+?)([a-zäöüß])([A-ZÄÖÜ])')
while workinprogress.search(splittedtrailer):
splittedtrailer = workinprogress.sub(r'">\1\2 \3', splittedtrailer, 0)
workinprogress = re.compile(r'([^<]+?)([a-zäöüß])([A-ZÄÖÜ])')
while workinprogress.search(splittedtrailer):
splittedtrailer = workinprogress.sub(r'\1\2 \3', splittedtrailer, 0)
return splittedtrailer
def html_stylesheet_link(self, charset, media, href):
return ('\n') % (charset, media, href)
def html_stylesheets(self, d):
"""
Assemble stylesheet links
@param d: parameter dictionary
@rtype: string
@return: links
"""
html = []
if d.get('print_mode', False):
stylesheets = self.stylesheets_print
else:
stylesheets = self.stylesheets
user_css_url = self.request.user.valid and self.request.user.css_url
# Create stylesheets links
for theme, charset, media, name in stylesheets:
href = self.css_url(name, theme)
html.append(self.html_stylesheet_link(charset, media, href))
# workaround for old user settings
# Dont add user css url if it matches one of ours
if user_css_url and user_css_url == href:
user_css_url = None
# Add user css url (assuming that user css uses iso-8859-1)
# ??? Maybe move to utf-8?
# TODO: Document this in the Help system
if user_css_url and user_css_url.lower() != "none":
html.append(
self.html_stylesheet_link('iso-8859-1', 'all', user_css_url))
return ''.join(html)
def html_head(self, d):
"""
Assemble html head
@param d: parameter dictionary
@rtype: string
@return: html head
"""
dict = {
'stylesheets_html': self.html_stylesheets(d),
}
dict.update(d)
html = """
%(title)s - %(sitename)s
%(stylesheets_html)s
""" % dict
return html
def header(self, d):
"""
Assemble page header
@param d: parameter dictionary
@rtype: string
@return: page header html
"""
dict = {
'config_header1_html': self.emit_custom_html(config.page_header1),
'config_header2_html': self.emit_custom_html(config.page_header2),
'logo_html': self.logo(d),
'title_html': self.title(d),
'username_html': self.username(d),
'navibar_html': self.navibar(d),
'iconbar_html': self.iconbar(d),
'search_form_html': self.searchform(d),
'available_actions_html': self.availableactions(d),
'msg_html': self.msg(d),
'trail_html': self.trail(d),
'mapbar_html': self.mapbar(d),
}
dict.update(d)
html = """
%(config_header1_html)s
%(logo_html)s
%(title_html)s
%(msg_html)s
""" % dict
# Next parts will use config.default_lang direction, as set in the
return html
# Footer stuff #######################################################
def showtext_link(self, d, **keywords):
"""
Assemble ShowText link (on action pages)
@param d: parameter dictionary
@rtype: string
@return: edittext link html
"""
_ = self.request.getText
html = ''
if keywords.get('showpage', 0):
#html += '
\n'
return html
def edittext_link(self, d, **keywords):
"""
Assemble EditText link (or indication that page cannot be edited)
@param d: parameter dictionary
@rtype: string
@return: edittext link html
"""
_ = self.request.getText
html = []
html.append('
')
if keywords.get('editable', 1):
editable = self.request.user.may.edit(d['page_name']) and d['page'].isWritable()
if editable:
html.append("%s %s" % (
wikiutil.link_tag(self.request, d['q_page_name']+'?action=edit', _('EditText')),
_('of this page'),
))
else:
html.append("%s" % _('Immutable page'))
html.append(' %(last_edit_info)s' % d)
html.append('
')
return ''.join(html)
def footer_fragments(self, d, **keywords):
"""
assemble HTML code fragments added by the page formatters
@param d: parameter dictionary
@rtype: string
@return: footer fragments html
"""
html = ''
if d['footer_fragments']:
html = ''.join(d['footer_fragments'].values())
return html
def searchform(self, d):
"""
assemble HTML code for the search forms
@param d: parameter dictionary
@rtype: string
@return: search form html
"""
_ = self.request.getText
sitenav_pagename = wikiutil.getSysPage(self.request, 'SiteNavigation').page_name
dict = {
'search_title': _("Search"),
'search_html': _("Title: %(titlesearch)s Text: %(textsearch)s") % d,
}
dict.update(d)
html = """
""" % dict
return html
def availableactions(self, d):
"""
assemble HTML code for the available actions
@param d: parameter dictionary
@rtype: string
@return: available actions html
"""
_ = self.request.getText
html = []
html.append('
\n')
return ''.join(html)
def showversion(self, d, **keywords):
"""
assemble HTML code for copyright and version display
@param d: parameter dictionary
@rtype: string
@return: copyright and version display html
"""
html = ''
if config.show_version and not keywords.get('print_mode', 0):
html = ('
'
'MoinMoin %s, Copyright \xa9 2000-2004 by Jürgen Hermann'
'
')
if d['time_html']:
html.append("%(time_html)s" % d)
html.append('
\n')
html.append('
%(info_html)s
\n' % d)
html.append('
')
if d['editors']:
html.append(' '.join(d['editors']))
html.append('
\n')
html.append('
')
if d['comments']:
if d['changecount'] > 1:
notfirst = 0
for comment in d['comments']:
html.append('%s#%02d %s' % (
notfirst and ' ' or '' , comment[0], comment[1]))
notfirst = 1
else:
comment = d['comments'][0]
html.append('%s' % comment[1])
html.append('
\n')
html.append('
\n')
return ''.join(html)
def recentchanges_daybreak(self, d):
"""
Assemble a rc daybreak indication (table row)
@param d: parameter dictionary
@rtype: string
@return: recentchanges daybreak html
"""
if d['bookmark_link_html']:
set_bm = ' [%(bookmark_link_html)s]' % d
else:
set_bm = ''
return ('
'
'%s'
'%s'
'
\n') % (6, d['date'], set_bm)
def recentchanges_header(self, d):
"""
Assemble the recentchanges header (intro + open table)
@param d: parameter dictionary
@rtype: string
@return: recentchanges header html
"""
_ = self.request.getText
html = '
\n' % self.ui_lang_attr()
html += '
\n'
if d['rc_rss_link']:
html += '
%s
\n' % d['rc_rss_link']
html += '
'
if d['rc_update_bookmark']:
html += "%(rc_update_bookmark)s %(rc_curr_bookmark)s " % d
if d['rc_days']:
days = []
for day in d['rc_days']:
if day == d['rc_max_days']:
days.append('%d' % day)
else:
days.append(
wikiutil.link_tag(self.request,
'%s?max_days=%d' % (d['q_page_name'], day),
str(day)))
days = ' | '.join(days)
html += (_("Show all changes in the last %s days.") % (days,))
html += '
\n
\n'
html += '
\n'
return html
def recentchanges_footer(self, d):
"""
Assemble the recentchanges footer (close table)
@param d: parameter dictionary
@rtype: string
@return: recentchanges footer html
"""
_ = self.request.getText
html = ''
html += '
\n'
if d['rc_msg']:
html += " %(rc_msg)s\n" % d
html += '
\n'
return html
#
# Language stuff
#
def ui_lang_attr(self):
"""Generate language attributes for user interface elements
User interface elements use the user language (if any), kept in
request.lang.
@rtype: string
@return: lang and dir html attributes
"""
lang = self.request.lang
dir = i18n.getDirection(lang)
return 'lang="%(lang)s" dir="%(dir)s"' % locals()
def content_lang_attr(self):
"""Generate language attributes for wiki page content
Page content uses the wiki default language
@rtype: string
@return: lang and dir html attributes
"""
lang = config.default_lang
dir = i18n.getDirection(lang)
return 'lang="%(lang)s" dir="%(dir)s"' % locals()
def execute(request):
"""
Generate and return a theme object
@param request: the request object
@rtype: MoinTheme
@return: Theme object
"""
return Theme(request)