CaseCorrection

Summary: Makes PmWiki intelligently case-insensitive
Version: 20170618
Prerequisites: PmWiki 2.2.58 or newer, requires $EnablePathInfo set
Status: beta
Maintainer: Petko (original author: EemeliAro)
License: Gnu GPLv2, ICS License

Questions answered by this recipe

  • How can I make case-insensitive URLs work in PmWiki?

Description

CaseCorrection handles mistakes of case in PmWiki addresses (eg. homepage instead of HomePage) by looking for a case-insensitive match in all of a wiki's pages. If a match is found, the user is silently redirected to it.

The recipe can also be used together with a generic 404 page to catch mistakes such as <http://example.com/main/homepage> even when CleanUrls wouldn't normally direct the request to PmWiki at all.

To install this recipe:

  • download casecorrect.phpΔ to your cookbook directory
  • add the following line to your configuration file:
    include_once("$FarmD/cookbook/casecorrect.php");
  • add the directive (:case-correction:) to your 404 page, by default located at Site.PageNotFound

What it does

When PmWiki can't find a page, it uses the contents of the page Site.PageNotFound to produce a 404 Page Not Found message that by default has a link to create the missing page. This recipe adds a function call to the rendering of that page that looks through the wiki for a case-insensitive match to the sought page, eg. <http://example.com/main/homepage> looks for anything matching "main.homepage", and will probably find "Main.HomePage". In such a case, the user will be redirected to <http://example.com/Main/HomePage>.

Since CaseCorrection is only triggered if the system would otherwise produce a 404 page, it in no way limits what names you can give your pages; you can still have eg. Everyday and EveryDay if you so wish, but if an user looks for everyday they'll end up at whichever of those pages the PHP readdir() function first finds. It's also still possible to create a new page (eg. EveryDay following the above example) when a similarly-named one (Everyday) already exists, you just have to directly add ?action=edit to the URL.

ErrorDocument integration

The code is structured in such a way that you can make Site.PageNotFound your default 404 page, and the user can be redirected to the wiki page they're actually looking for. If using an Apache server, you should add the following to your configuration (adjusting for whatever URL path resolves to your 404 page):

ErrorDocument 404 /Site/PageNotFound

Since PmWiki will think it's just getting a request for the page Site.PageNotFound instead of whatever the actual requested URL was, CaseCorrection resets the values of a few page variables (specifically, $FullName, $Group, $Name and $RequestedPage). Also, a new page variable {$RequestedUrl} is provided, containing the local part of the address in a sanitized form. Obviously these variablea are only available if a matching page wasn't found.

Site.PageNotFound example

This is what I'm using on my sites. The (:case-correction:) triggers the recipe and redirects if a match is found, otherwise {$RequestedUrl} provides the local path of the requested address, $FullName is used to make a link to create and edit a page with this name, and finally $Name or $Group is used as a search term to look for other possible pages.

(:case-correction:)
The location "{$RequestedUrl}" doesn't exist on this server.

(:if auth edit :)%rel=nofollow% ([[{*$FullName}?action=edit | Create {*$FullName}]]) 

(:if equal {*$Name} {$DefaultName} :)
(:searchresults {*$Group}:)
(:else:)
(:searchresults {*$Name}:)
(:ifend:)

Notes

The use of $EnablePathInfo is assumed. If you'd like to make CaseCorrection parse the contents of queries as well, the code should be relatively simple to modify.

If you're using a 404 page in a location different from the default $SiteGroup.PageNotFound, you should set the value of the variable $PageNotFoundPageName to match that; by default it's 'PageNotFound'. This is required to prevent redirect loops when trying to view the 404 template page directly.

You can also use CaseCorrection to find partial matches, eg. to redirect site/si to Site.Site. To permit this, edit the regular expression on line 44.

Release Notes

  • 20170618 — update for PHP 7.2 (by Petko)
  • 20170212 — update for PHP 5.5 (by Petko)
  • 2008-09-03Δ — bugfixes & generalisations
    • overwrites normal page variables if necessary instead of providing new ones
    • removes any part matching $ScriptUrl before looking for group & page names
    • uses MakePageName to, well, make the page name
    • can handle non-standard alternatives to $SiteGroup.PageNotFound
  • 2008-09-02Δ — first public release

See Also

Contributors

Comments

User notes +4: If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.