CleanUrls-Talk

Summary: Talk page for CleanUrls.
Maintainer: Hagan Fox
Users: (View / Edit)

This space is for User-contributed commentary and notes. Please include your name and a date along with your comment.

Comments

Add redirect /Cookbook.CleanUrls -> /Cookbook/CleanUrls ?

I'm not sure, but probably we should add such a redirect when $EnablePathInfo = 1; ? Now these adresses example.com/*.* exists as a separate pages, and this is not good as far as they can be mistakenly indexed by search engines.

Finar September 08, 2020, at 11:48 AM

$makeRedirect = strpos($pagename,".");
  if ($makeRedirect !== false && $action == "browse") {
    $makeRedirect = str_replace(".","/",$pagename);
    header("HTTP/1.1 301 Moved Permanently"); 
    header("Location: $ScriptUrl/$makeRedirect"); 
    exit(); 
  }
unset($makeRedirect);

The code above in your config.php will do such a redirect. Finar September 14, 2020, at 05:05 PM

500 error?

What could possibly cause a 500 Server Error? Maybe it's because of the Cyrillic url? I've tried both Cyrillic name and its „punny code“, neither works. At the same hoster I've got other projects with working rewrite rules (mostly under WordPress). ruask? March 31, 2011, at 11:53 AM

Renaming to shorten URLs

I'm new to PmWiki, but what I did was this:

  1. I created a file called i.php in the same directory as pmwiki.php. The contents of I were <?php include_once('pmwiki.php');
  2. Then, I renamed the folder called that I previously had titled "PmWiki" to "w"
  3. I put this into my config.php file:
      ## Eliminate "pmwiki.php" from URLs.
      $EnablePathInfo = 0;
      $ScriptUrl = "http://put your domain name here/w/i.php";
      ## more configuration settings...

Finally, I pointed my server to i.php and it worked with a short URL!

Ok,I tried this exact process (with a Windows server) and this is what I got "Warning: Cannot modify header information - headers already sent by (output started at E:\xampp\htdocs\wikifolder\myinformation.php:1) in E:\xampp\htdocs\wikifolder\pmwiki.php on line 1075," can someone advise?

thanks! -Chris August 24, 2008

Solved the same problem thanks to PM

 > The "Cannot modify header information" probably comes from some 
 > extra characters or blank lines at the beginning of index.php, before
 > the "<?php" tag.
 >
 > Pm   http://www.mail-archive.com/pmwiki-users@pmichaud.com/msg12201.html

Damien September 16, 2008, at 02:10 AM

Trying to remove pmwiki.php with .htaccess

I'm trying to remove the pmwiki.php using .htaccess but have so far failed, hopefully you guys can help me out.

In my config file I have:

## Use "Clean URLs".
$EnablePathInfo = 1;
$ScriptUrl = "http://www.mydomain.com/necrowiki";
## more configuration settings...

Then in my .htaccess file, which is located in the same dir as pmwiki.php:

# Use mod_rewrite to enable "Clean URLs" for a PmWiki installation.
RewriteEngine On
# Define the rewrite base.
RewriteBase /necrowiki
# Send requests without parameters to pmwiki.php.
RewriteRule ^$           pmwiki.php  [L]
# Send requests for index.php to pmwiki.php.
RewriteRule ^index\.php$ pmwiki.php  [L]
# Send requests to pmwiki.php, appending the query string part.
RewriteRule ^([^/a-z].*) pmwiki.php?n=$1  [QSA,L]

Anybody know why it isn't working?

Remove www from URL

Also add this and you will remove the www from all URLs for your site. It is completely compatible with CleanUrls.

RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]

Lowercase Group Names

Does anyone know how to use rewriting capabilities to allow lower-case group names to be entered and successfully redirected to the title-cased group names? e.g. http://mywiki.com/group redirects to http://mywiki.com/Group. —JoeW? 2006-08-25

Yes, the rewrite rule should be

