WordPress:自定义重写规则 - .htaccess或functions.php?

时间:2010-07-31 15:39:06

标签: wordpress mod-rewrite

我疯了。我唯一想做的就是将这些规则添加到我正在开发的网站中:

fastigheter-spanien/x    property/X&lang=sv
fastigheter-usa/x    property/X&lang=sv
properties-spain/X    property/X&lang=en
properties-usa/X    property/X&lang=en

其中X是帖子的名称。这些都是自定义帖子类型。我最终遇到这种情况的原因是我使用多种语言,但希望客户不必为每篇文章创建多个帖子(他们有很多选项和图片,不得不重新发布它们实际上不属于题)。 我已经研究过在functions.php中创建rewrite_rules以及修改.htaccess文件但是无法让它工作。这些重写非常简单,不需要使用任何函数。我不能只调整.htaccess文件吗?

尝试

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_URI} !^/fastigheter-spanien/([^\./]+)
RewriteCond %{REQUEST_URI} !^/fastigheter-usa/([^\./]+)
RewriteCond %{REQUEST_URI} !^/properties-spain/([^\./]+)
RewriteCond %{REQUEST_URI} !^/properties-usa/([^\./]+)

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

RewriteRule ^fastigheter-spanien/([^\./]+)$ property/$1 [L]
RewriteRule ^fastigheter-usa/([^\./]+)$ property/$1 [L]
RewriteRule ^properties-spain/([^\./]+)$ property/$1&lang=sv [L]
RewriteRule ^properties-usa/([^\./]+)$ property/$1&lang=sv [L]

这给了我一个404.任何想法?

2 个答案:

答案 0 :(得分:6)

您的重写应该正常,但WordPress看不到您的修改。这样做的原因是WordPress从$_SERVER['REQUEST_URI']读取,它始终包含原始请求URI,而不是mod_rewrite操作中产生的结果。

我对实际使用WordPress并不熟悉,但是我已经查看了其他一些问题的一些源代码,如果提供的话,它似乎也会尝试使用$_SERVER['PATH_INFO']。因此,你可以试试这个:

AcceptPathInfo On
RewriteEngine On
RewriteBase /

RewriteRule ^fastigheter-(spanien|usa)/([^\./]+)$ property/$2&lang=sv
RewriteRule ^properties-(spain|usa)/([^\./]+)$    property/$2&lang=en

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /index.php/$0 [L]

我发现使用PATH_INFO是有问题的(并且通常不会在每个目录的上下文中工作,虽然我不认为我已经确定了原因),并且通常建议不要使用它。

您的其他选项也涉及到PHP方面的工作。你可以做类似Anraiki suggested的事情,或者你可以告诉$_SERVER['REQUEST_URI']你正在期待的事情。

如果mod_rewrite执行重定向,则模块看到的REQUEST_URI存储在服务器的REDIRECT_URL变量中。因此,稍微调整重写规则集,我们可以这样做:

RewriteEngine On
RewriteBase /

# Force L on these rules to cause the REQUEST_URI to be changed (so that
# REDIRECT_URL will end up with the rewritten value we want)
RewriteRule ^fastigheter-(spanien|usa)/([^\./]+)$ property/$2&lang=sv [L]
RewriteRule ^properties-(spain|usa)/([^\./]+)$    property/$2&lang=en [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

然后,在WordPress处理的早期某处(例如在index.php中,由于您不太可能需要使用后续的WordPress版本更新该文件),您可以执行以下操作:

if (!empty($_SERVER['REDIRECT_URL']))
    $_SERVER['REQUEST_URI'] = $_SERVER['REDIRECT_URL'];

很可能有一种方法可以使用永久链接设置本身在WordPress中定义您的行为,因为它在解析请求时会迭代该规则列表,但我并不完全清楚这个细节,因为我'从来没有用过它。如果这是可能的,我会认为这是处理这种情况的推荐方法,但无论哪种方式,希望其中一个选项可以让事情适合你。

答案 1 :(得分:3)

如果所有其他方法都失败了.htaccess文件,那么有一个替代解决方案来挂钩“通过插件”

以下是我的某个插件的摘录。

<?php 
function fancy_url_hook($var='REQUEST_URI')
{
    if (!in_array($var, array('REQUEST_URI', 'PATH_INFO'))) $var = 'REQUEST_URI';
    $req = $_SERVER[$var];

    if (($var != 'PATH_INFO') && isset($_SERVER['PATH_INFO'])) {
        fancy_url_hook('PATH_INFO');
    }
    $explodeURL = array_slice(explode('/',$req),1,5);

    global $language;

    switch($explodeURL) {
        case 'fastigheter-spanien': $url = 'sv'; break;
        case 'fastigheter-usa': $url = 'sv'; break;
        case 'properties-spain': $url = 'en'; break;
        case 'properties-usa': $url = 'en'; break;
    }

    $language = $url;

}

function source_function()
{
    global $language;
    $_GET['lang'] = $language;

}

add_action('init', 'fancy_url_hook');
add_action('init', 'source_function');
?>

虽然,它需要一些编辑,它必须直接从“插件”挂钩。所以插件可能是必要的。

尽管如此,您是否尝试在编辑.htaccess文件后禁用所有插件?