These are the changes I've made to my own wikis. I'm posting them in case they're useful for someone else.

Some of these are clearly ugly hacks. I'm just getting started with moinmoin, so I haven't yet learned enough about the codebase to make changes in the right way, in the right places. As I read stuff like MoinDev/CodeStructure, MoinDev/PluginConcept, and Writing Macros I hope to improve this. Feel free to educate me. :-)

These changes are to a system with MoinMoin version 1.5.5a and MentalWealth version 0.95.2.

MoinMoin

  1. SystemInfo only for superuser.

  2. Action=test only for superuser.
  3. No tracebacks if not debug mode.
  4. Debug from querystring only for superuser.
  5. Action=test for fcgi.
  6. Alt-<X> accesskeys.

  7. Preserved linebreaks.

Several of these changes are in the spirit of FixLeaks.

SystemInfo only for superuser. I put this at the start of _macro_SystemInfo in wikimacro.py:

        if not self.request.user.isSuperUser():
            return "System Information is not available."

Action=test only for superuser. I modified wikiaction.py's do_test as follows:

def do_test(pagename, request):
    from MoinMoin.wikitest import runTest
    request.http_headers(["Content-type: text/plain;charset=%s" % config.charset])
    if request.user.isSuperUser():
        request.write('MoinMoin Diagnostics\n======================\n\n')
        runTest(request)
    else:
        request.write('Test results unavailable.\n')
    raise MoinMoinNoFooter

No tracebacks if not debug mode. I changed View.formatContent in failure.py so that the output depends on self.debug:

    def formatContent(self):
        content = [
            self.script(),
            self.formatStylesheet(),
            self.formatTitle(),
            self.formatMessage()
            ]
        if self.debug:
            content += [
                self.formatButtons(),
                self.formatDebugInfo(),
                self.formatTextTraceback()
                ]
        return ''.join(content)

Debug from querystring only for superuser. Since debug mode gives access to stack traces that might be overly revealing, I changed failure.py's handle() to restrict taking debug from the querystring:

