mod_rewrite алиасинг подкаталога - PullRequest
3 голосов
/ 21 июля 2011

Я борюсь с mod_rewrite как всегда.У нас есть несколько клиентских порталов, работающих через мультисайт WordPress, доступ ко всем через подкаталог: portal.

Так, например: http://www.mydomain.com/portal/clientA/

Я хотел бы получить возможность получитьпросто набрав http://www.mydomain.com/clientA/, и он перенаправит меня на http://www.mydomain.com/portal/clientA/

Вот что я имею до сих пор, и я не могу переписать, что я могу сказать:

RewriteCond %{REQUEST_URI} /portal/
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . - [S=1]

RewriteRule /clientA(/?) /portal/clientA/

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Вторая часть я не могу коснуться, потому что это нужно WordPress.Мой паттерн также пытается предвидеть, что кто-то не вставит косую черту, поэтому (/?)

РЕДАКТИРОВАТЬ: Я должен также отметить, что я не хочу создавать более общее правило- Мне удобно добавлять правило перезаписи для каждого нового клиента и увеличивать число S=x каждый раз.

РЕДАКТИРОВАТЬ (11 августа), так что после еще немного вставок это то, что мой .htaccessв:

RewriteEngine On
RewriteRule ^clientA(/?) /portal/clientA/ [R]

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Излишне говорить, что это не работает.Тем не менее, первая часть работает, если я удаляю весь раздел WordPress.Мне нужно, чтобы они ОБА работали одновременно.Что это за кусок WordPress, который вызывает сбой в первом разделе?Я полагаю, что это сочетание RewriteBase и самого последнего правила, которое связывает что-либо еще с /index.php, что, откровенно говоря, немного облом.На самом деле я не совсем понимаю, как это правило могло бы работать даже в многосайтовом контексте, и все же оно кажется.

ЗАКЛЮЧИТЕЛЬНОЕ РЕШЕНИЕ благодаря LazyOne за правильный ответ!Для справки других, окончательное решение, которое я использовал, было:

RewriteEngine On
RewriteRule ^clientA(/.+)? /portal/clientA$1 [R,L]
RewriteRule ^clientB(/.+)? /portal/clientB$1 [R,L]


# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Ответы [ 2 ]

2 голосов
/ 21 июля 2011

Все так просто:

RewriteCond %{REQUEST_URI} !^/portal/
RewriteRule (.*) /portal/$1 [L]

Перезапишет (внутренний перенаправление) все запросы в папку /portal/ (например, /clientA/something => /portal/clientA/something).

Есливам нужно сделать это только для некоторых клиентов (или, точнее, только для определенных папок, которые являются клиентами, хотя у них есть общие / общие папки как есть), вы можете использовать это правило для каждого клиента:

RewriteRule ^clientA(.*) /portal/clientA$1 [L]

Так что .htaccess будет выглядеть так:

RewriteRule ^clientA(.*) /portal/clientA$1 [L]
RewriteRule ^clientB(.*) /portal/clientB$1 [L]

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
0 голосов
/ 22 ноября 2012

Я разместил часть этого в качестве комментария, но подумал, что для людей, которые приземлились здесь, было бы более понятно сделать это в качестве ответа. С точки зрения OP, он нашел способ сделать это, используя строку [R] (перенаправление), но это устраняет созданную вами структуру URL подкаталога, которая была бы предпочтительна в большинстве переписываний URL. Итак, ранее опубликованный ответ правильный, я не оспариваю это, но в зависимости от вашей реализации, вы все равно можете получить ошибки WordPress 404. Вот решение моей ситуации, которое, я думаю, может быть более распространенным.

В моем случае мне нужна была структура URL, подобная этой:

http://mysite.com/p/profile_name/

Каждый пользователь, который приходит на регистрацию, может создать свой собственный профиль на лету, и кроме нескольких модификаций контента, по большей части весь контент WordPress в корне будет отображаться. По сути, мне нужно это:

http://mysite.com/p/profile_name/(.*)

Переписать на это:

http://mysite.com/$1

Это код .htaccess, опубликованный в другом ответе, который БУДЕТ правильно обрабатывать это правило:

RewriteRule ^p/([-a-zA-Z0-9_]+)(/.*) $2 [L]

Проблема в том, что WordPress не заботится о вашем переписывании с точки зрения понимания, что такое $ 2, потому что WordPress использует $ _SERVER ['REQUEST_URI'], который независимо от того, что вы переписываете, всегда находится в окне браузера пользователя. , ОП нашел способ обойти это, используя опцию [R], но это приводит к потере вашего URL:

RewriteRule ^p/([-a-zA-Z0-9_]+)(/.*) $2 [R,L]

Перенаправление

http://mysite.com/p/profile/(.*)

Кому:

http://mysite.com/$1

Но пользователь таким образом теряет свой уникальный URL. В лучшем случае вы можете добавить строку запроса, чтобы хотя бы сохранить данные, но тогда вы потеряете смысл красивых URL-адресов.

Я нашел решение; однако, это включает в себя взлом включаемых файлов WordPress :( Если у кого-то есть лучший способ, пожалуйста, обновите. Вот и мы:

РЕШЕНИЕ

Я установил свой файл .htaccess равным этому:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
#My addition:
RewriteRule ^p/([-a-zA-Z0-9_]+)(/.*) $2 [L]

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

Затем я знал, что WordPress использовал переменную REQUEST_URI, поэтому я провел рекурсивный поиск и поместил эту строку кода в /wp-includes/class-wp.php (строка 147 v3.4.2):

$req_uri = $_SERVER['REQUEST_URI'];

Я изменил это на:

$req_uri = preg_replace(@'/^\/?p\/([-a-zA-Z0-9_]+)\//', '', $_SERVER['REQUEST_URI']);

Что в основном обманывает WordPress, отфильтровывая содержимое профиля в начале URI.

Наконец, мне также понадобилось решение для ссылок на сайте. Для этого я добавил этот фильтр:

ПРИМЕЧАНИЕ : Некоторые из этих регулярных выражений могут быть немного помешаны; Я отфильтровывал материалы, специфичные для сайта, поэтому, пожалуйста, используйте это как концепцию, а не как копирование / вставку.

function mysite_wp_make_link_relative( $link ) {
    $sBaseUrl = (preg_match('/^\/(p\/[-a-zA-Z0-9_]+\/)(.*)/', $_SERVER['REQUEST_URI'], $matches)) ? $matches[1] : '';
    return preg_replace( '|https?://[^/]+/(.*)|i', '/' . $sBaseUrl . '$1', $link );
}
function rw_relative_urls() {
    $filters = array(
        'page_link', // Page link
        'home_url',
        'site_url',
        'get_site_url',
        'home_link',
    );
    foreach ( $filters as $filter ) {
        add_filter( $filter, 'mysite_wp_make_link_relative' );
    }
}

Некоторые из этих фильтров могут быть неактуальны; Я почти уверен, что page_link и home_url являются единственными важными. В любом случае, вам нужен этот код, чтобы ваши внутренние ссылки работали.

Я надеюсь, что это поможет, и если у кого-то есть какие-либо комментарии по улучшению этого положения, я был бы очень признателен.

...