RewriteRule ^([^/].*) pmwiki.php?n=$1  [QSA,L]

instead of

RewriteRule ^([^/a-z].*) pmwiki.php?n=$1  [QSA,L]

which just means the page name can't start with a forward slash, but anything else is fine. — Sam Wilson 2007-02-02.

hi. thanks for this. i'm using lowercase group and pagenames as well, and this solved a huge problem. however, in my case i discovered that while it enabled the mod_rewrite to finally occur for 'group.name', all of my css formatting was being lost. this was fixed when i put an exception for '/pub' in there (and for '/uploads' as well so that i could link directly to my files:

RewriteRule ^(?!pub/)(?!uploads/)(.*)/?$ pmwiki.php?n=$1 [QSA,L]

now it works great for me. special thank to PeterBowers for helping me figure out the pub & uploads regex exclusions...

overtones99 October 01, 2009, at 03:13 AM

Even cleaner URLs

I also use the following (plus some modifications of php code) to get even cleaner URLs:

# If of form Group/Name/action, 
# send requests to pmwiki.php with proper arguments appended ($3 is query string)
RewriteRule ^([A-Z0-9][^/.]*[/.][^/]*)[/]([a-z]+)(.*) pmwiki.php?n=$1&action=$2&args=$3 [QSA,L]
# Send requests to pmwiki.php, appending the query string part.
RewriteRule ^([^/a-z].*) pmwiki.php?n=$1  [QSA,L]
2006-03-23 AriEpstein

Simplify further for group main pages
For having the main page of each group display as {wikiroot}/group instead of {wikiroot}/group/group, add the following to your local/config.php file:

##  Even cleaner URLs: group main pages display as /$group and not /$group/$group
$EnableFixedUrlRedirect=0;
$FmtPV['$PageUrl'] = '($name==$group) ? "$ScriptUrl/$group" : "$ScriptUrl/$group/$name"';
2007-08-09 EemeliAro

Simplify further for group main pages (using .htaccess) - http://mysite.com/Group instead of http://mysite.com/Group/DefaultName
The above seems to work great if you're using the paradigm of Group/Group. But I was unable to get it to work with my $DefaultName set to Index (as in Group/Index). I may have been overlooking something, but my solution came from adding a line to my .htaccess file, before any of the pmwiki stuff is called, i.e.:

##  Even cleaner URLs: group main pages display as /$group and not /$group/index -- via .htaccess 
## (assuming $DefaultName = "index";)
RewriteRule ^([^/]+)/?$ $1/index  [L]
. . .
### and then all the usual stuff...
# Send requests without parameters to pmwiki.php.
RewriteRule ^$           pmwiki.php  [L]
# Send requests for index.php to pmwiki.php.
RewriteRule ^index\.php$ pmwiki.php  [L]
# Send requests to pmwiki.php, appending the query string part.
# meanwhile, making sure that calls to pub/ & uploads/ remain safe
RewriteRule ^(?!pub/)(?!uploads/)(?!pmwiki.php)(.*)$ pmwiki.php?n=$1  [QSA,L]

there are additional steps one can take in order to further prevent your DefaultPages from appearing in the url. the above solution works only up to a point - once you start clicking around the site, you'll notice that links in the format [[Group/]] always resolve to Group/DefaultName. the code below seems to successfully change this behavior, and make all links in the form [[Group/|txt]] or [[Group/DefaultPage|txt]] spit out as http://mysite.com/Group rather than http://mysite.com/Group/DefaultPage. it also seems to successfully preserve ?arguments and #anchors in the url, and accepts dot-syntax ([[Group.DefaultPage|txt]]) as well.

in config.php, towards the bottom:

