Про mod_rewrite и MediaWiki
Apr. 1st, 2009 05:21 pmЖил я одно время с MediaWiki без mod_rewrite, и ссылки у меня в её нутре были вида /wiki/index.php?title=.... Со временем меня таки допинали поправить это дело (ибо не human-writable, ейб-гу). Но чтобы старые ссылки не перестали работать, пришлось таки напрячь свой ганглий (ни один из стандартных советов как-то не подошёл). Ладно, сделал:
При этом вики лежит в /w/ и у MediaWiki в LocalConfig.php прописано, что ссылки надо генерить на /wiki/. И действительно, оно таки заработало. Но «есть один ньюанс»: всякие ссылки не на статьи (например, на страницы редактирования и прочие) всё равно выглядели как /w/index.php?title=.... Казалось бы, чего проще: при натыкании на такой URL редиректить его на /wiki/ и задача свелась бы к предыдушей. Но не тут-то было. После того, как RewriteRule со флагом L (last) отработал, всё равно происходит внутренний редирект и, кто бы мог подумать, заново начинают применяться RewriteRule. Что, естественно, порождает бесконечный цикл (/w/index.php?title=... ⇔ /wiki/...). Долго я смотрел на Apache Documentation аки баран на новые ворота и пытался увидить, как же отличить свежепришедший url от уже прошедшего обработку (хотя, что характерно, в логах оно явственно видно:
). В результате не придумал ничего более умного, чем парсить THE_REQUEST, который PT таки не манглит:
Первые два rewrite rule манглят просто имена и сложно (с параметрами) имена. Возможно, второе правило (при дополнительном допиливании) вполне себе покроет первое, но при отладке оно выродилось в это. Последнее правило обрабатывает URL изображений (ибо ваистену).
Собственно вопрос: есть ли нормальный способ отловить, что URL уже после внутреннего редиректа, или только костылями типа этого?
RewriteEngine On RewriteRule ^wiki/[iI]ndex.php/(.*)$ /wiki/$1 [R,L] RewriteRule ^wiki/index.php /w/index.php?$1 [R,L] RewriteRule ^wiki/images/(.*)$ /w/images/$1 [PT,L] RewriteRule ^wiki/?$ /w/index.php [PT,L,QSA] RewriteRule ^wiki/(.*)$ w/index.php?title=$1 [PT,L,QSA]
При этом вики лежит в /w/ и у MediaWiki в LocalConfig.php прописано, что ссылки надо генерить на /wiki/. И действительно, оно таки заработало. Но «есть один ньюанс»: всякие ссылки не на статьи (например, на страницы редактирования и прочие) всё равно выглядели как /w/index.php?title=.... Казалось бы, чего проще: при натыкании на такой URL редиректить его на /wiki/ и задача свелась бы к предыдушей. Но не тут-то было. После того, как RewriteRule со флагом L (last) отработал, всё равно происходит внутренний редирект и, кто бы мог подумать, заново начинают применяться RewriteRule. Что, естественно, порождает бесконечный цикл (/w/index.php?title=... ⇔ /wiki/...). Долго я смотрел на Apache Documentation аки баран на новые ворота и пытался увидить, как же отличить свежепришедший url от уже прошедшего обработку (хотя, что характерно, в логах оно явственно видно:
...
85.140.160.226 - - [31/Mar/2009:01:57:30 +0000] [esyr.org/sid#820e978][rid#84b8958/initial] (1) [perdir /var/www/esyr/] internal redirect with /w/index.php [INTERNAL REDIRECT]
85.140.160.226 - - [31/Mar/2009:01:57:30 +0000] [esyr.org/sid#820e978][rid#84ada28/initial/redir#1] (3) [perdir /var/www/esyr/] strip per-dir prefix: /var/www/esyr/w/index.php -> w/index.php
...
85.140.160.226 - - [31/Mar/2009:01:57:30 +0000] [esyr.org/sid#820e978][rid#84b8958/initial] (1) [perdir /var/www/esyr/] internal redirect with /w/index.php [INTERNAL REDIRECT]
85.140.160.226 - - [31/Mar/2009:01:57:30 +0000] [esyr.org/sid#820e978][rid#84ada28/initial/redir#1] (3) [perdir /var/www/esyr/] strip per-dir prefix: /var/www/esyr/w/index.php -> w/index.php
...
). В результате не придумал ничего более умного, чем парсить THE_REQUEST, который PT таки не манглит:
<Все вышеупомянутые правила>
RewriteCond %{REQUEST_METHOD} "^GET$" [NC]
RewriteCond %{THE_REQUEST} "^(GET|POST|HEAD) +/w/index.php\?title="
RewriteCond %{QUERY_STRING} ^title=([^&]*)$
RewriteRule ^w/index.php /wiki/%1? [NE,R,L]
RewriteCond %{REQUEST_METHOD} "^GET$" [NC]
RewriteCond %{THE_REQUEST} "^(GET|POST|HEAD) +/w/index.php\?title="
RewriteCond %{QUERY_STRING} ^title=([^&]*)&(.*)$
RewriteRule ^w/index.php /wiki/%1?%2 [NE,R,L]
RewriteCond %{THE_REQUEST} "^(GET|POST|HEAD) +/w/images/"
RewriteRule ^w/images/(.*)$ /wiki/images/$1 [R,L]
Первые два rewrite rule манглят просто имена и сложно (с параметрами) имена. Возможно, второе правило (при дополнительном допиливании) вполне себе покроет первое, но при отладке оно выродилось в это. Последнее правило обрабатывает URL изображений (ибо ваистену).
Собственно вопрос: есть ли нормальный способ отловить, что URL уже после внутреннего редиректа, или только костылями типа этого?
no subject
Date: 2009-04-02 06:49 am (UTC)Есыр, я сейчас тоже за 1600x1200 монитором, но у меня шрифт не такой мелкий!
( это намёк про то, что надо или автопереносить, или под кат такие длинные строчки )
no subject
Date: 2009-04-02 07:32 am (UTC)no subject
Date: 2009-04-02 07:38 am (UTC)no subject
Date: 2009-04-02 12:55 pm (UTC)no subject
Date: 2009-04-02 01:12 pm (UTC)Да, а менять DooM можно не только в гризманки. Я это обычно фарьбагом делаю.
Прописал fixed width.
no subject
Date: 2009-04-02 02:55 pm (UTC)Вот у меня к каждому посту в гризманки при загрузке страницы приделывается кнопочка "hide". Как добиться такого эффекта от файрбага я не знаю.
no subject
Date: 2009-04-02 05:10 pm (UTC)no subject
Date: 2009-04-02 04:50 pm (UTC)Имхо, самое простое и безопасное для всех - это просто поставить моноширинный шрифт.