在WordPress插件中以编程方式添加Mod重写规则

时间:2012-10-10 16:42:37

标签: php mod-rewrite wordpress-plugin wordpress

以下示例插件在用户更改固定链接设置时将自定义mod重写规则添加到.htaccess

/* Plugin Name: Sample Mod Rewrite  */

add_action('generate_rewrite_rules', array(new custom_mod_rewrite, "generate_rewrite_rules"));

class custom_mod_rewrite {
    function __construct() {
        $this->wp_rewrite = & $GLOBALS["wp_rewrite"];
    }
    function generate_rewrite_rules() {

        $non_wp_rules = array(
            'simple-redirect/?$plugin_name' => 'http://google.com',
            'one-more-redirect/?$plugin_name' => 'http://yahoo.com'
        );

        $this->wp_rewrite->non_wp_rules = $non_wp_rules + $this->wp_rewrite->non_wp_rules;
        add_filter('mod_rewrite_rules', array(&$this, "mod_rewrite_rules"));
    }
    function mod_rewrite_rules($rules) {
        return preg_replace('#^(RewriteRule \^.*/)\?\$plugin_name .*(http://.*) \[QSA,L\]#mi', '$1 $2 [R=301,L]', $rules);
    }
}

我发现有两个问题。

  1. 如果设置为默认永久链接,则不会添加规则。
  2. 更重要的是,除非用户更改固定链接设置,否则不会添加规则。(可以通过插件激活时执行$wp_rewrite->flush_rules()来解决)
  3. 对于#2,我想知道是否有一种以编程方式添加规则的好方法。

      

    IIS(Windows服务器上常见)不支持mod_rewrite。

    来源:http://codex.wordpress.org/Using_Permalinks#Permalinks_without_mod_rewrite

    听起来并非所有系统都使用.htaccess。因此,直接编辑.htaccess文件可能不是分布式插件的最佳选择。我不知道。可能我必须检查服务器是否使用Apache,如果需要,我需要检查.htacess是否可写,现有规则是否没有添加规则,最后我可以将规则附加到它。此外,当用户停用插件时,必须擦除规则。所以这很麻烦。

    如果WordPress可以使用内置API或其他东西来处理它,我想把它留给WordPress。但上面的例子是我迄今为止所能找到的。所以我感谢您的信息。

    更新

    pfefferle 建议,我可以使用$wp_rewrite->flush_rules()。然而,问题#1仍然存在;使用默认永久链接设置时,它不会产生任何影响。有什么想法吗?

    /* Plugin Name: Sample Mod Rewrite  */
    
    $custom_mod_rewrite = new custom_mod_rewrite;
    register_activation_hook( __FILE__, array($custom_mod_rewrite, 'flush_rewrite_rules'));
    register_deactivation_hook( __FILE__, array($custom_mod_rewrite, 'flush_rewrite_rules'));
    add_action('generate_rewrite_rules', array($custom_mod_rewrite, "generate_rewrite_rules"));
    
    class custom_mod_rewrite {
        function __construct() {
            $this->wp_rewrite = & $GLOBALS["wp_rewrite"];
        }
        function flush_rewrite_rules() {
            $this->wp_rewrite->flush_rules();
        }
        function generate_rewrite_rules() {
    
            $non_wp_rules = array(
                'simple-redirect/?$plugin_name' => 'http://google.com',
                'one-more-redirect/?$plugin_name' => 'http://yahoo.com'
            );
    
            $this->wp_rewrite->non_wp_rules = $non_wp_rules + $this->wp_rewrite->non_wp_rules;
            add_filter('mod_rewrite_rules', array(&$this, "mod_rewrite_rules"));
        }
        function mod_rewrite_rules($rules) {
            return preg_replace('#^(RewriteRule \^.*/)\?\$plugin_name .*(http://.*) \[QSA,L\]#mi', '$1 $2 [R=301,L]', $rules);
        }
    }
    

    此外,停用插件时,它不会更改回先前的规则。我只是遵循了codex示例,只是将其设置为在停用插件时刷新规则。所以应该有一些代码来删除添加的规则。

    作为附注,根据the codex

      

    刷新重写规则是一项昂贵的操作,......你应该在插件的激活钩子上刷新重写规则,或者当你知道需要更改重写规则时

    剩余问题:

    1. 如果设置为默认永久链接,则不会添加规则。
    2. 停用插件时,它不会更改回之前的规则。

3 个答案:

答案 0 :(得分:2)

添加一些更改后,您必须“刷新”重写规则:http://codex.wordpress.org/Function_Reference/flush_rewrite_rules

答案 1 :(得分:2)

不幸的是,目前似乎没有有效的解决方案。

答案 2 :(得分:1)

您可以使用symfony的路由系统,如下所述:http://pookey.co.uk/wordpress/archives/80-playing-with-symfony-routing-without-symfony

您可以编写一个简单的插件来实现ideea。

编辑:已经有一个编辑.htaccess的插件。 http://plugins.svn.wordpress.org/wp-htaccess-editor/trunk/以此为例。

注意:直接编辑.htaccess意味着apache用户具有对文件的写入权限,这可能很危险。但我想你已经知道了。 ;)