## [[target/ | text]]  &  [[target/DefaultPage | text]]
## this takes any link in the form [[target/ | text]], [[target/?args | text]], 
## [[target/DefaultPage | text]], or [[target/DefaultPage?args | text]], 
## and prepends the $imap identifier GROUPONLY:
## it then returns the path minus the Default page i.e. GROUPONLY:target, or GROUPONLY:target?args
## this markup also preserves #anchors
Markup('[[Group/|',
	'<[[',
	"/\\[\\[([^\\/]+)[\\/\\.]($DefaultName)?((\?[^\\s]+)?(#[^\\s]+)?)\\s*\\|\\s*(.*?)\\s*\\]\\]($SuffixPattern)/e",
	"Keep(MakeLink(\$pagename,'GROUPONLY:'.PSS('$1'.'$3'),PSS('$6'),'$7'),'L')");

# the following presumes you've set the variable $DomainName = "mysite.com";
$LinkFunctions['GROUPONLY:'] = 'ShortenLinkUrl';
function ShortenLinkUrl($pagename,$imap,$path,$title,$txt,$fmt=NULL) {
	global $DomainName;

	# remove last forwardslash/ - this is only removed if no ?aruments are appended to the url
	$path = (preg_match("#^([^\/]*)/?$#", $path, $m)) ? $m[1] : $path;
	$path = "//$DomainName/$path";  # create a path, with two leading forwardslashes //
	$imap = 'http:';  # change imap from GROUPONLY: to http:
	#echo "$pagename,$imap,$path,$title,$txt,$fmt<br />";

	return LinkIMap($pagename,$imap,$path,$title,$txt,$fmt);
}
2011-04-03 overtones99

Sam Brenner 2-7-2006
Apache 2.0.54 came default with the rewrite module turned off and .htaccess turned off.

In your http.conf file uncomment:

#LoadModule rewrite_module modules/mod_rewrite.so

or you will get an "Internal Server Error" message.

Then you will have to enable the use of .htaccess

Someone recommended using the following script directories as an alternative to hardcoding the servername.

$BaseUrl = 'http://'.$_SERVER['HTTP_HOST'];
$ScriptUrl = $BaseUrl.'/pmwiki';
$PubDirUrl = $BaseUrl.'/pmwiki/pub';
$UploadDir = '/uploads';
$UploadUrlFmt=$BaseUrl.'/pmwiki/uploads';

Using the $_SERVER[HTTP_HOST] variable solved a Netscape localhost name issue.

For recent PmWiki releases you should be able to replace the five lines above with
$ScriptUrl = 'http://'.$_SERVER['HTTP_HOST'].'/pmwiki';
$PubDirUrl = 'http://'.$_SERVER['HTTP_HOST'].'/pmwiki/pub';
$UploadDir = '/uploads';
although that $UploadDir setting looks incorrect. Try leaving that line out, or replacing it with
$UploadDir =
  realpath($UploadDir = dirname(__FILE__).'/../uploads');

Thank you for all the work on this. The URL Rewriting (mod_rewrite + .htaccess) is so clear that I was able to immediately see what I broke when I moved my pmwiki directory down a level.

--Pico

Clean URLs in WikiFarms

Am I correct in concluding that each Wiki Field would need its own distinct .htaccess file to ensure that each field queries itself? When you say to "place the .htaccess file in the directory that will correspond the shortest URL that will reach the wiki" does that mean, in the context of WikiFarms, the directories that correspond to the shortest URLs that will distinctly reach one (and only one) Farm? See here for more.

--Pico

Yes, each field wiki needs its own distinct .htaccess because each field wiki has its own distinct URL. Does this rewrite of the note about farms make that point clearer?

Another thing to check is the Apache error log. For example you may see the error message Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden

I tried approach #3, first (simple suggestion, Eliminating "pmwiki.php" From URLs), but the shortened URLs did not display the desired pages.

It seems that index.php was not processed. Maybe this recipe requires certain webserver settings to work that are not in place on my server? I noticed that I also had to remove the trailing slash, or the path names would be displayed as http://my.url.com//Group/Page. (As you can see, I have already switched off the /n= part of the URL. I hope this doesn't complicate things.)

Henning March 24, 2006, at 09:22 AM