--- old-failure.py  2006-10-19 21:54:08.000000000 -0700
+++ new-failure.py  2006-10-19 21:54:39.000000000 -0700
@@ -140,8 +140,9 @@
     """
     savedError = sys.exc_info()
     try:
-        debug = ('debug' in getattr(request, 'form', {}) or
-                 'MOIN_DEBUG' in os.environ)
+        debug = 'MOIN_DEBUG' in os.environ
+        if not debug and 'debug' in getattr(request, 'form', {}):
+            debug = request.user.isSuperUser()
         handler = cgitb.Hook(file=request, viewClass=View, debug=debug)
         handler.handle()
     except:

Action=test for fcgi. I changed the call to TextTestRunner at the bottom of _tests/__init__.py to write the results to a file in the log directory, and to write a summary to the webpage:

    f = open("/path/to/where/you/want/to/save/results", "w")
    results = TextTestRunner(stream=f, verbosity=2).run(suite)
    f.close()
    if results.wasSuccessful():
        request.write("    %d tests completed successfully.\n" % results.testsRun)
    else:
        request.write("    %d tests run.\n" % results.testsRun)
        for failure in results.failures:
            request.write("    FAIL: %s\n" % failure[0])
        for error in results.errors:
            request.write("    ERROR: %s\n" % error[0])
    request.write("    See file in logging directory for details.\n")

Alt-<X> accesskeys. I added alt-S for Save and alt-P for Preview on the editor pages, and support for accesskeys in links, which I used below to add alt-M for edit(modify) in the mentalwealth theme.

diff -ur old/PageEditor.py new/PageEditor.py
--- old/PageEditor.py   2006-10-19 22:04:55.000000000 -0700
+++ new/PageEditor.py   2006-10-19 22:08:27.000000000 -0700
@@ -331,8 +331,8 @@


         self.request.write('''
-<input class="button" type="submit" name="button_save" value="%s" onClick="flgChange = false;">
-<input class="button" type="submit" name="button_preview" value="%s" onClick="flgChange = false;">
+<input class="button" type="submit" name="button_save" value="%s" onClick="flgChange = false;" accesskey="S">
+<input class="button" type="submit" name="button_preview" value="%s" onClick="flgChange = false;" accesskey="P">
 ''' % (save_button_text, _('Preview'),))

         if not (self.request.cfg.editor_force and self.request.cfg.editor_default == 'text'):
diff -ur old/PageGraphicalEditor.py new/PageGraphicalEditor.py
--- old/PageGraphicalEditor.py  2006-10-19 22:04:59.000000000 -0700
+++ new/PageGraphicalEditor.py  2006-10-19 22:09:12.000000000 -0700
@@ -237,8 +237,8 @@
             }, '</em></p>')

         self.request.write('''
-<input class="button" type="submit" name="button_save" value="%s">
-<input class="button" type="submit" name="button_preview" value="%s">
+<input class="button" type="submit" name="button_save" value="%s" accesskey="S">
+<input class="button" type="submit" name="button_preview" value="%s" accesskey="P">
 <input class="button" type="submit" name="button_switch" value="%s">
 %s
 <input class="button" type="submit" name="button_cancel" value="%s">
diff -ur old/wikiutil.py new/wikiutil.py
--- old/wikiutil.py 2006-10-19 22:05:04.000000000 -0700
+++ new/wikiutil.py 2006-10-19 22:14:30.000000000 -0700
@@ -1098,6 +1098,7 @@
         css_class = None
     id = kw.get('id', None)
     name = kw.get('name', None)
+    accesskey = kw.get('accesskey', None)
     if text is None:
         text = params # default
     if formatter:
@@ -1117,6 +1118,8 @@
         attrs += ' id="%s"' % id
     if name:
         attrs += ' name="%s"' % name
+    if accesskey:
+        attrs += ' accesskey="%s"' % accesskey
     result = '<a%s href="%s/%s">' % (attrs, request.getScriptname(), params)
     if on:
         return result

Preserved linebreaks. This is definitely a hack, but it's also the change that I'm happiest with as a user. I make heavy use of plain text with linebreaks, especially for simple "lists". These are not lists in an html sense -- I don't want numbers or letters or bullets or special spacing. It's not text without markup -- I still want bold, italic, links, and so forth. These are just lines of text like you might type into notepad or vi. And in moinmoin, what you would get by putting [[BR]] at the end of each line. But using the macro gets tiresome very quickly. Imagine if you had to put [[BR]] at the end of every line in notepad or vi, or every line of source code, or else the lines would be merged in a printout. No way. When you hit Return, you mean Return -- the text after Return should start on a new line. In the GUI editor, when two lines abut vertically in the editor, they should not have an intervening line when saved. Paragraphs are separated by two such Returns. And if there really is the need to support "I want this line and the next to appear without an intervening linebreak, but nonetheless I want to divide the text into multiple physical lines" then that is the case that should require additional effort. As in many programming languages, you could end the line with a line-continuation macro/marker.

The code below tries to preserve these linebreaks, while also trying to be cautious about interfering with other macros and markup. It's just a rough hack. I'm looking forward to learning how to do this the right way.

--- old-wiki.py 2006-10-19 20:27:07.000000000 -0700
+++ new-wiki.py 2006-10-19 20:25:42.000000000 -0700
@@ -954,6 +954,8 @@

         self.in_processing_instructions = 1

+        want_implicit_break = False
+
         # Main loop
         for line in self.lines:
             self.lineno += 1
@@ -1100,6 +1102,14 @@

             # Scan line, format and write
             formatted_line = self.scan(scan_re, line)
+            break_ok = not (self.in_list or self.in_li or self.in_dd or
+                            self.in_table or self.in_pre or
+                            self.line_is_empty)
+            if break_ok and want_implicit_break:
+                self.request.write("<br />")
+            want_implicit_break = (break_ok and
+                                   '[[' not in line and
+                                   '<hr ' not in formatted_line)
             self.request.write(formatted_line)

             if self.in_pre == 3:

MentalWealth

  1. Converted line-endings and tabs.
  2. Added accesskey for edit link.
  3. Added Quicklink action link.
  4. Added page title and backlink to header.
  5. Made tables not full-width.
  6. Running two instances of theme.

Converted line-endings and tabs. To get rid of the ^M on linux I used this tip. To get convert the tabs to spaces, :%retab in vi. I wish I had done this first. A few times I got syntax errors that I eventually traced back to the fact my new code had four spaces, while the existing code was using tabs.

Added accesskey for edit link. I like to be able to bring up the edit screen with a simple Alt-<key>.

--- old-mentalwealth.py  2006-10-19 15:55:17.000000000 -0700
+++ new-mentalwealth.py  2006-10-19 15:36:38.000000000 -0700
@@ -28,11 +28,11 @@
    def addplain(self, text):
        self.links += [text]
        
-   def add(self, action, label):
+   def add(self, action, label, accesskey=None):
        url = '%s?action=%s' % (self.url, action)
        txt = self.request.getText(label, formatted=False)
        
-       self.links += [link(self.request, url, txt)]
+       self.links += [link(self.request, url, txt, accesskey=accesskey)]

    def __call__(self):
        html = u'<ul class="editbar">\n%s\n</ul>\n' %\
@@ -116,7 +116,8 @@
                continue
            if action[0].isupper() and not action in available:
                continue
-           builder.add(action, label)
+           accesskey = (action == 'edit' and "M")
+           builder.add(action, label, accesskey=accesskey)
 
        # delegate this next part so I can stop rewriting code ;-)
        builder.addplain(self.subscribeLink(page))^M

Added Quicklink action link. In Theme.header function, added [ 'quicklink', 'add quick link' ] to self.choices list.

Added page title and backlink to header. Having the page title displayed prominently in the header is a must for me. Even better if the title is a link that finds all references to the page:

--- old-mentalwealth.py  2006-10-19 16:24:00.000000000 -0700
+++ new-mentalwealth.py  2006-10-19 16:45:33.000000000 -0700
@@ -160,9 +160,17 @@
                        ['DeletePage',      'delete page']
                        ]
        
+
+       title_and_backlink = """
+<a title="Click to do a full-text search for '%(page_name)s'"
+   href="%(script_name)s/%(page_name)s?action=fullsearch&amp;value=linkto%%3A%%22%(page_name)s%%22&amp;context=180">
+   %(page_name)s
+</a>""" % d
+
        # bundle up all our parts
        parts = [   self.emit_custom_html(self.cfg.page_header1),
-                   '<div id="header">%s</div>' % self.logo(),
+                   '<div id="header">%s</div>' % self.logo().replace("</div>",
+                                   " %s</div>" % title_and_backlink),
                    self.emit_custom_html(self.cfg.page_header2),
                    u'<div id="sidebar">',
                    html % (_('Search'),        searchpanel),

Made tables not full-width. I prefer tables not to automatically expand to the width of the screen. In htdocs/mentalwealth/css/base.css, delete the "width: 99%" from the "table" selector.

Running two instances of theme. I installed two copies so that I can have one wiki with the orange colors, and another with blue. In the future the themes may diverge further. Copy mentalwealth.py to data/plugin/theme/<new-name.py>. In <new-name.py>, change name='mentalwealth' to name='<new-name>'. To change the color scheme, change the skin in htdocs/<new-name>/css/screen.css.

MoinMoin: DavidMontgomery/MyMoinMoinTweaks (last edited 2007-10-29 19:11:00 by localhost)