Case Insensitive MoinMoin

I wanted case-insensitive filenames in MoinMoin, so I wrote this hack to do so. It causes a marginal increase in CPU usage as it lists directories when it doesn't find a page, but I think it is worth it.

To do this requires changes to MoinMoin's "Page.py" class.

WARNING - make backups first! While this worked for me, it might damage your wiki! These changes are tested on MoinMoin Version 1.5.2, and no other version.

Steps for MoinMoin 1.5.2

Diff file

For those who like diffs, here is a diff file for these changes to Page.py. The changes are described below.

Edits

  1. Open Page.py in your favorite text editor. Find the following section of code:

Toggle line numbers
   1     def reset(self):
   2         """ Reset page state """
   3         page_name = self.page_name
   4         # page_name quoted for file system usage, needs to be reset to
   5         # None when pagename changes
   6 
   7         qpagename = wikiutil.quoteWikinameFS(page_name)
   8         self.page_name_fs = qpagename
   9 
  10         # the normal and the underlay path used for this page

1. Add lines 8-13 as shown below after "qpagename = wikiutil...".

Toggle line numbers
   1     def reset(self):
   2         """ Reset page state """
   3         page_name = self.page_name
   4         # page_name quoted for file system usage, needs to be reset to
   5         # None when pagename changes
   6 
   7         qpagename = wikiutil.quoteWikinameFS(page_name)
   8         insensitive = self.get_fs_name_ignoring_case(qpagename)
   9         if insensitive != qpagename:
  10             qpagename = insensitive
  11             # set page name with proper cases and spaces
  12             self.page_name = wikiutil.unquoteWikiname(qpagename)
  13 
  14         self.page_name_fs = qpagename
  15 
  16         # the normal and the underlay path used for this page

2. Next, scroll to the end of the "reset" method, and add the following method:

Toggle line numbers
   1     def get_fs_name_ignoring_case(self, page_name):
   2         """
   3         get the case sensitive path to "pagedir",
   4         ignoring pagedir's case.
   5         @param page_name: the page name to parse
   6         @return: str page_name with proper case
   7         """
   8         datadirs = [ self.cfg.data_dir, self.cfg.data_underlay_dir ]
   9 
  10         # quit early if the page exists as given
  11         for datadir in datadirs:
  12             if not datadir == None:
  13                 if os.path.exists(os.path.join(datadir, "pages", page_name)):
  14                     return page_name
  15 
  16         for datadir in datadirs:
  17             if not datadir == None:
  18                 for page in os.listdir( os.path.join( datadir, "pages" ) ):
  19                     if page.lower() == page_name.lower():
  20                         return page
  21         return page_name

3. You're done! Case-insensitive pagenames for the masses.

For Wiki Farms

If your wiki lives in a wikifarm like mine does, where other wikis don't necessarily want case-insensitivity, you can make the wiki case insensitive only if a configuration directive is there, as shown here. Add a "try... except" block to the method in step 2 above, as shown here:

Toggle line numbers
   1     def get_fs_name_ignoring_case(self, page_name):
   2         """
   3         get the case sensitive path to "pagedir",
   4         ignoring pagedir's case.
   5         @param page_name: the page name to parse
   6         @return: str page_name with proper case
   7         """
   8         try:
   9             if not self.cfg.case_insensitive_pagenames:
  10                 return page_name
  11         except AttributeError:
  12             return page_name
  13 
  14         datadirs = [ self.cfg.data_dir, self.cfg.data_underlay_dir ]
  15 
  16         # quit early if the page exists as given
  17         for datadir in datadirs:
  18             if not datadir == None:
  19                 if os.path.exists(os.path.join(datadir, "pages", page_name)):
  20                     return page_name
  21 
  22         for datadir in datadirs:
  23             if not datadir == None:
  24                 for page in os.listdir( os.path.join( datadir, "pages" ) ):
  25                     if page.lower() == page_name.lower():
  26                         return page
  27         return page_name

Now, to enable case insensitivity, add the following option to your wiki's configuration script:

Toggle line numbers
   1         case_insensitive_pagenames = 1

Other MoinMoin Extensions

© 2008