阿帕奇重写规则和WordPress问题

时间:2014-03-01 作者:Elian ten Holder

我试图通过使用wordpress重写规则来解决我的问题,但遗憾的是,我花了太长时间才尝试这种方法。我把它用于一个更简单的问题,但现在我无法将它用于我的双变量重写。

# START Custom rules.
RewriteEngine On

RewriteRule ^examentraining/vak/([^/]+)/([^/]+)/?$ index.php?p=1316&vakname=$1&level=$2 [L]
RewriteRule ^examentraining/training/([^/]+)/?$ index.php?pagename=examentraining/training&trainingid=$1 [L]

# FIN customrules

# 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
第二条规则重写index.php?pagename=examentraining/training$trainingid=VAKID => /examentraining/training/VAKID/. 这一个工作正常,已经过测试。

我希望我的第一个例子也能起作用,这一个需要重写/index.php?p=1316&vakname=VAKNAME&level=LEVELNAME => /examentraining/vak/VAKNAME/LEVELNAME/.

LEVELNAMEVAKNAME 这两个字符串都应该能够包含A-Z、A-Z、\\u、&;。我已经在多联机测试仪上测试了这个重写规则,但当我将它与wordpress一起使用时,它总是失败。

我为启用了日志记录。htaccess和我可以看到重写功能正常,但之后我就无法继续了。

日志:https://gist.github.com/ITWarrior/9292036

我希望有人能帮助我,我必须完成这件事,我已经尝试了各种方法。

编辑1

我补充道remove_filter(\'template_redirect\', \'redirect_canonical\'); 到我的插件。现在请求/examentraining/vak/natuurkunde/vwo可以让我访问/examentraining/vak/natuurkunde/vwo,但出现404找不到wordpress错误。此请求的日志:https://gist.github.com/ITWarrior/9294435重写工作正常,在第一次重写后输入url实际上可以让我进入正确的页面(/index.php?p=1316&vakname=aardrijkskunde&;level=vwo)。

1 个回复
最合适的回答,由SO网友:Elian ten Holder 整理而成

经过几周的摆弄和各种各样的把戏,我终于明白了。有两件事我做错了,我希望wordpress能够访问位于斜杠之间的最后两个值作为get参数/examentraining/vak/VAKNAME/LEVELNAME/ 已提交给Wordpress。p=1316&vakname=VAKNAME&level=LEVELNAME => /examentraining/vak/VAKNAME/LEVELNAME/ 是不正确的,因为它起到了相反的作用。但当我改变重写规则时,它仍然不起作用。

我仍然需要找出确切的原因,但我从来没有设法通过。htaccess文件。然后我遇到了Kyle E Gentile的以下课程。

<?php
/*
//Author Kyle E Gentile
//To use this class you must first include the file.  
//After including the file, you need to create an options array.  For example:
$options = array(
    \'query_vars\' => array(\'var1\', \'var2\'),
    \'rules\' => array(\'(.+?)/(.+?)/(.+?)/?$\' => \'index.php?pagename=$matches[1]&var1=$matches[2]&var2=$matches[3]\')
);
//After creating our $option array, 
//we will need to create a new instance of the class as below:
$rewrite = new Add_rewrite_rules($options);
//You must pass the options array, this way. (If you don\'t there could be problems) 
//Then you can call the filters and action functions as below:
add_action(\'wp_head\', array(&$rewrite, \'flush_rules\'));
add_action( \'generate_rewrite_rules\', array(&$rewrite, \'add_rewrite_rules\') );
add_filter( \'query_vars\', array(&$rewrite, \'add_query_vars\') );
//That is it.
*/

//prevent duplicate loading of the class if you are using this in multiply plugins
if(!class_exists(\'add_rewrite_rules\')){

    class Add_rewrite_rules{

        var $query_vars;
        var $rules;

        function __construct($options){
            $this->init($options);
        }

        function init($options){
            foreach($options as $key => $value){
                $this->$key = $value;
            }
        }

        function rules_exist(){
            global $wp_rewrite;

            $has_rules = TRUE;

            foreach($this->rules as $key => $value){
                if(!in_array($value, $wp_rewrite->rules)){
                    $has_rules = FALSE;
                }   
            }

            return $has_rules;
        }

        //to be used add_action with the hook \'wp_head\'
        //flushing rewrite rules is labor intense so we better test to see if our rules exist first
        //if the rules don\'t exist flush its like after a night of drinking  
        function flush_rules(){
            global $wp_rewrite;

            if(!$this->rules_exist()){
                //echo "flushed"; // If want to see this in action uncomment this line and remove this text and you will see it flushed before your eyes
                $wp_rewrite->flush_rules();
            }
        }

        //filter function to be used with add_filter() with the hook "query_vars"
        function add_query_vars($query_vars){

            foreach($this->query_vars as $var){
                $query_vars[] = $var;
            }

            return $query_vars;
        }

        //to be used with a the add_action() with the hook "generate_rewrite_rules"
        function add_rewrite_rules(){
            global $wp_rewrite;

            $wp_rewrite->rules = $this->rules + $wp_rewrite->rules;
        }

    }

}
?>
我在插件的init中添加了以下函数。

public function rewriteRules()
{
//Add the query variables to the list so wordpress doesn\'t discard them or worse use them to try and find by itself what page to serve.
    $options = array(
        \'query_vars\' => array(\'trainingid\', \'vakname\'),
        \'rules\' =>
            array( \'uncategorized/vak/([^/]+)/([^/]+)/?$\' => \'index.php?p=1316&vakname=$matches[1]&level=$matches[2]\'
            )
    );

    //I use a autoloader but if you don\'t you have to include the class.
    //include_once(\'path/to/AddRewriteRules.php\');
    $rewrite = new AddRewriteRules($options);
    add_action(\'wp_head\', array(&$rewrite, \'flush_rules\'));
    add_action(\'generate_rewrite_rules\', array(&$rewrite, \'add_rewrite_rules\'));
    add_filter(\'query_vars\', array(&$rewrite, \'add_query_vars\'));


}
这解决了问题,但在这之前还有一步,你可能已经注意到我想要匹配examentraining/vak/VAKNAME/LEVELNAME/ 但我最终匹配了uncategorized/vak/VAKNAME/LEVELNAME/. 这是因为出于某种原因,Wordpress SEO或Wordpress本身会干扰我的请求。要找到正确的请求URL,请使用debug bar plugin. 它准确地告诉您将收到什么请求,以及符合哪些规则。

我希望这对任何人都有帮助!

结束

相关推荐

为WordPress提供自己的目录并使用.htAccess目录索引

这是个坏主意吗在当前未使用Wordpress的网站(即http://example.com/Wordpress)旁边的子目录(即http://example.com/Wordpress)中安装Wordpress。。。仍然从根目录运行WordpressGiving Wordpress It\'s Own Directory 和using .htaccess to change the Directory Index (因此http://example.com仍然指向非Wordpress网站的主页)。这将允许