Henning,
Your parenthetical comment is the key. Approach #3 doesn't include setting $EnablePathInfo to 1. It must be set to 0. In other words, you can use $EnablePathInfo OR hide index.php, but not both (as far as I know).

This brings up an important point because you can (sometimes) use index.php + $EnablePathInfo to have clean URLs, too. In other words, you can do this

Before: http://www.example.com/~someuser/pmwiki/pmwiki.php?n=Main.HomePage
 After: http://www.example.com/~someuser/index.php/Main/HomePage

Here's an index.php file for the corresponding directory (/home/someuser/public_html/):

<?php
chdir('pmwiki');
include_once('pmwiki.php');

Here's the matching local/config.php file, which simply turns on $EnablePathInfo:

<?php if (!defined('PmWiki')) exit();
## Use "Clean URLs".
$EnablePathInfo = 1;
## more configuration settings...

--Hagan

The samedir mod-rewrite method breaks links to http://site.com/path/to/pmwiki.php?action=blah, apparently causing POST data to be dropped.

A direct link to [blah]/pmwiki.php?action=login and [blah]/pmwiki.php?action=mailform2 (see Mailform2) causes both of these actions to fail.

This quote from Mailform2 may be helpful:

If you applied the CleanUrls recipe and have a redirect rule installed, make sure that the ?action=mailform2 URL above goes to the "unclean" URL (the one that contains pmwiki.php). Otherwise, form input data will be dropped by Apache, and all you'll get is seemingly empty input fields.

This is happening with the samedir mod-rewrite method regardless of whether the link (in the case of ?action=login) or the form (in the case of Mailform2) is directed to the "unclean" URL. -- Neurophyre, 7 Aug 2006

'RewriteRule ^index\.php$ ~someuser/pmwiki/pmwiki.php [L]' doesn't work on Aplus.net

I'm hosting a wiki on aplus.net, and it seems that '^index\.php$' doesn't work as expected.

'RewriteRule ^index.php$ ~someuser/pmwiki/pmwiki.php [L]' works as expected, but it also rewrites 'index_php', 'indexQphp'...

Shigeru Kobayashi December 28, 2006, at 09:29 AM

ISAPI module link broken

The link to iismods.com generates an error (Bad Request (Invalid Hostname)). A little googling turned up Ionic's ISAPI Rewrite Filter which is free but not open-source. I've no idea whether the .ini syntax modeled on the CleanURLS page is compatible or not. Alas, I'm in a shared IIS hosting environment and can't use it. -thomas taylor, 03/05/2007

Minimum required "Options" for mod_rewrite

the web server I use is very restrictive by default. The apache option FollowSymLinks was disabled. This has to be enabled in order for mod_rewrite to work. To fix this, add the following to the top of the .htaccess file:

Options +FollowSymLinks

99% of the people out there won't need this, but for the other 1%, here you go. Without this you will get a "403 Forbidden" error message --Vrillusions June 04, 2007, at 10:46 AM

Even cleaner

Some people might also be interested in GetRidOfMain. I had a hard time finding it. Jeff 7/19/07

It keeps renaming lowercase urls to group names - Paulo

I'm using pmwiki on the root of my site and have this line on my .htaccess:

RewriteRule ^([A-Z0-9\xa0-\xff].*)$ web/pmwiki.php?n=$1 [QSA,L]

I thinks this Regular Expression doesn't work at all because it ignores casing. The best Regex would be: ^([A-Z][a-z\xa0-\xff].*)$

I had problems to access sub-directories in the root of my website (like: domain.com/forum). This regex matches only the strings that starts with uppercased letters and then, sends to pmwiki.php.

Showing images have been used in skin when using clean Urls

When you use clean urls with it will not show pictures have been set relative to pmwiki.php. To solve this problem you should add a line before the line sends parameters to pmwiki so those lines will be like the following:

RewriteRule ^([A-Z0-9\xa0-\xff].*\.(jpg|gif))$ $1 [L]
RewriteRule ^([A-Z0-9\xa0-\xff].*)$ pmwiki.php?n=$1 [QSA,L]

