Mercurial > moin-softie
changeset 0:af911d8e119f
Initial import
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Thu Dec 06 12:06:54 2007 +0100 @@ -0,0 +1,5 @@ +syntax: glob +.cookies.wget +*.pyc +*~ +.*.swp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PageActions.py Thu Dec 06 12:06:54 2007 +0100 @@ -0,0 +1,68 @@ +# -*- coding: iso-8859-1 -*- + +import re +from MoinMoin import config, wikiutil +from MoinMoin.Page import Page + +# Ripped from the LikePages action +def execute(pagename, request): + _ = request.getText + from MoinMoin.formatter.text_html import Formatter + request.formatter = Formatter(request) + + request.http_headers() + + # This action generate data using the user language + request.setContentLanguage(request.lang) + request.theme.send_title(_('Actions for %s') % pagename, page_name=pagename) + + # Start content - IMPORTANT - without content div, there is no + # direction support! + request.write(request.formatter.startContent("content")) + + # Just list the actions + request.write(availableactions(request)) + + # End content and send footer + request.write(request.formatter.endContent()) + request.theme.send_footer(pagename) + +# Make a link to action +def actionlink(request, action, title, comment=''): + page = request.page + _ = request.getText + # Always add spaces: AttachFile -> Attach File + # XXX TODO do not make a page object just for split_title + title = Page(request, title).split_title(request) #, force=1) + # Use translated version if available + title = _(title, formatted=False) + params = '%s?action=%s' % (page.page_name, action) + link = wikiutil.link_tag(request, params, _(title)) + return u''.join([ u'<li>', link, comment, u'</li>' ]) + + +# Rippped from the theme code +def availableactions(request): + page = request.page + _ = request.getText + html = '' + links = [] + available = request.getAvailableActions(page) +# try: +# available = available.keys() +# except AttributeError: +# pass + for action in available: + links.append(actionlink(request, action, action)) + if page.isWritable() and request.user.may.write(page.page_name): + links.append(actionlink(request, 'edit', 'EditText')) + if request.user.valid and request.user.email: + action = ("Subscribe", "Unsubscribe")[request.user.isSubscribedTo([page.page_name])] + links.append(actionlink(request, 'subscribe', action)) + if request.user.valid: + links.append(actionlink(request, 'userform&logout=logout', 'Logout')) + links.append(actionlink(request, 'print', 'PrintView')) + links.append(actionlink(request, 'raw', 'ViewRawText')) + links.append(actionlink(request, 'refresh', 'DeleteCache')) + html = u'<ul>%s</ul>' % u''.join(links) + return html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.txt Thu Dec 06 12:06:54 2007 +0100 @@ -0,0 +1,17 @@ += Mandarin theme for MoinMoin = + +This is a theme for the MoinMoin wiki enigne. + +== Instalation == + +To install this theme, put the file mandarin.py into your +data/plugin/theme directory, the PageActions.py file into +your data/plugin/actions and all the rest of files into +htdocs/mandarin. + +== License == + +This theme is licensed under GPL, see the LICENSE file you +got with MoinMoin for details. + +The author is Radomir Dopieralski <moin@sheep.art.pl>.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mandarin.py Thu Dec 06 12:06:54 2007 +0100 @@ -0,0 +1,333 @@ +# -*- coding: iso-8859-1 -*- +""" +MoinMoin Mandarin theme + +@copyright: 2007 by RadomirDopieralski (moin@sheep.art.pl), Oliver Siemoneit () +@license: GNU GPL, see COPYING for details. +""" + +from MoinMoin import wikiutil, version +from MoinMoin import caching +from MoinMoin.theme import ThemeBase +from MoinMoin.Page import Page +import StringIO + +class Theme(ThemeBase): + + name = "mandarin" + + _ = lambda x: x # We don't have gettext at this moment, so we fake it + icons = { + # key alt icon filename w h + # FileAttach + 'attach': ("%(attach_count)s", "moin-attach.png", 7, 15), + 'attachimg': ("", "attach.png", 32, 32), + # RecentChanges + 'rss': (_("[RSS]"), "moin-rss.png", 24, 24), + 'deleted': (_("[DELETED]"), "moin-deleted.png",16, 16), + 'updated': (_("[UPDATED]"), "moin-updated.png",16, 16), + 'renamed': (_("[RENAMED]"), "moin-renamed.png",16, 16), + 'conflict': (_("[CONFLICT]"), "moin-conflict.png", 15, 15), + 'new': (_("[NEW]"), "moin-new.png", 16, 16), + 'diffrc': (_("[DIFF]"), "moin-diff.png", 15, 11), + # General + 'bottom': (_("[BOTTOM]"), "moin-bottom.png", 14, 10), + 'top': (_("[TOP]"), "moin-top.png", 14, 10), + 'www': ("[WWW]", "moin-www.png", 11, 11), + 'mailto': ("[MAILTO]", "moin-email.png", 14, 10), + '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", 16, 16), + + # smileys (this is CONTENT, but good looking smileys depend on looking + # adapted to the theme background color and theme style in general) + #vvv == vvv this must be the same for GUI editor converter + 'X-(': ("X-(", 'angry.png', 16, 16), + ':D': (":D", 'biggrin.png', 16, 16), + '<:(': ("<:(", 'frown.png', 16, 16), + ':o': (":o", 'redface.png', 16, 16), + ':(': (":(", 'sad.png', 16, 16), + ':)': (":)", 'smile.png', 16, 16), + 'B)': ("B)", 'smile2.png', 16, 16), + ':))': (":))", 'smile3.png', 16, 16), + ';)': (";)", 'smile4.png', 16, 16), + '/!\\': ("/!\\", 'alert.png', 15, 15), + '<!>': ("<!>", 'attention.png', 15, 15), + '(!)': ("(!)", 'idea.png', 16, 16), + ':-?': (":-?", 'tongue.png', 16, 16), + ':\\': (":\\", 'ohwell.png', 16, 16), + '>:>': (">:>", 'devil.png', 16, 16), + '|)': ("|)", 'tired.png', 16, 16), + ':-(': (":-(", 'sad.png', 16, 16), + ':-)': (":-)", 'smile.png', 16, 16), + 'B-)': ("B-)", 'smile2.png', 16, 16), + ':-))': (":-))", 'smile3.png', 16, 16), + ';-)': (";-)", 'smile4.png', 16, 16), + '|-)': ("|-)", 'tired.png', 16, 16), + '(./)': ("(./)", 'checkmark.png', 16, 16), + '{OK}': ("{OK}", 'thumbs-up.png', 16, 16), + '{X}': ("{X}", 'icon-error.png', 16, 16), + '{i}': ("{i}", 'icon-info.png', 16, 16), + '{1}': ("{1}", 'prio1.png', 16, 16), + '{2}': ("{2}", 'prio2.png', 16, 16), + '{3}': ("{3}", 'prio3.png', 16, 16), + '{*}': ("{*}", 'star_on.png', 16, 16), + '{o}': ("{o}", 'star_off.png', 16, 16), + } + del _ + + def header(self, d): + parts = [ + self.emit_custom_html(self.cfg.page_header1), + self.msg(d), + u'<div class="header">', + self.logo(), + self.searchform(d), + self.username(d), + self.gotobar(d), + self.editbar(d), + self.title(d), + self.logged_trail(d), + u'</div>', + self.emit_custom_html(self.cfg.page_header2), + u'<div class="wrapper">', + self.sidebar(d), + u'<div class="content"%s>\n' % self.content_lang_attr(), + ] + return u''.join(parts) + + editorheader = header + + def logged_trail(self, d): + user = self.request.user + html = u"" + if user.valid and user.show_page_trail: + if len(user.getTrail())>1: + html = self.trail(d) + return html + + def footer(self, d, **keywords): + page = d['page'] + parts = [ + self.endPage(), + u'</div></div>', + self.emit_custom_html(self.cfg.page_footer1), + u'<div class="footer">', + self.pageinfo(page), + u'</div>', + self.emit_custom_html(self.cfg.page_footer2), + ] + return u''.join(parts) + + def sidebar(self, d, **keywords): + request = self.request + _ = self.request.getText + sidebar = 'SideBar'; + page = Page(request, sidebar) + buff = StringIO.StringIO() + request.redirect(buff) + try: + page.send_page(request, content_only=1, content_id="sidebar") + finally: + request.redirect() + return u'<div class="sidebar">%s</div>' % buff.getvalue() + + + def editbar(self, d, **keywords): + if not self.shouldShowEditbar(d['page']): + return u'' + parts = [ + u'<div class="editbar">', + self.edit_link(d), + self.info_link(d), + self.admin_link(d), + u'</div>', + ] + return u' '.join(parts) + + def edit_link(self, d): + page = d['page'] + if not (page.isWritable() and + self.request.user.may.write(page.page_name)): + return self.login_link(d) + _ = self.request.getText + params = (wikiutil.quoteWikinameURL(page.page_name) + + '?action=edit') + text = _('Edit', formatted=False) + return wikiutil.link_tag(self.request, params, text, css_class="edit") + + def login_link(self, d): + page = d['page'] + _ = self.request.getText + params = (wikiutil.quoteWikinameURL(page.page_name) + + '?action=login') + text = _('Locked', formatted=False) + return wikiutil.link_tag(self.request, params, text, css_class="password") + + def info_link(self, d): + page = d['page'] + _ = self.request.getText + params = (wikiutil.quoteWikinameURL(page.page_name) + + '?action=info') + text = _('History', formatted=False) + return wikiutil.link_tag(self.request, params, text, css_class="history") + + def admin_link(self, d): + page = d['page'] + _ = self.request.getText + params = (wikiutil.quoteWikinameURL(page.page_name) + + '?action=PageActions') + text = _('Actions', formatted=False) + return wikiutil.link_tag(self.request, params, text, css_class="admin") + + def gotobar(self, d, **k): + request = self.request + found = {} + items = [] + item = u'%s' + current = d['page_name'] + if request.cfg.navi_bar: + for text in request.cfg.navi_bar: + #pagename, url = self.splitNaviurl(text) + pagename, link = self.splitNavilink(text, localize=1) + if pagename == current: + cls = 'wikilink current' + else: + cls = 'wikilink' + items.append( + '<li class="%s">%s</li>'%(cls, link) + ) + found[pagename] = 1 + userlinks = request.user.getQuickLinks() + for text in userlinks: + #pagename, url = self.splitNaviurl(text, localize=0) + pagename, link = self.splitNavilink(text, localize=0) + if not pagename in found: + if pagename == current: + cls = 'userlink current' + else: + cls = 'userlink' + items.append( + '<li class="%s">%s</li>' % (cls, link) + ) + found[pagename] = 1 + return u'<ul class="gotobar">%s<li class="clear"></li></ul>' % u' '.join(items) + + def pagepath(self, d): + _ = self.request.getText + content = [] + if d['title_text'] == d['page_name']: # just showing a page, no action + curpage = u'' + segments = d['page_name'].split('/') + for s in segments[:-1]: + curpage += s + content.append(Page(self.request, curpage).link_to(self.request, s)) + content.append("/") + curpage += '/' + html = '<span class="pagepath">%s</span>' % "".join(content) + return html + + def title(self, d): + title = d['title_text'] + if title == d['page_name']: + html = '<h1>%s%s</h1>' % ( + self.pagepath(d), wikiutil.escape(title.split('/')[-1])) + else: + html = '<h1>%s</h1>' % wikiutil.escape(title) + return html + + def html_stylesheets(self, d): + prefix = self.cfg.url_prefix_static + url = '%s/%s/%s' % (prefix, self.name, 'style.css') + return '<link rel="stylesheet" type="text/css" href="%s">' % url + + def searchform(self, d): + _ = self.request.getText + form = self.request.form + updates = { + 'search_label' : _('Search:'), + 'search_value': wikiutil.escape(form.get('value', [''])[0], 1), + 'search_full_label' : _('Text', formatted=False), + 'search_title_label' : _('Titles', formatted=False), + } + d.update(updates) + + return u''' +<form class="search" method="get" action=""> +<p> +<input type="hidden" name="action" value="fullsearch"> +<input type="hidden" name="context" value="180"> +<label for="search">%(search_label)s</label> +<input id="search" type="text" name="value" value="%(search_value)s"> +<input id="titlesearch" name="titlesearch" type="submit" value="%(search_title_label)s"> +<input id="fullsearch" name="fullsearch" type="submit" value="%(search_full_label)s"> +</p> +</form>''' % d + + def pageinfo(self, page): + _ = self.request.getText + html = '' + if self.shouldShowPageinfo(page): + info = page.lastEditInfo() + if info: + if info['editor']: + info = _("last edited %(time)s by %(editor)s") % info + else: + info = _("last modified %(time)s") % info + html = '<span class="time"%(lang)s>%(info)s</span>\n' % { + 'lang': self.ui_lang_attr(), + 'info': info + } + return html + + def logo(self): + html = u'' + if self.cfg.logo_string: + pagename = wikiutil.getFrontPage(self.request).page_name + pagename = wikiutil.quoteWikinameURL(pagename) + logo = wikiutil.link_tag(self.request, pagename, self.cfg.logo_string, css_class="logo") + return logo + + def headscript(self, d): + return u'' + + def externalScript(self, name): + return u'' + + def guiEditorScript(self, d): + return u'' + def recentchanges_entry(self, d): + _ = self.request.getText + if d['comments']: + rccomm = '' + for c in d['comments']: + rccomm += ' <b>%d</b> ' % c[0]; + rccomm += c[1]; + else: + rccomm = '' + html = (u'''<li><b class="rctime">%s</b> %s %s . . . . <span class="rcauth">%s</span> <i class="rccomm">%s</i></li>''' % ( + d['time_html'], + d['pagelink_html'], + d['icon_html'], + ', '.join(d['editors']), + rccomm, + )) + return html + + def recentchanges_daybreak(self, d): + return u'</ul><h3 class="rcdaybreak">%s</h3><ul>' % d['date'] + + def recentchanges_header(self, d): + return u'<div class="recentchanges"%s><ul>' % self.ui_lang_attr() + + def recentchanges_footer(self, d): + return u'</ul></div>' + + +def execute(request): + return Theme(request) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mandarin/style.css Thu Dec 06 12:06:54 2007 +0100 @@ -0,0 +1,303 @@ +html { + padding: 0; + margin; 0; + font-size: 90%; + font-family: DejaVu Sans, Droid Sans, Verdana, sans-serif; + height: 100%; + background: #fff; + color: #000; +} +body { + padding: 0; + margin: 0; + min-height: 100%; + position: relative; +} +* html body { height: 100%; } + + + +a img { border: none } +a { color: #f60; text-decoration: none } +a:visited { color: #f93; } + +a.interwiki, a.www, a.external { color: #48f } +a.interwiki:visited, a.www:visited, a.external:visited { color: #65f } +a.nonexistent { color: #f02 } +a:hover { color: #000; text-decoration: underline } + + +li p { margin: 0 } + +textarea, select, input { + border: 1px solid #999; + vertical-align: middle; + line-height: 1.2; + font-size: 100%; +} +textarea { + display: block; + width: 99%; +} + +form.search { + float: right; + margin: 0.5em; + color: #666; +} +form.search p { + margin: 0; + font-size: 90%; +} +div.gotobar p { + margin: 0; + padding: 0.5em; +} + +div.editbar a.edit:before { + content: url(img/edit.png); + vertical-align: baseline; + margin-right: 0.05em; +} + +div.editbar { + float: right; + margin: 1em 0.75em; + color: #999; +} +div.editbar a { + color: #999; + font-size: 90%; + margin-left: 0.25em; +} +div.editbar a:hover { + color: #fff; +} + +a.logo { + display: block; + margin: 0.25em; + float: left; + clear: none; + font-size: 200%; + text-decoration: none; + color: #444; + line-height: 1.2; + font-family: Impact, Haettenschweiler, fantasy; + letter-spacing: 0.025em; +} +a.logo img { + vertical-align: middle; + margin: 0 0.25em 0 0; +} + + +ul#username { + display; block; + float: right; + clear: right; + list-style none; + margin: 0 0.5em; +} +ul#username li { + list-style none; + display: inline; + margin: 0 0 0 1em; + font-size: 90%; +} + + +ul.gotobar { + margin: 0; + padding: 0 0.5em; + display: block; + border-top: 1px solid #d60; + border-bottom: 1px solid #e70; + color: #eee; + background: #f93; + clear: both; +} +ul.gotobar li { + display: block; + float: left; + margin: 0.25em 0.25em; + border: 1px solid #e70; +} +ul.gotobar li a { + letter-spacing: 0.05em; + display: block; + border: 1px solid #fb7; + text-decoration: none; + font-size: 90%; + padding: 0.25em 0.75em; + background: #fa4; + color: #420; +} +ul.gotobar li.current a { + background: #f93; + border: 1px solid #fa3; + color: #000; +} +ul.gotobar li.current { + border: 1px solid #d60; +} +ul.gotobar li a:hover { + color: #000; + background: #fb6; + border: 1px solid #fd9; +} +ul.gotobar li.clear { + display: block; + list-style: none; + clear: both; + float: none; + visibility: hidden; + margin: 0; + padding: 0; +} + +div.header h1 { + color: #eee; + background: #444; + margin: 0; + border-bottom: 1px solid #555; + padding: 0.5em; + font-weight: normal; + font-size: 125%; + border-top: 2px solid #333; + letter-spacing: 0.025em; +} + +span.pagepath { + font-size: 80%; color: #666; + font-weight: bold; +} +span.pagepath a { + font-weight: normal; + color: #999; +} + +div.header { + border-bottom: 1px solid #000; +} + + +div.wrapper { + padding: 0.5em 1em 2em 12em; + color: #444; + border-top: 2px solid #ddd; + position: relative; +} + +div.content { + line-height: 1.35; +} + +div.sidebar { + width: 11.5em; + position: absolute; + left: 0.75em; + top: 0.75em; + font-size: 90%; + line-height: 1.3; + background: #feb; + border: 1px solid #ea7; + border-bottom: 1px solid #e83; + padding: 1px; +} +div.wrapper div.sidebar h1, +div.wrapper div.sidebar h2, +div.wrapper div.sidebar h3 { + font-size: 100%; + margin: 0 0 0.25em 0; + letter-spacing: 0.05em; + font-weight: normal; + color: #852; + border: 1px solid #ea6; + background: #fc7; + padding: 0.25em 0.5em; + line-height: 1.1; + font-family: DejaVu Sans, Droid Sans, Verdana, sans-serif; +} +div.sidebar ul { + margin: 0; + list-style: none; + padding: 0 0 0.25em 0; +} +div.sidebar li { + list-style: none; + background: url(img/bullet.png) no-repeat 3px 3px; + padding: 0 0 0 15px; +} +div.sidebar a { color: #000; } +div.sidebar a:hover { text-decoration: underline } + + +div.wrapper h1, h2, h3, h4, h5 { + color: #fa4; + font-family: Impact, Haettenschweiler, fantasy; + font-weight: normal; + line-height: 1.2; +} +div.wrapper h1 { font-size: 200%; margin: 1em 0 0.5em 0; color: #f92 } +div.wrapper h2 { font-size: 200%; margin: 1em 0 0.5em 0; } +div.wrapper h3 { font-size: 150%; letter-spacing: 0.025em; margin: 1.25em 0 0.75em 0; } +div.wrapper h4 { font-size: 125%; letter-spacing: 0.05em; margin: 1.5em 0 1em 0; color: #fb6 } + + +ul#pagetrail { + display: block; + background: #eee; + border-bottom: 1px solid #fff; + border-top: 3px solid #bbb; + margin: 0; + padding: 0; +} +ul#pagetrail li { + display: inline; + list-style: none; + margin-left: 0.75em; +} +ul#pagetrail li a { + font-size: 80%; + color: #666; +} + + +div.footer { + position: absolute; + width: 100%; + bottom: 0; + left: 0; + right: 0; + color: #ddd; + text-align; right; + border-top: 1px solid #ccc; + padding: 0; + margin: 0; +} +div.footer span.time { + display: block; + text-align: right; + color: #666; + font-size: 80%; + padding: 0.25em 0.5em; + font-style: italic; +} + +div#message, p.status { + position: absolute; + top: 0; + left: 0; + right: 0; + background: #eee; + border-bottom: 1px solid #888; + padding: 0.125em 0.5em; + margin: 0; + font-size: 90%; + color: #000; + opacity: 0.75; +} + +div.message p { margin: 0 } +
