Adjunto 'moniker19.py'
Descargar 1 # -*- coding: iso-8859-1 -*-
2 """
3 Moniker theme for MoinMoin wiki
4
5 Theme code largely based on modernized, with inspiration and help by
6 Roger Haase's FixedLeft theme (code for converting the dropdown menu into javascript).
7
8 @copyright: 2010 Rick Vanderveer
9 @license: GNU GPL
10
11 """
12
13 from MoinMoin.theme import ThemeBase
14 from MoinMoin.action import get_available_actions
15 from MoinMoin import wikiutil
16 from MoinMoin.Page import Page
17
18 class Theme(ThemeBase):
19
20 name = "moniker" # Rick: I call it 'moniker' so that I can use the same CSS folder regardless of which I'm testing.
21
22 _ = lambda x: x # We don't have gettext at this moment, so we fake it
23 icons = {
24 # key alt icon filename w h
25 # file mime types for AttachTable.py macro:
26 'unknown': ("unknown type", "filetype-unknown.png", 24, 24),
27 '.doc': ("Word file", "filetype-doc.png", 24, 24),
28 '.docx': ("Word file", "filetype-doc.png", 24, 24),
29 '.xls': ("Excel file", "filetype-xls.png", 24, 24),
30 '.xlsx': ("Excel file", "filetype-xls.png", 24, 24),
31 '.ppt': ("PowerPoint file", "filetype-ppt.png", 24, 24),
32 '.mov': ("mov file", "filetype-mov.png", 24, 24),
33 '.txt': ("txt file", "filetype-doc.png", 24, 24),
34 '.pdf': ("pdf file", "filetype-pdf.png", 24, 24),
35 '.swf': ("Flash file", "filetype-swf.png", 24, 24),
36 '.png': ("Graphic file", "filetype-image.png", 24, 24),
37 '.zip': ("zip file", "filetype-zip.png", 24, 24),
38 '.bmp': ("Graphic file", "filetype-image.png", 24, 24),
39 '.jpg': ("Graphic file", "filetype-image.png", 24, 24),
40 '.gif': ("Graphic file", "filetype-image.png", 24, 24),
41 '.wmv': ("Graphic file", "filetype-media.png", 24, 24),
42 '.wma': ("Graphic file", "filetype-media.png", 24, 24),
43 '.mp3': ("Graphic file", "filetype-media.png", 24, 24),
44 # AttachTable toggle controls
45 #'table-null': ("null table control image", "table-null.png", 16, 16),
46 #'table-close': ("close table control image", "table-null.png", 16, 16),
47 #'table-open': ("open table control image", "table-null.png", 16, 16),
48 # FileAttach
49 'attach': ("%(attach_count)s", "moin-attach.png", 16, 16),
50 'info': ("[INFO]", "moin-info.png", 16, 16),
51 'attachimg': (_("[ATTACH]"), "attach.png", 32, 32),
52 # RecentChanges
53 'rss': (_("[RSS]"), "moin-rss.png", 16, 16),
54 'deleted': (_("[DELETED]"), "moin-deleted.png", 16, 16),
55 'updated': (_("[UPDATED]"), "moin-updated.png", 16, 16),
56 'renamed': (_("[RENAMED]"), "moin-renamed.png", 16, 16),
57 'conflict': (_("[CONFLICT]"), "moin-conflict.png", 16, 16),
58 'new': (_("[NEW]"), "moin-new.png", 16, 16),
59 'diffrc': (_("[DIFF]"), "moin-diff.png", 16, 16),
60 # General
61 'bottom': (_("[BOTTOM]"), "moin-bottom.png", 16, 16),
62 'top': (_("[TOP]"), "moin-top.png", 16, 16),
63 'www': ("[WWW]", "moin-www.png", 16, 16),
64 'mailto': ("[MAILTO]", "moin-email.png", 16, 16),
65 'news': ("[NEWS]", "moin-news.png", 16, 16),
66 'telnet': ("[TELNET]", "moin-telnet.png", 16, 16),
67 'ftp': ("[FTP]", "moin-ftp.png", 16, 16),
68 'file': ("[FILE]", "moin-ftp.png", 16, 16),
69 # search forms
70 'searchbutton': ("[?]", "moin-search.png", 16, 16),
71 'interwiki': ("[%(wikitag)s]", "moin-inter.png", 16, 16),
72
73 # smileys (this is CONTENT, but good looking smileys depend on looking
74 # adapted to the theme background color and theme style in general)
75 #vvv == vvv this must be the same for GUI editor converter
76 'X-(': ("X-(", 'angry.png', 16, 16),
77 ':D': (":D", 'biggrin.png', 16, 16),
78 '<:(': ("<:(", 'frown.png', 16, 16),
79 ':o': (":o", 'redface.png', 16, 16),
80 ':(': (":(", 'sad.png', 16, 16),
81 ':)': (":)", 'smile.png', 16, 16),
82 'B)': ("B)", 'smile2.png', 16, 16),
83 ':))': (":))", 'smile3.png', 16, 16),
84 ';)': (";)", 'smile4.png', 16, 16),
85 '/!\\': ("/!\\", 'alert.png', 16, 16),
86 '<!>': ("<!>", 'attention.png', 16, 16),
87 '(!)': ("(!)", 'idea.png', 16, 16),
88 ':-?': (":-?", 'tongue.png', 16, 16),
89 ':\\': (":\\", 'ohwell.png', 16, 16),
90 '>:>': (">:>", 'devil.png', 16, 16),
91 '|)': ("|)", 'tired.png', 16, 16),
92 ':-(': (":-(", 'sad.png', 16, 16),
93 ':-)': (":-)", 'smile.png', 16, 16),
94 'B-)': ("B-)", 'smile2.png', 16, 16),
95 ':-))': (":-))", 'smile3.png', 16, 16),
96 ';-)': (";-)", 'smile4.png', 16, 16),
97 '|-)': ("|-)", 'tired.png', 16, 16),
98 '(./)': ("(./)", 'checkmark.png', 16, 16),
99 '{OK}': ("{OK}", 'thumbs-up.png', 16, 16),
100 '{X}': ("{X}", 'icon-error.png', 16, 16),
101 '{i}': ("{i}", 'icon-info.png', 16, 16),
102 '{1}': ("{1}", 'prio1.png', 15, 13),
103 '{2}': ("{2}", 'prio2.png', 15, 13),
104 '{3}': ("{3}", 'prio3.png', 15, 13),
105 '{*}': ("{*}", 'star_on.png', 16, 16),
106 '{o}': ("{o}", 'star_off.png', 16, 16),
107 }
108 del _
109 def header(self, d, **kw):
110 """ Assemble wiki header
111
112 @param d: parameter dictionary
113 @rtype: unicode
114 @return: page header html
115 """
116 html = [
117 # Pre header custom html
118 self.emit_custom_html(self.cfg.page_header1),
119 self.username(d),
120 '<div id="header">%s</div>' % self.logo(),
121
122 # Start of left panels.
123 u'<div id="sidebar">',
124
125 # Rick: rebuild below so we can put a cute little box around it: self.navibar(d),
126 self.navibarpanel(d),
127
128 # Rick: rebuild below so we can put a cute little box around it: self.searchform(d),
129 self.searchpanel(d),
130
131 # Rick: rebuild below so we can put a cute little box around it: self.trail(d),
132 self.trailpanel(d),
133
134 # Rick: rebuild below so we can put a cute little box around it: self.navibar(d),
135 self.editbarpanel(d),
136 u'</div>',
137
138 # Post header custom html (not recommended)
139 self.emit_custom_html(self.cfg.page_header2),
140
141 # Start of page
142 self.msg(d),
143 self.startPage(),
144 self.title_with_separators(d),
145 ]
146 return u'\n'.join(html)
147
148 # Rick: copied code from Roger Haase's FixedLeft theme, but then whacked out most of it because all I really want is just to load my little javascript. This augments to the __init__.py def html_head
149 def html_head(self, d):
150 """ Assemble html head
151
152 modifications to ThemeBase method:
153 - Add javascript source file
154
155 @param d: parameter dictionary
156 @rtype: unicode
157 @return: formatted header
158 """
159 head = ThemeBase.html_head(self, d)
160 head += u'\n<script type="text/javascript" src="%s/%s/js/actionmenuoptions.js"></script>' % (self.cfg.url_prefix_static, self.name)
161 return head
162
163
164 #
165 # Rick: Let's build us some panels!
166 # We're going to wrap a cute little HTML box around each bar so we can dress it in CSS.
167 #
168
169
170 # Rick: Remember to customize this box by editing the edit_bar entry in your farmconfig/wikiconfig.py file!
171 # ## Rick This is a basic, no-frills (no hiding) panel
172 def navibarpanel(self, d):
173 """ Create page actions panel .
174
175 @param d: parameter dictionary
176 @rtype: unicode
177 @return: formatted actions panel
178 """
179 _ = self.request.getText
180 html = [
181 # Modified by Leonardo Alviarez for correct translation
182 #u'<div class="sidepanel"><h1>%s</h1>' % ( _("Quick Links")),
183 u'<div class="sidepanel"><h1>%s</h1>' % ( _("Quick links")),
184 self.navibar(d),
185 u'</div>',
186 ]
187 return u''.join(html)
188
189
190 # Rick: Borrowing code from Roger Haase's FixedLeft theme so that the searchbox buttons will wrap:
191 def searchpanel(self,d):
192 """Create search panel.
193
194 @param d: parameter dictionary
195 @rtype: unicode
196 @return: formatted search panel
197 """
198 _ = self.request.getText
199 html = [
200 # Modified by Leonardo Alviarez for correct translation
201 #u'<div class="sidepanel"><h1>%s</h1>' % (_("Search Wiki")),
202 u'<div class="sidepanel"><h1>%s</h1>' % (_("Search:")),
203 self.searchform(d),
204 u'</div>',
205 ]
206 return u''.join(html)
207
208
209 def trailpanel(self, d):
210 """ Create page trail panel.
211
212 @param d: parameter dictionary
213 @rtype: unicode
214 @return: formatted page trail panle
215 """
216 _ = self.request.getText
217 trail = self.trail(d)
218 if trail:
219 html = [
220 # Modified by Leonardo Alviarez for correct translation
221 # in this case item is not present in file .po :-(
222 #u'<div class="sidepanel"><h1>%s</h1>' % ( _("Recently Viewed")),
223 u'<div class="sidepanel"><h1>%s</h1>' % ( _("Visto recientemente")),
224 trail,
225 u'</div>',
226 ]
227 else:
228 html = []
229 return u''.join(html)
230
231
232 def trail(self, d):
233 """ Assemble page trail
234 from modernized (not __init__.py):
235
236 @param d: parameter dictionary
237 @rtype: unicode
238 @return: trail html
239 """
240 request = self.request
241 user = request.user
242 html = ''
243 if not user.valid or user.show_page_trail:
244 trail = user.getTrail()
245 if trail:
246 items = []
247 for pagename in trail:
248 try:
249 interwiki, page = wikiutil.split_interwiki(pagename)
250 if interwiki != request.cfg.interwikiname and interwiki != 'Self':
251 link = (self.request.formatter.interwikilink(True, interwiki, page) +
252 self.shortenPagename(page) +
253 self.request.formatter.interwikilink(False, interwiki, page))
254 items.append(link)
255 continue
256 else:
257 pagename = page
258
259 except ValueError:
260 pass
261 page = Page(request, pagename)
262 title = page.split_title()
263 title = self.shortenPagename(title)
264 link = page.link_to(request, title)
265 items.append(link)
266 html = u'<div class="pagetrail">%s</div>' % u'<span class="sep"> ↓ </span> <br>'.join(items)
267 return html
268
269
270
271 # if the the user is not allowed to edit (i.e. not logged in), then don't display at all.
272 def editbarpanel(self, d):
273 """ Create page actions panel .
274
275 @param d: parameter dictionary
276 @rtype: unicode
277 @return: formatted actions panel
278 """
279 _ = self.request.getText
280 if self.shouldShowEditbar(d['page']):
281 html = [
282 # Modified by Leonardo Alviarez for correct translation
283 # in this case item is not present in file .po :-(
284 #u'<div class="sidepanel"><h1>%s</h1>' % ( _("Page Tools")),
285 u'<div class="sidepanel"><h1>%s</h1>' % ( _("Herramientas")),
286 self.editbar(d),
287 u'</div>',
288 ]
289 return u''.join(html)
290 return ''
291
292
293 # Rick: We get to re-write this whole def all so we can convert the actions menu a drop-down list.
294 # original code block copied out of Roger Haase's FixedLeft theme: he added baseurl to make things work properly
295 # with javascript, then we re-write the HTML end with our own javascript.
296
297 # Don't forget you can control what appears in this listed in this menu by controlling the Actions_excluded option.
298 # Paste the following into your farmconfig.py/wikiconfig.py file and comment out items you -DO- want to list:
299 """
300 actions_excluded = [
301 'raw',
302 #'print',
303 'RenderAsDocbook',
304 #'refresh',
305 'SpellCheck',
306 'LikePages',
307 #'LocalSiteMap',
308 #'RenamePage',
309 'CopyPage',
310 'DeletePage',
311 'MyPages',
312 #'SubscribeUser',
313 'Despam',
314 'revert',
315 'PackagePages',
316 'SyncPages',
317 'Load',
318 'Save',
319 ]
320 """
321
322 def actionsMenu(self, page):
323 """ Create actions menu list and items data dict
324
325 The menu will contain the same items always, but items that are
326 not available will be disabled (some broken browsers will let
327 you select disabled options though).
328
329 The menu should give best user experience for javascript
330 enabled browsers, and acceptable behavior for those who prefer
331 not to use Javascript.
332
333 TODO: Move actionsMenuInit() into body onload - requires that the theme will render body,
334 it is currently done in wikiutil/page.
335
336
337 @param page: current page, Page object
338 @rtype: unicode
339 @return: actions menu html fragment
340 """
341 request = self.request
342 _ = request.getText
343 rev = request.rev
344 # rev was a hidden input within the more actions form
345 # alternative will be to append it to anchor urls
346 if rev:
347 revision = '&rev=%s' % rev
348 else:
349 revision = ''
350
351 menu = [
352 'raw',
353 'print',
354 'RenderAsDocbook',
355 'refresh',
356 #'__separator__',
357 'SpellCheck',
358 'LikePages',
359 'LocalSiteMap',
360 #'__separator__',
361 'RenamePage',
362 'CopyPage',
363 'DeletePage',
364 #'__separator__',
365 'MyPages',
366 'SubscribeUser',
367 #'__separator__',
368 'Despam',
369 'revert',
370 'PackagePages',
371 'SyncPages',
372 ]
373
374 titles = {
375 # action: menu title
376 '__title__': _("More Actions:"),
377 # Rick: Set separator to blank, as that looks better in our drop down menu:
378 '__separator__': _(''),
379 'raw': _('Raw Text'),
380 'print': _('Print View'),
381 'refresh': _('Delete Cache'),
382 'SpellCheck': _('Check Spelling'), # rename action!
383 'RenamePage': _('Rename Page'),
384 'CopyPage': _('Copy Page'),
385 'DeletePage': _('Delete Page'),
386 'LikePages': _('Like Pages'),
387 'LocalSiteMap': _('Local Site Map'),
388 'MyPages': _('My Pages'),
389 'SubscribeUser': _('Subscribe User'),
390 'Despam': _('Remove Spam'),
391 # Modified by Leonardo Alviarez for correct translation
392 #'revert': _('revert to this revision'),
393 'revert': _('Revert to this revision'),
394 'PackagePages': _('Package Pages'),
395 'RenderAsDocbook': _('Render as Docbook'),
396 'SyncPages': _('Sync Pages'),
397 }
398
399 options = []
400 #original: option = '<option value="%(action)s"%(disabled)s>%(title)s</option>'
401
402 option = '<li><a href="%(baseurl)s?action=%(action)s%(revision)s">%(title)s</a></li>'
403 disabledOption = '<li class="disabled">%(title)s</li>'
404
405 # class="disabled" is a workaround for browsers that ignore
406 # "disabled", e.g IE, Safari
407 # for XHTML: data['disabled'] = ' disabled="disabled"'
408 disabled = ' disabled class="disabled"'
409 # @@@ is this best way to form link to current page? Had trouble with subpages replicating parent page name in url
410 # baseurl is full url as used here
411 baseurl = self.request.getScriptname() + '/' + wikiutil.quoteWikinameURL(page.page_name)
412
413
414 # Format standard actions
415 available = get_available_actions(request.cfg, page, request.user)
416 for action in menu:
417 data = {'action': action, 'disabled': '', 'title': titles[action], 'baseurl': baseurl, 'revision': revision,}
418 # removes excluded actions from the more actions menu
419 if action in request.cfg.actions_excluded:
420 continue
421
422 # Enable delete cache only if page can use caching
423 if action == 'refresh':
424 if not page.canUseCache():
425 data['action'] = 'show'
426 data['disabled'] = disabled
427
428 # revert action enabled only if user can revert
429 if action == 'revert' and not request.user.may.revert(page.page_name):
430 data['action'] = 'show'
431 data['disabled'] = disabled
432
433 # SubscribeUser action enabled only if user has admin rights
434 if action == 'SubscribeUser' and not request.user.may.admin(page.page_name):
435 data['action'] = 'show'
436 data['disabled'] = disabled
437
438 # PackagePages action only if user has write rights
439 if action == 'PackagePages' and not request.user.may.write(page.page_name):
440 data['action'] = 'show'
441 data['disabled'] = disabled
442
443 # Despam action enabled only for superusers
444 if action == 'Despam' and not request.user.isSuperUser():
445 data['action'] = 'show'
446 data['disabled'] = disabled
447
448 # Special menu items. Without javascript, executing will
449 # just return to the page.
450 if action.startswith('__'):
451 data['action'] = 'show'
452
453 # Actions which are not available for this wiki, user or page
454 if (action == '__separator__' or
455 (action[0].isupper() and not action in available)):
456 data['disabled'] = disabled
457
458
459 #~ options.append(option % data) # @@@
460 if data['disabled']:
461 options.append(disabledOption % data)
462 else:
463 options.append(option % data)
464
465 # Add custom actions not in the standard menu, except for
466 # some actions like AttachFile (we have them on top level)
467 more = [item for item in available if not item in titles and not item in ('AttachFile', )]
468 more.sort()
469 if more:
470 # Add separator
471 #~ separator = option % {'action': 'show', 'disabled': disabled, # @@@
472 #~ 'title': titles['__separator__'], 'baseurl': baseurl,} # @@@ deleted by last fix
473 #~ 'title': titles['__separator__'], 'baseurl': baseurl, 'revision': revision,} # @@@
474 separator = disabledOption % {'action': 'show', 'disabled': disabled,
475 'title': titles['__separator__'], 'baseurl': baseurl,}
476
477 options.append(separator)
478 # Add more actions (all enabled)
479 for action in more:
480 data = {'action': action, 'disabled': '', 'baseurl': baseurl, 'revision': revision,}
481 # Always add spaces: AttachFile -> Attach File
482 # XXX do not create page just for using split_title -
483 # creating pages for non-existent does 2 storage lookups
484 #title = Page(request, action).split_title(force=1)
485 title = action
486 # Use translated version if available
487 data['title'] = _(title)
488 options.append(option % data)
489
490 data = {
491 'label': titles['__title__'],
492 'options': '\n'.join(options),
493 'rev_field': rev and '<input type="hidden" name="rev" value="%d">' % rev or '',
494 'do_button': _("Do"),
495 'baseurl': self.request.getScriptname(),
496 'pagename_quoted': wikiutil.quoteWikinameURL(page.page_name),
497 }
498 # Modified by Leonardo Alviarez for correct translation
499 # html = '''
500 #<div class="togglelink" id="togglelink" onclick="toggleMenu('menu1')">[ more options ]</div>
501 #<div id="menu1">
502 #<ul>
503 #%(options)s
504 #</ul>
505 #</div>
506 #''' % data
507
508 html = '''<div class="togglelink" id="togglelink" onclick="toggleMenu('menu1')">[ %s ]</div>''' % _("More Actions:")
509 html += '<div id="menu1"><ul>%(options)s</ul></div>' % data
510 return html
511
512
513
514
515
516
517 # Rick: We get to copy this in from __init__.py so that we can comment out the current page link.
518 def navibar(self, d):
519 """ Assemble the navibar
520
521 @param d: parameter dictionary
522 @rtype: unicode
523 @return: navibar html
524 """
525 request = self.request
526 found = {} # pages we found. prevent duplicates
527 items = [] # navibar items
528 item = u'<li class="%s">%s</li>'
529 current = d['page_name']
530
531 # Process config navi_bar
532 if request.cfg.navi_bar:
533 for text in request.cfg.navi_bar:
534 pagename, link = self.splitNavilink(text)
535 if pagename == current:
536 cls = 'wikilink current'
537 else:
538 cls = 'wikilink'
539 items.append(item % (cls, link))
540 found[pagename] = 1
541
542 # Add user links to wiki links, eliminating duplicates.
543 userlinks = request.user.getQuickLinks()
544 for text in userlinks:
545 # Split text without localization, user knows what he wants
546 pagename, link = self.splitNavilink(text, localize=0)
547 if not pagename in found:
548 if pagename == current:
549 cls = 'userlink current'
550 else:
551 cls = 'userlink'
552 items.append(item % (cls, link))
553 found[pagename] = 1
554
555 # Rick: This. This gets commented out to hide "current page" from navibar links.
556 """
557 # Add current page at end of local pages
558 if not current in found:
559 title = d['page'].split_title()
560 title = self.shortenPagename(title)
561 link = d['page'].link_to(request, title)
562 cls = 'current'
563 items.append(item % (cls, link))
564 """
565
566 # Add sister pages.
567 for sistername, sisterurl in request.cfg.sistersites:
568 if sistername == request.cfg.interwikiname: # it is THIS wiki
569 cls = 'sisterwiki current'
570 items.append(item % (cls, sistername))
571 else:
572 # TODO optimize performance
573 cache = caching.CacheEntry(request, 'sisters', sistername, 'farm', use_pickle=True)
574 if cache.exists():
575 data = cache.content()
576 sisterpages = data['sisterpages']
577 if current in sisterpages:
578 cls = 'sisterwiki'
579 url = sisterpages[current]
580 link = request.formatter.url(1, url) + \
581 request.formatter.text(sistername) +\
582 request.formatter.url(0)
583 items.append(item % (cls, link))
584
585 # Assemble html
586 items = u''.join(items)
587 html = u'''
588 <ul id="navibar">
589 %s
590 </ul>
591 ''' % items
592 return html
593
594
595
596 # Rick: Pasted in <div id="searchbuttons"> (don't forget the extra </div>) to break onto two lines. Also removed the extra size="20" so that we can make it pretty.
597 def searchform(self, d):
598 """
599 assemble HTML code for the search forms
600
601 @param d: parameter dictionary
602 @rtype: unicode
603 @return: search form html
604 """
605 _ = self.request.getText
606 form = self.request.form
607 updates = {
608 # Rick - commented out because we don't need it. We wrap this in the panel above:
609 #'search_label': _('Search:'),
610 'search_value': wikiutil.escape(form.get('value', [''])[0], 1),
611 'search_full_label': _('Text'),
612 'search_title_label': _('Titles'),
613 'baseurl': self.request.getScriptname(),
614 'pagename_quoted': wikiutil.quoteWikinameURL(d['page'].page_name),
615 }
616 d.update(updates)
617 # Rick - paste this in below if you want a needless field label.
618 # <label for="searchinput">%(search_label)s</label>
619 # Rick - I also whack the 'size' from input id because that belongs in CSS.
620 html = u'''
621 <form id="searchform" method="get" action="%(baseurl)s/%(pagename_quoted)s">
622 <div>
623 <input type="hidden" name="action" value="fullsearch">
624 <input type="hidden" name="context" value="180">
625
626 <input id="searchinput" type="text" name="value" value="%(search_value)s"
627 onfocus="searchFocus(this)" onblur="searchBlur(this)"
628 onkeyup="searchChange(this)" onchange="searchChange(this)" alt="this">
629 <div id="searchbuttons">
630 <input id="titlesearch" name="titlesearch" type="submit"
631 value="%(search_title_label)s" alt="Search Titles">
632 <input id="fullsearch" name="fullsearch" type="submit"
633 value="%(search_full_label)s" alt="Search Full Text">
634 </div>
635 </div>
636 </form>
637 <script type="text/javascript">
638 // Initialize search form
639 // var f = document.getElementById('searchform');
640 // f.getElementsByTagName('label')[0].style.display = 'none';
641 var e = document.getElementById('searchinput');
642 e.value = "";
643 searchChange(e);
644 searchBlur(e);
645 </script>
646 ''' % d
647 return html
648
649
650 # Rick: Here we comment out the code that does the "linkto:" code because it's too easy to accidently click in our theme.
651 # Rick: Use the WhatLinksToThis.py macro available on http://moinmo.in/MacroMarket
652 def title_with_separators(self, d):
653 """ Assemble the title using slashes, not <ul>
654
655 @param d: parameter dictionary
656 @rtype: string
657 @return: title html
658 """
659 _ = self.request.getText
660 if d['title_text'] == d['page'].split_title():
661 # just showing a page, no action
662 segments = d['page_name'].split('/')
663 link_text = segments[-1]
664 link_title = _('Click to do a full-text search for this title')
665 # Rick: commented out the below line:
666 #link_query = {'action': 'fullsearch', 'context': '180', 'value': 'linkto:"%s"' % d['page_name'], }
667
668 # Rick: We also delete 'querystr=link_query, title=link_title,' from this section:
669 link = d['page'].link_to(self.request, link_text, css_class='backlink', rel='nofollow')
670 if len(segments) <= 1:
671 html = link
672 else:
673 content = []
674 curpage = ''
675 for s in segments[:-1]:
676 curpage += s
677 content.append(Page(self.request,
678 curpage).link_to(self.request, s))
679 curpage += '/'
680 path_html = u'<span class="sep"> / </span>'.join(content)
681 # Rick: original: html = u'<span class="pagepath"> return to %s</span><span class="sep"> < </span>%s' % (path_html, link)
682 html = u'<span class="pagepath">%s</span><span class="sep"> / </span>%s' % (path_html, link)
683 else:
684 html = wikiutil.escape(d['title_text'])
685 # Modified by Leonardo Alviarez for correct translation
686 #return u'<span id="pagelocation">location: %s</span>' % html
687 return u'<span id="pagelocation">%s</span>' % html
688
689 # Rick: This is experimental feature for creating auto-backlinks. Basically identical to title_with_separators, except that it hides the current page. The backlink is only displayed on non-root pages (like subpages). Nothing fancy, just a new link description combined with CSS display:none tag.
690 def auto_backlink(self, d):
691 """ Assemble the title using slashes, not <ul>
692
693 @param d: parameter dictionary
694 @rtype: string
695 @return: title html
696 """
697 _ = self.request.getText
698 if d['title_text'] == d['page'].split_title():
699 # just showing a page, no action
700 segments = d['page_name'].split('/')
701 link_text = segments[-1]
702 link_title = _('Click to do a full-text search for this title')
703 # Rick: commented out the below line:
704 #link_query = {'action': 'fullsearch', 'context': '180', 'value': 'linkto:"%s"' % d['page_name'], }
705
706 # Rick: We also delete 'querystr=link_query, title=link_title,' from this section:
707 link = d['page'].link_to(self.request, link_text, css_class='backlink', rel='nofollow')
708 if len(segments) <= 1:
709 html = link
710 else:
711 content = []
712 curpage = ''
713 for s in segments[:-1]:
714 curpage += s
715 content.append(Page(self.request,
716 curpage).link_to(self.request, s))
717 curpage += '/'
718 path_html = u'<span class="sep"> / </span>'.join(content)
719 # Rick: original: html = u'<span class="pagepath"> return to %s</span><span class="sep"> < </span>%s' % (path_html, link)
720 html = u'<span class="pagepath_autobacklink">parent: %s</span><span class="sep"> / </span>' % (path_html)
721 else:
722 html = wikiutil.escape(d['title_text'])
723 return u'<span id="pagelocation_autobacklink">%s</span>' % html
724
725
726
727
728 # Rick: I copy this in from __init__.py so that I can change the last bit for CSS:
729 def username(self, d):
730 """ Assemble the username / userprefs link
731
732 @param d: parameter dictionary
733 @rtype: unicode
734 @return: username html
735 """
736 request = self.request
737 _ = request.getText
738
739 userlinks = []
740 # Add username/homepage link for registered users. We don't care
741 # if it exists, the user can create it.
742 if request.user.valid and request.user.name:
743 interwiki = wikiutil.getInterwikiHomePage(request)
744 name = request.user.name
745 aliasname = request.user.aliasname
746 if not aliasname:
747 aliasname = name
748 title = "%s @ %s" % (aliasname, interwiki[0])
749 # link to (interwiki) user homepage
750 homelink = (request.formatter.interwikilink(1, title=title, id="userhome", generated=True, *interwiki) +
751 request.formatter.text(name) +
752 request.formatter.interwikilink(0, title=title, id="userhome", *interwiki))
753 userlinks.append(homelink)
754 # link to userprefs action
755 if 'userprefs' not in self.request.cfg.actions_excluded:
756 # Modified by Leonardo Alviarez for correct translation
757 #userlinks.append(d['page'].link_to(request, text=_('settings'),
758 userlinks.append(d['page'].link_to(request, text=_('Settings'),
759 querystr={'action': 'userprefs'}, id='userprefs', rel='nofollow'))
760
761 if request.user.valid:
762 if request.user.auth_method in request.cfg.auth_can_logout:
763 # Modified by Leonardo Alviarez for correct translation
764 #userlinks.append(d['page'].link_to(request, text=_('logout'),
765 userlinks.append(d['page'].link_to(request, text=_('Logout'),
766 querystr={'action': 'logout', 'logout': 'logout'}, id='logout', rel='nofollow'))
767 else:
768 query = {'action': 'login'}
769 # special direct-login link if the auth methods want no input
770 if request.cfg.auth_login_inputs == ['special_no_input']:
771 query['login'] = '1'
772 if request.cfg.auth_have_login:
773 # Modified by Leonardo Alviarez for correct translation
774 #userlinks.append(d['page'].link_to(request, text=_("please sign in"),
775 userlinks.append(d['page'].link_to(request, text=_("Login"),
776 querystr=query, id='login', rel='nofollow'))
777
778 # Rick added this to get the welcome in there:
779 userlinks_html = u' | '.join(userlinks)
780 # Modified by Leonardo Alviarez for correct translation
781 #html = u'<div id="username">welcome: %s</div>' % userlinks_html
782 html = u'<div id="username">%s</div>' % userlinks_html
783 return html
784
785
786
787 # Rick: here we copy in the maxPagenameLength from __init__.py so that we can shorten it so that it fits in our panels.
788 # Rick; effects "Recently Viewed" as well as "quick links". (original value: 25).
789 def maxPagenameLength(self):
790 """ Return maximum length for shortened page names """
791 return 21
792
793
794
795 #
796 # Rick: Let's re-write some def Links so that we can make them human-readable!
797 # This entire section is untouched code-wise, except to just change the "text=_('something descriptive'),"
798 #
799
800 # originally 'Info'
801 def infoLink(self, page):
802 """ Return link to page information """
803 if 'info' in self.request.cfg.actions_excluded:
804 return ""
805 _ = self.request.getText
806 return page.link_to(self.request,
807 # Modified by Leonardo Alviarez for correct translation
808 #text=_('page history'),
809 text=_('Info'),
810 querystr={'action': 'info'}, rel='nofollow')
811
812
813 # originally 'Attachments'
814 def attachmentsLink(self, page):
815 """ Return link to page attachments """
816 if 'AttachFile' in self.request.cfg.actions_excluded:
817 return ""
818 _ = self.request.getText
819 return page.link_to(self.request,
820 # Modified by Leonardo Alviarez for correct translation
821 #text=_('upload & manage files'),
822 text=_('Attachments'),
823 querystr={'action': 'AttachFile'}, rel='nofollow')
824
825
826 # originally 'Immutable Page'
827 def disabledEdit(self):
828 """ Return a disabled edit link """
829 _ = self.request.getText
830 return ('<span class="disabled">%s</span>'
831 # Modified by Leonardo Alviarez for correct translation
832 #% _('Page Locked'))
833 % _('Immutable Page'))
834
835
836 # originally 'Subscribe' and 'Unsubscribe'
837 def subscribeLink(self, page):
838 """ Return subscribe/unsubscribe link to valid users
839
840 @rtype: unicode
841 @return: subscribe or unsubscribe link
842 """
843 if not ((self.cfg.mail_enabled or self.cfg.jabber_enabled) and self.request.user.valid):
844 return ''
845 _ = self.request.getText
846 if self.request.user.isSubscribedTo([page.page_name]):
847 # Modified by Leonardo Alviarez for correct translation
848 #action, text = 'unsubscribe', _("stop email updates")
849 action, text = 'unsubscribe', _("Unsubscribe")
850 else:
851 # Modified by Leonardo Alviarez for correct translation
852 #action, text = 'subscribe', _("email me changes")
853 action, text = 'subscribe', _("Subscribe")
854 if action in self.request.cfg.actions_excluded:
855 return ""
856 return page.link_to(self.request, text=text, querystr={'action': action}, rel='nofollow')
857
858
859 # originally 'Add Link' and 'Remove Link'
860 def quicklinkLink(self, page):
861 """ Return add/remove quicklink link
862
863 @rtype: unicode
864 @return: link to add or remove a quicklink
865 """
866 if not self.request.user.valid:
867 return ''
868
869 _ = self.request.getText
870 if self.request.user.isQuickLinkedTo([page.page_name]):
871 # Modified by Leonardo Alviarez for correct translation
872 #action, text = 'quickunlink', _("remove from quicklinks")
873 action, text = 'quickunlink', _("Remove Link")
874 else:
875 # Modified by Leonardo Alviarez for correct translation
876 #action, text = 'quicklink', _("add to quicklinks")
877 action, text = 'quicklink', _("Add Link")
878 if action in self.request.cfg.actions_excluded:
879 return ""
880 return page.link_to(self.request, text=text, querystr={'action': action}, css_class='nbquicklink', rel='nofollow')
881
882
883
884 # originally 'Edit'
885 # P.S. not going to bother copying in "def guiEditorScript" because we set "editor_ui = 'theonepreferred'" in the farmconfig.py.
886 def editorLink(self, page):
887 """ Return a link to the editor
888
889 If the user can't edit, return a disabled edit link.
890
891 If the user want to show both editors, it will display "Edit
892 (Text)", otherwise as "Edit".
893 """
894 if 'edit' in self.request.cfg.actions_excluded:
895 return ""
896
897 if not (page.isWritable() and
898 self.request.user.may.write(page.page_name)):
899 return self.disabledEdit()
900
901 _ = self.request.getText
902 querystr = {'action': 'edit'}
903
904 guiworks = self.guiworks(page)
905 if self.showBothEditLinks() and guiworks:
906 # Rick: This.
907 text = _('Edit (Text)')
908 querystr['editor'] = 'text'
909 attrs = {'name': 'texteditlink', 'rel': 'nofollow', }
910 else:
911 # Rick: And this.
912 # Modified by Leonardo Alviarez for correct translation
913 #text = _('edit this page')
914 text = _('Edit')
915 if guiworks:
916 # 'textonly' will be upgraded dynamically to 'guipossible' by JS
917 querystr['editor'] = 'textonly'
918 attrs = {'name': 'editlink', 'rel': 'nofollow', }
919 else:
920 querystr['editor'] = 'text'
921 attrs = {'name': 'texteditlink', 'rel': 'nofollow', }
922
923 return page.link_to(self.request, text=text, querystr=querystr, **attrs)
924
925
926 #
927 # End def link re-writes.
928 #
929
930 #
931 # Rick: The rest of these are carried over from Modernized, and are unmodified:
932 #
933
934
935 def editorheader(self, d, **kw):
936 """ Assemble wiki header for editor
937
938 @param d: parameter dictionary
939 @rtype: unicode
940 @return: page header html
941 """
942 html = [
943 # Pre header custom html
944 self.emit_custom_html(self.cfg.page_header1),
945
946 # Header
947 u'<div id="header">',
948 u'<h1 id="locationline">',
949 self.title(d),
950 u'</h1>',
951 self.msg(d),
952 u'</div>',
953
954 # Post header custom html (not recommended)
955 self.emit_custom_html(self.cfg.page_header2),
956
957 # Start of page
958 self.startPage(),
959 ]
960 return u'\n'.join(html)
961
962
963 def footer(self, d, **keywords):
964 """ Assemble wiki footer
965
966 @param d: parameter dictionary
967 @keyword ...:...
968 @rtype: unicode
969 @return: page footer html
970 """
971 page = d['page']
972 html = [
973 # End of page
974 self.pageinfo(page),
975 self.endPage(),
976
977 # Pre footer custom html (not recommended!)
978 self.emit_custom_html(self.cfg.page_footer1),
979
980 # Footer
981 u'<div id="footer">',
982 self.credits(d),
983 self.showversion(d, **keywords),
984 u'</div>',
985
986 # Post footer custom html
987 self.emit_custom_html(self.cfg.page_footer2),
988 ]
989 return u'\n'.join(html)
990
991
992
993 def title(self, d):
994 """ Assemble the title (now using breadcrumbs)
995
996 @param d: parameter dictionary
997 @rtype: string
998 @return: title html
999 """
1000 _ = self.request.getText
1001 content = []
1002 if d['title_text'] == d['page'].split_title(): # just showing a page, no action
1003 curpage = ''
1004 segments = d['page_name'].split('/') # was: title_text
1005 for s in segments[:-1]:
1006 curpage += s
1007 content.append(Page(self.request, curpage).link_to(self.request, s))
1008 curpage += '/'
1009 link_text = segments[-1]
1010 link_title = _('Click to do a full-text search for this title')
1011 link_query = {
1012 'action': 'fullsearch',
1013 'value': 'linkto:"%s"' % d['page_name'],
1014 'context': '180',
1015 }
1016 # we dont use d['title_link'] any more, but make it ourselves:
1017 link = d['page'].link_to(self.request, link_text, querystr=link_query, title=link_title, css_class='backlink', rel='nofollow')
1018 content.append(link)
1019 else:
1020 content.append(wikiutil.escape(d['title_text']))
1021
1022 location_html = u'<span class="sep">/</span>'.join(content)
1023 html = u'<span id="pagelocation">%s</span>' % location_html
1024 return html
1025
1026
1027
1028 def interwiki(self, d):
1029 """ Assemble the interwiki name display, linking to page_front_page
1030
1031 @param d: parameter dictionary
1032 @rtype: string
1033 @return: interwiki html
1034 """
1035 if self.request.cfg.show_interwiki:
1036 page = wikiutil.getFrontPage(self.request)
1037 text = self.request.cfg.interwikiname or 'Self'
1038 link = page.link_to(self.request, text=text, rel='nofollow')
1039 html = u'<span id="interwiki">%s<span class="sep">: </span></span>' % link
1040 else:
1041 html = u''
1042 return html
1043
1044 def execute(request):
1045 """
1046 Generate and return a theme object
1047
1048 @param request: the request object
1049 @rtype: MoinTheme
1050 @return: Theme object
1051 """
1052 return Theme(request)
Archivos adjuntos
Para referirse a los adjuntos de una página, usa attachment:nombredelarchivo, como se muestra abajo en la lista de archivos. NO uses la URL del enlace [get], ya que puede cambiar fácilmente y dejar de funcionar.- [obtener | ver] (2013-04-30 15:34:28, 0.7 KB) [[attachment:actionmenuoptions.js]]
- [obtener | ver] (2013-04-30 15:33:56, 42.8 KB) [[attachment:moniker19.py]]
No tienes permisos para adjuntar un archivo a esta página.