This works except when you want to upload a picture so if you want to upload a picture the parameters won't be sent and you can't do it so a better regex for eliminating this problem is appreciated.Soroush

mod_rewrite with Apache 1.3 on Windows

When using Apache 1.3 on Windows, the RewriteRule for CleanUrls does not work properly, since Apache 1.3 always lowercases the URI before providing it to mod_rewrite. This does not work (the original recipe with .htaccess and pmwiki.php in the Same Directory):

RewriteBase  /pmwiki
RewriteRule  ^([A-Z0-9\xa0-\xff].*)$  pmwiki.php?n=$1  [QSA,L]

Change it to

RewriteBase  /pmwiki
RewriteCond  %{REQUEST_URI}  ^/pmwiki/[A-Z0-9\xa0-\xff]
RewriteRule  ^(.*)$  pmwiki.php?n=$1  [QSA,L]

Important: The path at RewriteBase and RewriteCond must be equal (here: /pmwiki).
Apache 2.x on Windows is not affected (AFAIK).
20080314 RRipley

Wrapper using SetHandler (similar to "Wrapper using MultiViews")

The web server that my account is on, for whatever reason, has MultiViews (and RewriteEngine) disabled, and of course, I can't override. I found another approach to creating a "wiki" wrapper. First, I create a php wrapper called just "wiki" with no extension, same contents as the MultiViews "wiki.php" wrapper. Then, I add the following to my .htaccess to force just this file to be handled as php.

<FilesMatch "^wiki$">
SetHandler application/x-httpd-php
</FilesMatch>

The other steps are the same as the MultiViews wrapper. The final URL looks like this: http://www.example.com/~someuser/wiki/Main/HomePage -Steve March 21, 2009

Which .htaccess file are you talking about? Where do you put this "wrapper" file? Is it just a .php file with only those three lines in it?

-Promsan 2009:OCT:24

Remove Main from URLs (using a RewriteRule and GetRidOfMain)

Note: GetRidOfMain is required for this to work completely (I have only tested this using the first GetRidOfMain method). This RewriteRule fixes GetRidOfMain by correctly linking to non-existent pages. This assumes you are already using CleanUrls' URL Rewriting Example 3.

In the .htaccess file, replace:

# Send requests to pmwiki.php, appending the query string part.
RewriteRule ^([A-Z0-9\xa0-\xff].*)$ pmwiki.php?n=$1  [QSA,L]

with:

#Send single name pages to pmwiki.php?n=Main.$1
RewriteRule ^([A-Z0-9\xa0-\xff][^\.\/]*(\?.*)?)$ pmwiki.php?n=Main.$1  [QSA,L]
# Send requests to pmwiki.php, appending the query string part.
RewriteRule ^([A-Z0-9\xa0-\xff].*)$ pmwiki.php?n=$1  [QSA,L]
-SMaddox Sep 22, 2009

Hello.

Which .htaccess file are you talking about? So, which method works best with a normal hosted wiki? I use NFS.net if anyone's had experience doing this. I simply can't follow all the abstruse technical instructions above and on the CleanURLs page; please can someone help explain?

cheers

-Promsan 2009:OCT:24

Just switched from GoDaddy Linux Deluxe shared hosting to GoDaddy Linux 4GH economy hosting.

Although PmWiki was already performing wonderfully on my old hosting plan, on the new GoDaddy 4GH is much much faster.

So far there is one thing that does not work on GoDaddy Linux 4GH economy: if using $EnablePathInfo = 1 when trying "CleanUrls method 4: Wrapper using MultiViews" CleanUrls/MultiViews the URLs will be properly re-written as http://www.example.com/wiki/Main/HomePage, but these pages will give HTTP error 404.

Unless using mod_rewrite in .htaccess files, there seems not to be any way to get a clean URL with method 4 on GoDaddy Linux 4GH economy hosting.

