6
6
and/or dynamic page content.
8
8
The canonical interface to plugin macros is their execute() function,
9
which gets passed an instance of the Macro class.
9
which gets passed an instance of the Macro class. Such an instance
10
has the four members parser, formatter, form and request.
12
Using "form" directly is deprecated and should be replaced by "request.form".
11
14
@copyright: 2000-2004 Juergen Hermann <jh@web.de>,
12
2006-2009 MoinMoin:ThomasWaldmann,
15
2006-2007 MoinMoin:ThomasWaldmann,
13
16
2007 MoinMoin:JohannesBerg
14
17
@license: GNU GPL, see COPYING for details.
17
20
from MoinMoin.util import pysupport
18
21
modules = pysupport.getPackageModules(__file__)
20
from MoinMoin import log
21
logging = log.getLogger(__name__)
23
23
import re, time, os
24
24
from MoinMoin import action, config, util
25
25
from MoinMoin import wikiutil, i18n
26
26
from MoinMoin.Page import Page
27
from MoinMoin.datastruct.backends.wiki_dicts import WikiDict
30
29
names = ["TitleSearch", "WordIndex", "TitleIndex", "GoTo",
75
74
"GetVal": ["pages"],
77
# we need the lang macros to execute when html is generated,
78
# to have correct dir and lang html attributes
79
for lang in i18n.wikiLanguages():
80
Dependencies[lang] = []
79
83
def __init__(self, parser):
80
84
self.parser = parser
81
#self.form --> gone, please use self.request.{form,args,values}
85
self.form = self.parser.form
82
86
self.request = self.parser.request
83
87
self.formatter = self.request.formatter
84
88
self._ = self.request.getText
87
91
# Initialized on execute
90
# we need the lang macros to execute when html is generated,
91
# to have correct dir and lang html attributes
92
# note: i18n needs to be initialized first before .wikiLanguages() will work
93
for lang in i18n.wikiLanguages():
94
self.Dependencies[lang] = []
94
def _wrap(self, function, args, fixed=[]):
96
return wikiutil.invoke_extension_function(self.request, function,
99
return self.format_error(e)
101
def format_error(self, err):
102
""" format an error object for output instead of normal macro output """
103
return self.formatter.text(u'<<%s: %s>>' % (self.name, err.args[0]))
96
105
def execute(self, macro_name, args):
97
106
""" Get and execute a macro
104
113
call = wikiutil.importPlugin(self.cfg, 'macro', macro_name,
105
114
function='macro_%s' % macro_name)
106
execute = lambda _self, _args: wikiutil.invoke_extension_function(
107
_self.request, call, _args, [_self])
115
execute = lambda _self, _args: _self._wrap(call, _args, [self])
108
116
except wikiutil.PluginAttributeError:
109
117
# fall back to old execute() method, no longer recommended
110
118
execute = wikiutil.importPlugin(self.cfg, 'macro', macro_name)
111
119
except wikiutil.PluginMissingError:
113
121
call = getattr(self, 'macro_%s' % macro_name)
114
execute = lambda _self, _args: wikiutil.invoke_extension_function(
115
_self.request, call, _args, [])
122
execute = lambda _self, _args: _self._wrap(call, _args)
116
123
except AttributeError:
117
124
if macro_name in i18n.wikiLanguages():
118
125
execute = self.__class__._m_lang
120
127
raise ImportError("Cannot load macro %s" % macro_name)
122
return execute(self, args)
123
except Exception, err:
124
# we do not want that a faulty macro aborts rendering of the page
125
# and makes the wiki UI unusable (by emitting a Server Error),
126
# thus, in case of exceptions, we just log the problem and return
127
# some standard text.
129
page_spec = " (page: '%s')" % self.formatter.page.page_name
132
logging.exception("Macro %s%s raised an exception:" % (self.name, page_spec))
133
_ = self.request.getText
134
return self.formatter.text(_('<<%(macro_name)s: execution failed [%(error_msg)s] (see also the log)>>') % {
135
'macro_name': self.name,
136
'error_msg': err.args[0], # note: str(err) or unicode(err) does not work for py2.4/5/6
139
logging.info("Stack:\n" + traceback.format_stack())
128
return execute(self, args)
141
130
def _m_lang(self, text):
142
131
""" Set the current language for page content.
204
193
request = self.request
205
194
fmt = self.formatter
206
allpages = int(request.values.get('allpages', 0)) != 0
195
allpages = int(self.form.get('allpages', [0])[0]) != 0
207
196
# Get page list readable by current user, filter by isSystemPage if needed
209
198
pages = request.rootpage.getPageList()
233
222
for word in all_words:
234
223
letter = wikiutil.getUnicodeIndexGroup(word)
235
224
if letter != current_letter:
236
anchor = "idx-%s" % letter
237
output.append(fmt.anchordef(anchor))
238
output.append(fmt.heading(1, 2))
225
cssid = "idx" + wikiutil.quoteWikinameURL(letter).replace('%', '')
226
output.append(fmt.heading(1, 2, id=cssid)) # fmt.anchordef didn't work
239
227
output.append(fmt.text(letter.replace('~', 'Others')))
240
228
output.append(fmt.heading(0, 2))
241
229
current_letter = letter
261
249
def _make_index_key(index_letters):
262
250
index_letters.sort()
263
251
def letter_link(ch):
264
anchor = "idx-%s" % ch
265
return fmt.anchorlink(1, anchor) + fmt.text(ch.replace('~', 'Others')) + fmt.anchorlink(0)
252
cssid = "idx" + wikiutil.quoteWikinameURL(ch).replace('%', '')
253
return fmt.anchorlink(1, cssid) + fmt.text(ch.replace('~', 'Others')) + fmt.anchorlink(0)
266
254
links = [letter_link(letter) for letter in index_letters]
267
255
return ' | '.join(links)
295
u'<form method="get" action="%s"><div>' % self.request.href(self.formatter.page.page_name),
283
u'<form method="get" action="%s/%s"><div>' % (self.request.getScriptname(), wikiutil.quoteWikinameURL(self.formatter.page.page_name)),
297
285
u'<input type="hidden" name="action" value="goto">',
298
286
u'<input type="text" name="target" size="30">',
386
374
def macro_GetVal(self, page=None, key=None):
387
375
page = wikiutil.get_unicode(self.request, page, 'page')
376
if not self.request.user.may.read(page):
377
raise ValueError("You don't have enough rights on this page")
389
378
key = wikiutil.get_unicode(self.request, key, 'key')
390
379
if page is None or key is None:
391
380
raise ValueError("You need to give: pagename, key")
393
d = self.request.dicts.get(page, {})
395
# Check acl only if dictionary is defined on a wiki page.
396
if isinstance(d, WikiDict) and not self.request.user.may.read(page):
397
raise ValueError("You don't have enough rights on this page")
381
d = self.request.dicts.dict(page)
399
382
result = d.get(key, '')
401
383
return self.formatter.text(result)