2011-07-21 108 views
3

我一直在努力与mod_rewrite。我们有许多通过WordPress多站点运行的客户端门户,所有这些客户端门户都可以通过子目录访问:portalmod_rewrite混淆子目录

因此,例如: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号码。

EDIT(8月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别名的最后一个规则的组合,这坦率地说是一个无趣的故事。事实上,我并没有真正理解这个规则如何能够在多站点环境下工作,但似乎是这样。

FINAL SOLUTION 感谢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

像这样简单:

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

感谢您的建议。唯一的问题是,使用[L] ast指令,WordPress重写将不会发生,它们需要发生(即使是客户端文件夹),以便在WP中启用漂亮的固定链接 –

+0

@Tom为什么“不会发生” ?看到'[L]'标志重写进入下一次迭代(即它的工作原理--L'并不意味着“停止重写并立即离开”),并且仍然会达到WordPress重写规则。但是,是的 - 您可以通过删除“L”标志来加速它*微小的一点。其余的由WordPress处理'/ portal/clientA/something'链接。 **关于[L]标志**:http://stackoverflow.com/questions/6797998/rewriterule-last-l-flag-not-working。如果你在服务器配置中有你的重写规则,那么最好跳过[L]标志。 – LazyOne

+0

啊!感谢您澄清[L]。我确实认为它在那之后立即停止处理.htaccess。现在,如果你看看我更新的帖子,你可以看到它仍然无法正常工作。是否因为RewriteBase? –

0

我贴的这部分作为注释,但想通这可能是谁在这里降落做到这一点作为一个答案的人更清晰。对于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]选项来解决这个问题,但是这会导致你失去你的网址:

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

重定向

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

要:

http://mysite.com/$1 

但是,用户以这种方式失去了他独特的URL。至多你可以添加一个查询字符串来至少保留这些数据,但是然后你就失去了开始的漂亮URL。

我确实想出了一个解决方案;然而,它涉及黑客WordPress的包含文件:(如果有人有更好的办法,请及时通知我们开始吧:

SOLUTION

设置我的.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']; 
0通过在URI年初筛选出轮廓的东西

$req_uri = preg_replace(@'/^\/?p\/([-a-zA-Z0-9_]+)\//', '', $_SERVER['REQUEST_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是唯一重要的。无论如何,你需要这个代码让你的内部链接工作。

我希望有帮助,如果任何人有任何意见的建议,以改善这一点,我将不胜感激。