我一如既往地在与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需要它。我的模式也试图预测某人没有进入尾随斜线,因此(/?)
编辑:我还应该注意,我不想创建更通用的规则 - 我很乐意为每个新客户端添加重写规则并增加{{1}每次都是数字。
编辑(8月11日),所以经过一点点推销后,这就是我的.htaccess所在:
S=x
毋庸置疑,它不起作用。但是,第一部分工作,如果我删除整个WordPress部分。我需要它们同时工作。什么是导致第一部分失败的WordPress片?我想这是RewriteBase和最后一条规则的组合,它将其他任何东西别名给/index.php,坦率地说这有点令人失望。事实上,我并不真正理解该规则在多站点环境中是如何工作的,但似乎也是如此。
最终解决方案 感谢LazyOne的正确答案!对于其他人的参考,我使用的最终解决方案是:
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
答案 0 :(得分:2)
这很简单:
RewriteCond %{REQUEST_URI} !^/portal/
RewriteRule (.*) /portal/$1 [L]
它会将所有请求重写(内部重定向)到/portal/
文件夹(例如/clientA/something
=&gt; /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
答案 1 :(得分:0)
我发布了部分内容作为评论,但认为对于那些在这里作为答案的人来说可能会更清楚。对OPs来说,他找到了一种使用[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'],无论你重写什么,它总是在用户的浏览器窗口中是什么。 OP通过使用[R]选项找到了解决此问题的方法,但这会导致您丢失URL:
RewriteRule ^p/([-a-zA-Z0-9_]+)(/.*) $2 [R,L]
<强>重定向强>:
http://mysite.com/p/profile/(.*)
要:
http://mysite.com/$1
但是,用户以这种方式丢失了他的唯一网址。最好你可以添加一个查询字符串来至少保留数据,但是你会失去漂亮网址的开头点。
我确实想出了一个解决方案;然而,它涉及黑客攻击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']);
这基本上只是通过过滤URI开头的配置文件来欺骗WordPress。
最后,我还需要一个网站内链接的解决方案。为此,我添加了这个过滤器:
注意:其中一些正则表达可能有点疯狂;我过滤掉了特定于网站的内容,因此请将其用作概念,而不是复制/粘贴。
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是唯一重要的。无论如何,您需要该代码才能使内部链接正常工作。
我希望有帮助,如果有人有任何评论建议,我会非常感谢。