WordPress 和 MediaWiki 搭配的 Rewrite Rules

跟 mod_rewrite 奮戰

今天晚上都在跟 mod_rewrite 奮戰,老實說就是經驗不夠所以才會搞那麼久,不過還是做個記錄。

最近在規劃一個新的網站,它是由 WordPress 當底,上面再搭一個 MediaWiki 來做 Wiki 的功能,如果要讓兩個系統無縫整合大概是相當困難的,在還沒有完美的方案之前就先不討論了,我只求兩個不要互相打架,自己運作自己的就好。所以在網址的根目錄 / 下,跑的是 WordPress,在 /wiki/ 下跑的是 MediaWiki。

這兩個系統都有內建美化網址的功能,都是透過 mod_rewrite 來實現的。WordPress 有自己的 Permalink 設定,透過後台的介面還蠻好設定的;而 Mediawiki 的則稱為 Short URL,雖然它的 Manual 好像寫了很多字,但實際上也不太好設定,一般都是推薦用 Redwerks 出的一個 MediaWiki ShourURL Builder,它可以自動偵測你的網站,給出適合的設定檔,根據它的建議,我的 .htaccess 設定檔應該是:

RewriteEngine On
RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/w/index.php [L]
RewriteRule ^/?$ %{DOCUMENT_ROOT}/w/index.php [L]

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^/?w/images/thumb/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/w/thumb.php?f=$1&width=$2 [L,QSA,B]

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^/?w/images/thumb/archive/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/w/thumb.php?f=$1&width=$2&archived=1 [L,QSA,B]

因為我要和原本 WordPress 的 rule 合併,理論上 wiki 特例,所以擺在前面:

# BEGIN MediaWiki
RewriteEngine On
RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/w/index.php [L]

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^/?w/images/thumb/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/w/thumb.php?f=$1&width=$2 [L,QSA,B]

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^/?w/images/thumb/archive/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/w/thumb.php?f=$1&width=$2&archived=1 [L,QSA,B]
# END MediaWiki

# BEGIN WordPress
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress

這些 rules 在一般的頁面下是運作正常的,但只要遇到和圖片 thumbnail 有關的,全都會破圖,上網 search 了一下,沒有明確的解法,只能說應該是 rule 出了問題,所以我只好自己把 rewrite log 打開來找原因(話說要打開 log 也費了一番工夫,重點是 RewriteLog 要設定在 Apache config 裡,放在 .htaccess 裡是無效的)

有點邪門的是,我預期 thumbnail 相關的 uri 應該會如同上述 rule 的 pattern 是 /w/image/ 開頭的,但實際上卻直接是從 thumb/ 開始,所以當然沒辦法正確的 rewrite,解法便是將 w/images/ 拿掉就好。

但這實在是件很奇怪的事,為什麼 REQUEST_URI 不是從 root 開始呢?這才發現原來我把 RewriteBase 設定放到底下了,應該要擺在最前頭的。因此最理想的設定應該是長這樣:

# BEGIN MediaWiki
RewriteEngine On
RewriteBase /
RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/w/index.php [L]

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^/?w/images/thumb/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/w/thumb.php?f=$1&width=$2 [L,QSA,B]

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^/?w/images/thumb/archive/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/w/thumb.php?f=$1&width=$2&archived=1 [L,QSA,B]
# END MediaWiki

# BEGIN WordPress
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress