Attachment 'solenoid_iso-191.py'
Download 1 # -*- coding: iso-8859-1 -*-
2 """
3 MoinMoin Solenoid theme
4
5 @copyright: 2007 RadomirDopieralski <moin@sheep.art.pl>, Oliver Siemoneit
6 2009 Renato Silva
7
8 @license: See the README file.
9 """
10
11 from MoinMoin import wikiutil, version
12 from MoinMoin import caching
13 from MoinMoin.theme import ThemeBase, modernized
14 from MoinMoin.Page import Page
15 from MoinMoin.i18n import Translation, translations, po_filename
16 import MoinMoin.i18n, re, os, glob
17 import MoinMoin
18 import StringIO
19
20 class Theme(ThemeBase):
21
22 name = "solenoid"
23
24 _ = lambda x: x
25
26 icons = {
27
28 # Key Alt Icon filename W H
29 # ----------------------------------------------------------------------------------
30 # Navibar
31 'help': ("%(page_help_contents)s", "moin-help.png", 16, 16),
32 'find': ("%(page_find_page)s", "moin-search.png", 16, 16),
33 'diff': (_("Diffs"), "moin-diff.png", 20, 16),
34 'info': (_("Info"), "moin-info.png", 16, 16),
35 'edit': (_("Edit"), "moin-edit.png", 16, 16),
36 'unsubscribe': (_("Unsubscribe"), "moin-unsubscribe.png", 16, 16),
37 'subscribe': (_("Subscribe"), "moin-subscribe.png", 16, 16),
38 'addquicklink': (_("Add quicklink"), "moin-addquicklink.png", 16, 16),
39 'delquicklink': (_("Delete quicklink"), "moin-delquicklink.png", 16, 16),
40
41 'raw': (_("Raw"), "moin-raw.png", 16, 16),
42 'xml': (_("XML"), "moin-xml.png", 20, 13),
43 'print': (_("Print"), "moin-print.png", 16, 16),
44 'view': (_("View"), "moin-show.png", 16, 16),
45 'home': (_("Home"), "moin-home.png", 16, 16),
46 'up': (_("Up"), "moin-parent.png", 16, 16),
47
48 # FileAttach
49 'attach': ("%(attach_count)s", "moin-attach.png", 12, 12),
50 'iconattach': ("Add/Manage files", "moin-iconattach.png", 16, 16),
51
52 # RecentChanges
53 'rss': (_("[RSS]"), "moin-rss.png", 39, 14),
54 'deleted': (_("[DELETED]"), "moin-deleted.png", 80, 16),
55 'updated': (_("[UPDATED]"), "moin-updated.png", 80, 16),
56 'renamed': (_("[RENAMED]"), "moin-renamed.png", 80, 16),
57 'conflict': (_("[CONFLICT]"), "moin-conflict.png", 23, 16),
58 'new': (_("[NEW]"), "moin-new.png", 80, 16),
59 'diffrc': (_("[DIFF]"), "moin-diff.png", 20, 16),
60
61 # General
62 'bottom': (_("[BOTTOM]"), "moin-bottom.png", 12, 12),
63 'top': (_("[TOP]"), "moin-top.png", 12, 12),
64 'www': ("[WWW]", "moin-www.png", 12, 12),
65 'mailto': ("[MAILTO]", "moin-email.png", 12, 12),
66 'news': ("[NEWS]", "moin-news.png", 12, 12),
67 'irc': ("[IRC]", "moin-irc.png", 15, 15),
68 'telnet': ("[TELNET]", "moin-telnet.png", 12, 12),
69 'ftp': ("[FTP]", "moin-ftp.png", 12, 12),
70 'file': ("[FILE]", "moin-ftp.png", 12, 12),
71
72 # Search forms
73 'searchbutton': ("[?]", "moin-search.png", 16, 16),
74 'interwiki': ("[%(wikitag)s]", "moin-inter.png", 12, 12),
75 'badinterwiki': ("[%(wikitag)s]", "moin-badinter.png", 12, 12),
76
77 # Smileys
78 'X-(': ("X-(", 'angry.png', 18, 18),
79 ':D': (":D", 'biggrin.png', 18, 18),
80 '<:(': ("<:(", 'frown.png', 18, 18),
81 ':o': (":o", 'redface.png', 18, 18),
82 ':(': (":(", 'sad.png', 18, 18),
83 ':)': (":)", 'smile.png', 18, 18),
84 'B)': ("B)", 'smile2.png', 18, 18),
85 ':))': (":))", 'smile3.png', 18, 18),
86 ';)': (";)", 'smile4.png', 18, 18),
87 '/!\\': ("/!\\", 'alert.png', 16, 16),
88 '<!>': ("<!>", 'attention.png', 16, 16),
89 '(!)': ("(!)", 'idea.png', 16, 16),
90 ':-?': (":-?", 'tongue.png', 18, 18),
91 ':\\': (":\\", 'ohwell.png', 18, 18),
92 '>:>': (">:>", 'devil.png', 18, 18),
93 '|)': ("|)", 'tired.png', 18, 18),
94 ':-(': (":-(", 'sad.png', 18, 18),
95 ':-)': (":-)", 'smile.png', 18, 18),
96 'B-)': ("B-)", 'smile2.png', 18, 18),
97 ':-))': (":-))", 'smile3.png', 18, 18),
98 ';-)': (";-)", 'smile4.png', 18, 18),
99 '|-)': ("|-)", 'tired.png', 18, 18),
100 '(./)': ("(./)", 'checkmark.png', 16, 16),
101 '{OK}': ("{OK}", 'thumbs-up.png', 16, 16),
102 '{X}': ("{X}", 'icon-error.png', 16, 16),
103 '{i}': ("{i}", 'icon-info.png', 16, 16),
104 '{1}': ("{1}", 'prio1.png', 16, 16),
105 '{2}': ("{2}", 'prio2.png', 16, 16),
106 '{3}': ("{3}", 'prio3.png', 16, 16),
107 '{*}': ("{*}", 'star_on.png', 16, 16),
108 '{o}': ("{o}", 'star_off.png', 16, 16),
109
110 # New big icons for classic theme
111 'diff-big': (_("Diffs"), "moin-diff-big.png", 31, 25),
112 'info-big': (_("Info"), "moin-info-big.png", 25, 25),
113 'edit-big': (_("Edit"), "moin-edit-big.png", 25, 25),
114 'unsubscribe-big': (_("Unsubscribe"), "moin-unsubscribe-big.png", 25, 25),
115 'subscribe-big': (_("Subscribe"), "moin-subscribe-big.png", 25, 25),
116 'raw-big': (_("Raw"), "moin-raw-big.png", 25, 25),
117 'print-big': (_("Print"), "moin-print-big.png", 25, 25),
118 'view-big': (_("View"), "moin-show-big.png", 25, 25),
119 'delquicklink-big': (_("Delete quicklink"), "moin-delquicklink-big.png", 25, 25),
120 'addquicklink-big': (_("Add quicklink"), "moin-addquicklink-big.png", 25, 25),
121 'attach-big': (_("Add/Manage files"), "moin-iconattach-big.png", 25, 25),
122 }
123
124 del _
125
126 def _(self, text):
127 lang = self.request.lang
128 _translations = self._translations
129 if lang in _translations:
130 if text in _translations[lang]:
131 return _translations[lang][text]
132 return self.request.getText(text, formatted=False)
133
134 _showApproveLink = None
135 def approved(self, d):
136 page = d['page']
137
138 # check whether page exists at all
139 if not page.exists():
140 return ""
141
142 # check whether or not to display the "Approve" action link
143 if page.get_real_rev() == page.getRevList()[0]:
144 self._showApproveLink = True
145 else:
146 self._showApproveLink = False
147
148 # return the page's approval status
149 return page.getApprovalMessage()
150
151
152 def approveLink(self, page):
153 """ Return approve link to valid users
154
155 @rtype: unicode
156 @return: approve link
157 """
158 _ = self.request.getText
159
160 #if user has perms
161 title = _("Approve")
162 quotedname = wikiutil.quoteWikinameURL(page.page_name)
163 return page.link_to(self.request, text=_('Approve', formatted=False), querystr='action=ApprovePage')
164
165
166 def _get_config(self, source, config_name, default=None):
167 return getattr(source, '%s_%s' % (self.name, config_name), default)
168
169 def get_bool_user_config(self, config_name):
170 user = self.request.user
171 if not user.valid:
172 return None
173 user_config = self._get_config(user, config_name)
174 if type(user_config) == str:
175 user_config = {'1': True}.get(user_config, False)
176 elif type(user_config) == int:
177 user_config = bool(user_config)
178 return user_config
179
180 def get_config(self, config_name, default=None, by_user=True):
181 if by_user and self.userprefs_allowed and self.get_bool_user_config('enable_prefs'):
182 user_config = self.get_bool_user_config(config_name)
183 if user_config is not None:
184 return user_config
185 return self._get_config(self.cfg, config_name, default)
186
187 def __init__(self, request):
188 ThemeBase.__init__(self, request)
189 append_translation = self.get_config('append_translation', default=True, by_user=False)
190 self._translations = self.theme_translations(append_translation)
191 self.userprefs_allowed = self.get_config('userprefs', default=False, by_user=False)
192 if self.userprefs_allowed:
193 self.load_user_options()
194 try:
195 self.static_prefix = self.cfg.url_prefix_static
196 except AttributeError:
197 self.static_prefix = self.cfg.url_prefix
198
199 def load_user_options(self):
200 user = self.request.user
201 self.define_user_options()
202 if user.valid:
203 user.save()
204 user.load_from_id()
205
206 def define_user_options(self):
207 capitalized_name = self.name.capitalize()
208 new_options = [
209 ('%s_enable_prefs' % self.name, lambda _: self._('%s theme: enable configuration by user') % capitalized_name),
210 ('%s_full_screen' % self.name, lambda _: self._('%s theme: use full screen mode') % capitalized_name),
211 ('%s_clear' % self.name, lambda _: self._('%s theme: use clear style') % capitalized_name),
212 ('%s_shadow' % self.name, lambda _: self._('%s theme: use shadows') % capitalized_name)
213 ]
214
215 defined_options = self.request.cfg.user_checkbox_fields
216 defined_option_names = [each[0] for each in defined_options]
217
218 for new_option in new_options:
219 for defined_option in defined_options:
220 if defined_option[0] == new_option[0]:
221 defined_options.remove(defined_option)
222 break
223 defined_options.append(new_option)
224
225 new_option_names = [each[0] for each in new_options]
226 self.request.cfg.user_checkbox_defaults.update(dict.fromkeys(new_option_names, 0))
227
228 def theme_translations(self, append=False):
229 """Load personal translations to be used by this theme.
230
231 @param append: if True makes theme translation global by appending it to the default Moin translation system.
232 @return: a dict (indexed by language) of translation dicts, or an empty dict if append=True.
233 """
234 _translations = {}
235 request = self.request
236 po_dir = os.path.join('i18n', 'themes', self.name)
237 encoding = 'utf-8'
238
239 for lang_file in glob.glob(po_filename(request, i18n_dir=po_dir, language='*', domain='Theme')):
240 dummy_language, domain, ext = os.path.basename(lang_file).split('.')
241 language = dummy_language.split('_')[0]
242 t = Translation(dummy_language, domain)
243 t.loadLanguage(request, trans_dir=po_dir)
244
245 if append:
246 if not language in translations:
247 translations[language] = Translation(language)
248 translations[language].loadLanguage(request)
249 translations[language].raw.update(t.raw)
250 else:
251 _translations[language] = {}
252 for key, text in t.raw.items():
253 _translations[language][key] = text
254
255 return _translations
256
257 def header(self, d):
258 _ = self._
259 wrapper_class = u'wrapper'
260 sidebar = self.sidebar(d)
261 if sidebar is None:
262 sidebar = u''
263 wrapper_class += u' no-sidebar'
264 page_title = self.title(d)
265 site_logo = self.logo()
266 if (site_logo == ''):
267 site_logo = page_title.replace('<h1>', '<div class="logo">').replace('</h1>', '</div>')
268 site_logo = site_logo.replace('id="', 'id="logo_')
269 site_logo = site_logo.replace("id='", "id='logo_")
270 page_title = '<h1> </h1>'
271 parts = [
272 self.emit_custom_html(self.cfg.page_header1),
273 u'<div class="header">',
274 site_logo,
275 self.searchform(d),
276 self.username(d),
277 self.gotobar(d),
278 self.msg(d),
279 self.editbar(d),
280 page_title,
281 self.logged_trail(d),
282 u'</div>',
283 self.emit_custom_html(self.cfg.page_header2),
284 u'<div class="%s">' % wrapper_class,
285 sidebar,
286 u'<div class="content"%s>\n' % self.content_lang_attr(),
287 self.approved(d),
288 "<!--[if lt IE 7]><div class='outdated-ie'><p><b>%s! </b>%s</p></div><![endif]-->"
289 % (_("Attention"), _("You are using an outdated version of Internet Explorer "
290 "which is not supported by this site. Please update your browser."))
291 ]
292 return u''.join(parts)
293
294 editorheader = header
295
296 def title(self, d):
297 _ = self._
298 cfg = self.request.cfg
299 modernized_theme = modernized.Theme(self.request)
300 if self.request.action != 'print':
301 try:
302 screen_title = self.title_with_separators # Moin 1.9
303 except AttributeError:
304 screen_title = modernized_theme.title # Moin 1.8
305 return u'<h1>%s%s</h1>' % (modernized_theme.interwiki(d), screen_title(d))
306
307 # We are in print action
308 page_path = wikiutil.escape(d['title_text'].replace('/', ' / '))
309 lines = d['page'].get_raw_body().split('\n')
310 for line in lines:
311 line = line.strip()
312 if not line.startswith('#') and not line.startswith('<<') and not line == '':
313 # If page starts with a title, then make page path a header before it
314 if re.sub('^\s*=+\s+[^=]+\s+=+\s*$', '', line) == '':
315 return u'<span id="pagelocation">%s: %s</span> <br> %s' % (_('Page Name'), page_path, self.approved(d))
316 break
317
318 # Page does not start with a title, so we use page path as title
319 interwiki_name = '%s: ' % (cfg.interwikiname or 'Wiki')
320 prefix = ['', interwiki_name][cfg.show_interwiki]
321 return u'<h1 id="pagelocation">%s%s</h1>' % (prefix, page_path)
322
323 def logged_trail(self, d):
324 user = self.request.user
325 html = u""
326 if user.valid and user.show_page_trail:
327 if len(user.getTrail())>1:
328 html = self.trail(d)
329 return html
330
331 def footer(self, d, **keywords):
332 page = d['page']
333 footer_note = self.get_config('footer_note', default='', by_user=False)
334 parts = [
335 u'<div id="pagebottom"></div>',
336 u'</div></div>', # wrapper and content divs
337 self.emit_custom_html(self.cfg.page_footer1),
338 u'<div class="footer">',
339 self.emit_custom_html(footer_note),
340 self.pageinfo(page),
341 u'</div>',
342 self.emit_custom_html(self.cfg.page_footer2),
343 ]
344 return u''.join(parts)
345
346 def sidebar(self, d, **keywords):
347 """ Display page called SideBar as an additional element on every page
348
349 @param d: parameter dictionary
350 @rtype: string
351 @return: sidebar html
352 """
353 request = self.request
354 _ = self._
355 sidebar = request.getPragma('sidebar') or u'SideBar';
356 page = Page(request, sidebar)
357 if not page.exists():
358 return None
359 import StringIO
360 buff = StringIO.StringIO()
361 request.redirect(buff)
362 try:
363 try:
364 page.send_page(content_only=1, content_id="sidebar")
365 except TypeError:
366 page.send_page(request, content_only=1, content_id="sidebar")
367 finally:
368 request.redirect()
369 return u'<div class="sidebar">%s<div id="sidebar-end"></div></div>' % buff.getvalue()
370
371
372 def editbar(self, d, **keywords):
373 page = d['page']
374 if not self.shouldShowEditbar(page):
375 return u''
376 result = []
377 enabled_items = self.request.cfg.edit_bar
378 suplementation_enabled = self.request.cfg.supplementation_page
379
380 if (self._showApproveLink == True) and (self.request.user.may.approve(page.page_name)):
381 result.append(self.approveLink(page))
382
383 if 'Edit' in enabled_items:
384 result.append(self.edit_link(page))
385 result.append(self.revert_link(page))
386
387 if 'Comments' in enabled_items:
388 result.append(self.toggle_comments_link(page))
389
390 if ('Discussion' in enabled_items and
391 self.request.getPragma('supplementation-page', suplementation_enabled) in
392 (True, 1, 'on', '1')):
393 result.append(self.supplementation_page_nameLink(page))
394
395 if 'Info' in enabled_items:
396 result.append(self.info_link(page))
397 if 'Subscribe' in enabled_items:
398 result.append(self.subscribeLink(page))
399 if 'Quicklink' in enabled_items:
400 result.append(self.quicklinkLink(page))
401 if 'Attachments' in enabled_items:
402 result.append(self.attach_link(page))
403
404 if 'ActionsMenu' in enabled_items:
405 result.append(self.actionsMenu(page).replace('</form>', '<input type="hidden" name="subpages_checked" value="1"></form>'))
406 else:
407 result.append(self.admin_link(page))
408 return u'<div class="editbar"> %s </div>' % (u' '.join(result))
409
410 def edit_link(self, page):
411 if not (page.isWritable() and
412 self.request.user.may.write(page.page_name)):
413 return self.login_link(page)
414 _ = self._
415 params = (wikiutil.quoteWikinameURL(page.page_name) +
416 '?action=edit')
417 text = _('Edit')
418 return wikiutil.link_tag(self.request, params, text, css_class="edit", name="texteditlink")
419
420 def login_link(self, page):
421 _ = self._
422 params = (wikiutil.quoteWikinameURL(page.page_name) +
423 '?action=login')
424 text = _('Locked')
425 return wikiutil.link_tag(self.request, params, text, css_class="password")
426
427 def info_link(self, page):
428 _ = self._
429 params = (wikiutil.quoteWikinameURL(page.page_name) +
430 '?action=info')
431 text = _('History')
432 return wikiutil.link_tag(self.request, params, text, css_class="history")
433
434 def revert_link(self, page):
435 try:
436 rev = self.request.rev
437 except AttributeError:
438 return u""
439 if not (self.request.rev and
440 page.isWritable() and
441 self.request.user.may.revert(page.page_name)):
442 return u''
443 _ = self._
444 params = (wikiutil.quoteWikinameURL(page.page_name) +
445 '?action=revert&rev=%d' % self.request.rev)
446 text = _('Revert')
447 return wikiutil.link_tag(self.request, params, text, css_class="revert")
448
449 def attach_link(self, page):
450 _ = self._
451 params = (wikiutil.quoteWikinameURL(page.page_name) +
452 '?action=AttachFile')
453 text = _('Attachments')
454 return wikiutil.link_tag(self.request, params, text, css_class="attachments")
455
456 def toggle_comments_link(self, page):
457 _ = self._
458 return '''<span class="toggleCommentsButton" style="display:none;">
459 <a href="#" class="nbcomment" onClick="toggleComments();return false;">%s</a></span>''' % _('Comments')
460
461 def admin_link(self, page):
462 _ = self._
463 params = (wikiutil.quoteWikinameURL(page.page_name) +
464 '?action=PageActions')
465 text = _('All Actions')
466 return wikiutil.link_tag(self.request, params, text, css_class="admin")
467
468 def gotobar(self, d, **k):
469 request = self.request
470 found = {}
471 items = []
472 item = u'%s'
473 current = d['page_name']
474 if request.cfg.navi_bar:
475 for text in request.cfg.navi_bar:
476 #pagename, url = self.splitNaviurl(text)
477 pagename, link = self.splitNavilink(text, localize=1)
478 if pagename == current:
479 cls = 'wikilink current'
480 else:
481 cls = 'wikilink'
482 items.append(
483 '<li class="%s">%s</li>'%(cls, link)
484 )
485 found[pagename] = 1
486 userlinks = request.user.getQuickLinks()
487 for text in userlinks:
488 #pagename, url = self.splitNaviurl(text, localize=0)
489 pagename, link = self.splitNavilink(text, localize=0)
490 if not pagename in found:
491 if pagename == current:
492 cls = 'userlink current'
493 else:
494 cls = 'userlink'
495 items.append(
496 '<li class="%s">%s</li>' % (cls, link)
497 )
498 found[pagename] = 1
499 return u'<ul class="gotobar">%s<li class="clear"></li></ul>' % u' '.join(items)
500
501 def html_stylesheets(self, d):
502
503 def ie_version_spec(ie_style): return re.compile('msie/.*_ie').sub('IE ', ie_style)
504 def ie_style(style, ie_version): return 'msie/%s_ie%d' % (style, ie_version)
505 def is_ie_style(style): return style.startswith('msie')
506
507 def ie_content(content, version_spec='IE'):
508 version_spec = version_spec.replace('<= ', 'lte ')
509 return '<!--[if %s]>%s<![endif]-->' % (version_spec, content)
510
511 def add_style(style):
512 styles.append(style)
513 for version in [7, 8]:
514 styles.append(ie_style(style, version))
515
516 clear = self.get_config('clear', default=False)
517 shadow = self.get_config('shadow', default=False)
518 full_screen = self.get_config('full_screen', default=False)
519 print_action = self.request.action == 'print'
520
521 tags = []
522 styles = []
523 add_style('style')
524 if clear: add_style('clear')
525
526 if print_action:
527 add_style('print')
528 try:
529 media = self.request.values.get('media')
530 except AttributeError:
531 media = self.request.form.get('media', [None])[0]
532 if media == 'projection':
533 add_style('projection')
534 elif full_screen: add_style('full')
535 elif shadow:
536 add_style('shadow')
537 if clear: add_style('shadow_clear')
538
539 static_dir = self.get_config('htdocs_dir', by_user=False)
540 if static_dir is None:
541 try:
542 # Moin 1.9
543 from MoinMoin.web.static import STATIC_FILES_PATH
544 static_dir = STATIC_FILES_PATH
545 except ImportError, e:
546 # Moin 1.8
547 moin_base = re.sub('MoinMoin$', '', self.cfg.moinmoin_dir)
548 static_dir = os.path.join(moin_base, 'wiki', 'htdocs')
549 if not os.path.exists(static_dir):
550 static_dir = '/usr/share/moin/htdocs'
551
552 link_template = '<link rel="stylesheet" type="text/css" href="%s">'
553 url_prefix = "%s/%s/css" % (self.static_prefix, self.name)
554 css_dir = os.path.join(static_dir, self.name, 'css')
555 found_css_dir = os.path.exists(css_dir)
556
557 for style in styles:
558 for namespace in ['', '/custom']:
559 css_url = '%s%s/%s.css' % (url_prefix, namespace, style)
560 css_file = '%s%s/%s.css' % (css_dir, namespace, style)
561 if not found_css_dir or os.path.exists(css_file):
562 css_link = link_template % css_url
563 if is_ie_style(style):
564 css_link = ie_content(css_link, ie_version_spec(style))
565 tags.append(css_link)
566
567 return '\n'.join(tags)
568
569 def searchform(self, d):
570 _ = self._
571 form = self.request.form
572 updates = {
573 'search_label' : _('Search:'),
574 'search_value': wikiutil.escape(form.get('value', [''])[0], 1),
575 'search_full_label' : _('Text'),
576 'search_title_label' : _('Titles'),
577 }
578 d.update(updates)
579
580 return u'''
581 <form class="search" method="get" action="">
582 <p>
583 <input type="hidden" name="action" value="fullsearch">
584 <input type="hidden" name="context" value="180">
585 <label for="search">%(search_label)s</label>
586 <input id="search" type="text" name="value" value="%(search_value)s">
587 <input id="titlesearch" name="titlesearch" type="submit" value="%(search_title_label)s">
588 <input id="fullsearch" name="fullsearch" type="submit" value="%(search_full_label)s">
589 </p>
590 </form>''' % d
591
592 def pageinfo(self, page):
593 _ = self._
594 html = ''
595 if self.shouldShowPageinfo(page):
596 info = page.lastEditInfo()
597 if info:
598 if info['editor']:
599 info = _("last edited %(time)s by %(editor)s") % info
600 else:
601 info = _("last modified %(time)s") % info
602 html = '<span class="time"%(lang)s>%(info)s</span>\n' % {
603 'lang': self.ui_lang_attr(),
604 'info': info
605 }
606 return html
607
608 def logo(self):
609 logo = u''
610 if self.cfg.logo_string:
611 pagename = wikiutil.getFrontPage(self.request).page_name
612 pagename = wikiutil.quoteWikinameURL(pagename)
613 logo = wikiutil.link_tag(self.request, pagename, self.cfg.logo_string, css_class="logo")
614 return logo
615
616 def headscript(self, d):
617 """Override the stupid default script with its hardcoded HTML structure"""
618 return u'''<script type="text/javascript"><!--
619 function add_gui_editor_links() {
620 // Add gui editor link after the text editor link
621
622 // If the variable is not set or browser is not compatible, exit
623 try {gui_editor_link_href}
624 catch (e) {
625 //alert("add_gui_editor_links: gui_editor_link_href not here");
626 return
627 }
628 if (can_use_gui_editor() == false){
629 //alert("add_gui_editor_links: can't use gui_editor");
630 return;
631 }
632 var all = document.getElementsByName('texteditlink');
633 for (i = 0; i < all.length; i++) {
634 var textEditorLink = all[i];
635 // Create a a link
636 var guiEditorLink = document.createElement('a');
637 guiEditorLink.href = gui_editor_link_href;
638 guiEditorLink.className = "edit";
639 var text = document.createTextNode(gui_editor_link_text);
640 guiEditorLink.appendChild(text);
641 // Insert in the editbar
642 var editbar = textEditorLink.parentNode
643 editbar.insertBefore(guiEditorLink, textEditorLink);
644 }
645 }
646 --></script>
647 '''
648
649 def recentchanges_entry(self, d):
650 _ = self._
651 if d['comments']:
652 rccomm = ''
653 for c in d['comments']:
654 rccomm += ' <b>%d</b> ' % c[0];
655 rccomm += c[1];
656 else:
657 rccomm = ''
658 html = (u'''<li><b class="rctime">%s</b> %s %s . . . . <span class="rcauth">%s</span> <i class="rccomm">%s</i></li>''' % (
659 d['time_html'],
660 d['pagelink_html'],
661 d['icon_html'],
662 ', '.join(d['editors']),
663 rccomm,
664 ))
665 return html
666
667 def recentchanges_daybreak(self, d):
668 return u'</ul><h3 class="rcdaybreak">%s</h3><ul>' % d['date']
669
670 def recentchanges_header(self, d):
671 return u'<div class="recentchanges"%s><ul>' % self.ui_lang_attr()
672
673 def recentchanges_footer(self, d):
674 return u'</ul></div>'
675
676
677 def execute(request):
678 return Theme(request)
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.