Short description

Sometimes a page should display some of its attributes, such as

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&nbsp;%s' % (actions, page.link_to(request,
  96                             text=_('view'),
  97                             querystr=''))
  98                         actions = '%s&nbsp;%s' % (actions, page.link_to(request,
  99                             text=_('raw'),
 100                             querystr='action=raw'))
 101                         actions = '%s&nbsp;%s' % (actions, page.link_to(request,
 102                             text=_('print'),
 103                             querystr='action=print'))
 104                     else:
 105                         actions = '%s&nbsp;%s' % (actions, page.link_to(request,
 106                             text=_('view'),
 107                             querystr='action=recall&rev=%d' % rev))
 108                         actions = '%s&nbsp;%s' % (actions, page.link_to(request,
 109                             text=_('raw'),
 110                             querystr='action=raw&rev=%d' % rev))
 111                         actions = '%s&nbsp;%s' % (actions, page.link_to(request,
 112                             text=_('print'),
 113                             querystr='action=print&rev=%d' % rev))
 114                         if may_revert:
 115                             actions = '%s&nbsp;%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&nbsp;%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&nbsp;%s' % (actions, page.link_to(request,
 157                                 text=_('edit'),
 158                                 querystr='action=AttachFile&drawing=%s' % filename.replace(".draw","")))
 159 
 160                         actions = '%s&nbsp;%s' % (actions, page.link_to(request,
 161                             text=_('get'),
 162                             querystr='action=AttachFile&do=get&target=%s' % filename))
 163                         actions = '%s&nbsp;%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 '&nbsp;',
 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 '&nbsp;',
 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:

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:

-- MatthewCary 2006-03-01 19:50:48


CategoryFeatureRequest

MoinMoin: FeatureRequests/PageInfo (last edited 2007-10-29 19:09:47 by localhost)