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.
For those who like diffs, here is a diff file for these changes to Page.py. The changes are described below.
Open Page.py in your favorite text editor. Find the following section of code:
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...".
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:
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.
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:
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:
1 case_insensitive_pagenames = 1