Here below the working settings on GoDaddy Linux 4GH economy hosting without using mod_rewrite in .htaccess files:

Before: http://www.example.com/pmwiki/pmwiki.php?n=Main.HomePage
 After: http://www.example.com/wiki.php?n=Main.HomePage

1. Create a wiki.php file at the same level as your pmwiki/ directory:

<?php chdir('pmwiki'); include_once('pmwiki.php');

2. Modify your local/config.php:

<?php
# $EnablePathInfo = 1; /* leave commented or set it to 0 */
# $ScriptUrl      = 'http://' . $_SERVER['HTTP_HOST'] . '/wiki';  /* leave commented */
  $PubDirUrl      = 'http://' . $_SERVER['HTTP_HOST'] . '/pmwiki/pub';
  ...

Zia April 26, 2011, at 10:12 AM


Ok, this seems a bit odd. I'm on OS X 10.5.8, Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.7l DAV/2 PHP/5.2.15 mod_fastcgi/2.4.2, and had to make the following addtion to the first recipe for getting clean urls at the top of the .htaccess file:

        Options FollowSymLinks

I'm really not sure why this was needed to get the clean urls to work, but it works now. - tamouse June 03, 2011, at 08:19 PM

The Apache mod_rewrite doc says:
To enable the rewrite engine for Per-directory Rewrites, you need to set "RewriteEngine On" and "Options FollowSymLinks" must be enabled.
RRipley 2011-09-16 10:30pm UTC

Well, I'm using the variant .htaccess and pmwiki.php in the Same Directory.
Works fine if you've attached one hostname to one address.

I then needed a solution to access my wiki by

http://example.com/in/this/subdir/

and

http://subdomain.example.com/

pointing to the same wiki.

Here's the result (for Apache 2.2 and later):

RewriteEngine  On
# No RewriteBase since we Base ourselves

RewriteCond %{HTTP_HOST}   ^subdomain\.example\.com$  [NC]
RewriteRule .? - [E=REWRITEBASE:/]
RewriteCond %{HTTP_HOST}   ^(www\.)?example\.com$     [NC]
RewriteRule .? - [E=REWRITEBASE:/in/this/subdir/]
# more RewriteCond-RewriteRule pairs may follow for further hostnames

RewriteRule ^$                      %{ENV:REWRITEBASE}pmwiki.php      [L]
RewriteRule ^index\.php$            %{ENV:REWRITEBASE}pmwiki.php      [L]
RewriteRule ^([A-Z0-9\xa0-\xff].*)$ %{ENV:REWRITEBASE}pmwiki.php?n=$1 [QSA,L]

First of all, RewriteBase cannot be used anymore, because there's no conditional form of it.
Additionally I use a server environment variable to store the path that points to the wiki directory.

So, a RewriteCond matches against a hostname via %{HTTP_HOST} and if the pattern matches, the immediately following RewriteRule is used: match whatever (=.?), keep it unchanged (=-) and set the environment variable REWRITEBASE to the specified path (must precede and follow a /). This combination can be done multiple times for every hostname you use on the same wiki.

Once the environment variable is set, it prepends each pmwiki.php in the following rules.
Unfortunately a default value for REWRITEBASE can't be set before Rewriting by

SetVar REWRITEBASE /

since the SetVar module is one of the latest being executed within Apache. The SetVarIf module would work indeed, but didn't checked it out further.

RRipley 2011-09-16 10:30pm UTC

Hi all I got a problem, I got it in my httpd.conf but I cant handle the actions requests.

this is my part of it which redirects

 location match "/([^/a-z].*)" {
     request rewrite "/pmwiki.php?n=%1" 
} 

can someone help me plz

Miniontoby 2020-11-02 19:45pm UTC+2 -1hr (no summertime)

What is your server software? The recipe here is about the Apache server with mod_rewrite and the syntax is different from yours. --Petko November 02, 2020, at 08:55 PM

Talk page for the CleanUrls recipe (users).