Short description
Sometimes a page should display some of its attributes, such as
- revision number
- modification date
- history list
Such values could be displayed via a macro.
[[PageInfo(revision)]] [[PageInfo(modifytime)]] [[PageInfo(history)]]
Another way is via variables.
@REVISION@ @MODIFYTIME@ @HISTORY@
The advantage of variables over a macro is the embedding of the variable value into the page.
The advantage of a macro over variables is the use of a macro in a Template, such that the user need never change the parts of the document which report these document statistics.
Sample Macro
Here is the code for a prototype macro which implements this functionality. It is broken in that it can only access the latest page revision's information. (When viewing a historic version of a page, the macro still displays the latest version's date or revision number.)
Yes, that's a copy of wikiaction.do_info()'s private history() method, used to format the history table. Consider this as an inline request for a first-class history() method. Ideally the "Diff" and "Actions" columns should disappear if we are in a print view. The only change is to remove the "Revision History" header.
1 # -*- coding: iso-8859-1 -*-
2 """
3 MoinMoin - PageInfo Macro
4
5 This generally complicated macro returns information about the
6 current page.
7
8 Invokation from within a page:
9 [[PageInfo(history)]] dumps the equivalent of the 'info' action's
10 history display into the document.
11 [[PageInfo(modifytime)]] returns the modify time (save time) of the
12 page.
13 [[PageInfo(revision)]] returns the revision number of the page.
14
15 The history() method is snarfed directly from MoinMoin 1.5.0's
16 wikiaction handler. Changes from that version are marked by "# CHG" --
17 either commenting out deletions, or bracketing additions.
18
19 @copyright: 2006 by Matthew Cary <carym@onebox.com>
20 @license: GNU GPL, see COPYING for details.
21 """
22
23 Dependencies = []
24
25 import os
26 from MoinMoin import util, wikiutil
27
28 def execute(macro, args):
29
30 ## begin shamelessly copied from MoinMoin 1.5.0's wikiaction.py:246
31 def history(page, pagename, request):
32 # CHG begin
33 current_action = request.form.get('action', ['show'])[0]
34 ## 'print view' is simply a CSS overlay on the normal views.
35 ## We can't really detect it, so disable diff and action
36 ## columns for now.
37 normal_display = (1==0)
38 ## normal_display = (current_action in ['bookmark', 'recall', 'refresh', 'show', 'subscribe'])
39 ## request.write('[Current action: ' + current_action + ']<br>\n')
40 ## request.write('[normal display: ')
41 ## if normal_display:
42 ## request.write('true')
43 ## else:
44 ## request.write('false')
45 ## request.write(']<br>\n')
46 # CHG end
47 # show history as default
48 _ = request.getText
49
50 # open log for this page
51 from MoinMoin.logfile import editlog
52 from MoinMoin.util.dataset import TupleDataset, Column
53
54 history = TupleDataset()
55 # CHG begin
56 if normal_display:
57 history.columns = [
58 Column('rev', label='#', align='right'),
59 Column('mtime', label=_('Date'), align='right'),
60 Column('size', label=_('Size'), align='right'),
61 Column('diff', label='<input type="submit" value="%s">' % (_("Diff"))),
62 Column('editor', label=_('Editor'), hidden=not request.cfg.show_hosts),
63 Column('comment', label=_('Comment')),
64 Column('action', label=_('Action')),
65 ]
66 else:
67 history.columns = [
68 Column('rev', label='#', align='right'),
69 Column('mtime', label=_('Date'), align='right'),
70 # no 'diff'
71 Column('size', label=_('Size'), align='right'),
72 Column('editor', label=_('Editor'), hidden=not request.cfg.show_hosts),
73 Column('comment', label=_('Comment')),
74 # no 'action'
75 ]
76 # CHG end
77
78 # generate history list
79 revisions = page.getRevList()
80 versions = len(revisions)
81
82 may_revert = request.user.may.revert(pagename)
83
84 # read in the complete log of this page
85 log = editlog.EditLog(request, rootpagename=pagename)
86 count = 0
87 for line in log.reverse():
88 rev = int(line.rev)
89 actions = ""
90 if line.action in ['SAVE','SAVENEW','SAVE/REVERT',]:
91 # CHG begin
92 if normal_display:
93 # CHG end
94 if count == 0: # latest page
95 actions = '%s %s' % (actions, page.link_to(request,
96 text=_('view'),
97 querystr=''))
98 actions = '%s %s' % (actions, page.link_to(request,
99 text=_('raw'),
100 querystr='action=raw'))
101 actions = '%s %s' % (actions, page.link_to(request,
102 text=_('print'),
103 querystr='action=print'))
104 else:
105 actions = '%s %s' % (actions, page.link_to(request,
106 text=_('view'),
107 querystr='action=recall&rev=%d' % rev))
108 actions = '%s %s' % (actions, page.link_to(request,
109 text=_('raw'),
110 querystr='action=raw&rev=%d' % rev))
111 actions = '%s %s' % (actions, page.link_to(request,
112 text=_('print'),
113 querystr='action=print&rev=%d' % rev))
114 if may_revert:
115 actions = '%s %s' % (actions, page.link_to(request,
116 text=_('revert'),
117 querystr='action=revert&rev=%d' % (rev,)))
118 if count == 0:
119 rchecked=' checked="checked"'
120 lchecked = ''
121 elif count == 1:
122 lchecked=' checked="checked"'
123 rchecked = ''
124 else:
125 lchecked = rchecked = ''
126 diff = '<input type="radio" name="rev1" value="%d"%s><input type="radio" name="rev2" value="%d"%s>' % (rev,lchecked,rev,rchecked)
127
128 comment = line.comment
129 if not comment and line.action.find('/REVERT') != -1:
130 comment = _("Revert to revision %(rev)d.") % {'rev': int(line.extra)}
131 size = page.size(rev=rev)
132 else: # ATT*
133 rev = '-'
134 diff = '-'
135
136 filename = wikiutil.url_unquote(line.extra)
137 comment = "%s: %s %s" % (line.action, filename, line.comment)
138 size = 0
139 if line.action != 'ATTDEL':
140 from MoinMoin.action import AttachFile
141 page_dir = AttachFile.getAttachDir(request, pagename)
142 filepath = os.path.join(page_dir, filename)
143 try:
144 # FIXME, wrong path on non-std names
145 size = os.path.getsize(filepath)
146 except:
147 pass
148 # CHG begin
149 if normal_display:
150 # CHG end
151 if line.action == 'ATTNEW':
152 actions = '%s %s' % (actions, page.link_to(request,
153 text=_('view'),
154 querystr='action=AttachFile&do=view&target=%s' % filename))
155 elif line.action == 'ATTDRW':
156 actions = '%s %s' % (actions, page.link_to(request,
157 text=_('edit'),
158 querystr='action=AttachFile&drawing=%s' % filename.replace(".draw","")))
159
160 actions = '%s %s' % (actions, page.link_to(request,
161 text=_('get'),
162 querystr='action=AttachFile&do=get&target=%s' % filename))
163 actions = '%s %s' % (actions, page.link_to(request,
164 text=_('del'),
165 querystr='action=AttachFile&do=del&target=%s' % filename))
166 # XXX use?: wikiutil.escape(filename)
167
168 # CHG begin
169 if normal_display:
170 history.addRow((
171 rev,
172 request.user.getFormattedDateTime(wikiutil.version2timestamp(line.ed_time_usecs)),
173 str(size),
174 diff,
175 line.getEditor(request) or _("N/A"),
176 wikiutil.escape(comment) or ' ',
177 actions,
178 ))
179 else:
180 history.addRow((
181 rev,
182 request.user.getFormattedDateTime(wikiutil.version2timestamp(line.ed_time_usecs)),
183 str(size),
184 # no 'diff'
185 line.getEditor(request) or _("N/A"),
186 wikiutil.escape(comment) or ' ',
187 # no 'action'
188 ))
189 # CHG end
190 count += 1
191 if count >= 100:
192 break
193
194 # print version history
195 from MoinMoin.widget.browser import DataBrowserWidget
196
197 # CHG begin
198 ## request.write('<h2>%s</h2>\n' % _('Revision History'))
199 request.write(
200 'To view previous revisions or compare revisions, please see the %s page.<br>\n' %
201 page.link_to(request, text=_('info'), querystr='action=info'))
202 # CHG end
203
204 if not count: # there was no entry in logfile
205 request.write(_('No log entries found.'))
206 return
207
208 # TODO: this form activates revert, which should use POST, but
209 # other actions should use get. Maybe we should put the revert
210 # into the page view itself, and not in this form.
211 request.write('<form method="GET" action="">\n')
212 request.write('<div id="page-history">\n')
213 request.write('<input type="hidden" name="action" value="diff">\n')
214
215 history_table = DataBrowserWidget(request)
216 history_table.setData(history)
217 history_table.render()
218 request.write('</div>\n')
219 request.write('</form>\n')
220 ## end shamelessly copied from MoinMoin 1.5.0's wikiaction.py:246
221
222
223 result = None
224 if args == 'modifytime' :
225 result = macro.request.page.lastEditInfo()
226 if result:
227 result = result['time']
228 elif args == 'revision' :
229 result = macro.request.page.get_real_rev()
230 if result == 0 :
231 result = '0 (Cannot determine history revision??)'
232 elif args == 'history' :
233 # dump out Info page
234 ## attempt 1
235 ## from MoinMoin.wikiaction import getHandler
236 ## handler = getHandler(macro.request, 'info')
237 ## # presently this dumps raw HTML into the page
238 ## handler(macro.request.page.page_name, macro.request)
239
240 ## attempt 2
241 ## from MoinMoin.wikiaction.do_info import history
242 ## # presently this dumps raw HTML into the page
243 ## history(macro.request.page, macro.request.page.page_name, macro.request)
244
245 ## attempt 3
246 ## from MoinMoin.wikiaction.do_info copy history !!
247 # presently this dumps raw HTML into the page
248 history(macro.request.page, macro.request.page.page_name, macro.request)
249 else:
250 result = '[Unknown page property "' + args + '"]'
251
252 if result == None or result == {} :
253 result = ''
254 if not isinstance( result, basestring ) :
255 result = str( result )
256
257 return macro.request.formatter.rawHTML(result)
-- MatthewCary 2006-02-23 03:04:14
Revision History
Updated PageInfo.py source:
- hide the "Diff" and "Actions" history columns when the display mode is something other than the basic web page display. (eg. for printing etc)
- fix some bugs related to first-revision pages
One significant bug remains: how to get the revision information (rev number, modify time, etc) for a specific version of the page? This probably means walking the editlog directly, instead of relying on the methods on Page.
-- MatthewCary 2006-02-24 21:32:39
Updated PageInfo.py source:
- import os to allow history()'s attachment handling to function.
-- MatthewCary 2006-03-01 19:50:48