Reputation: 2632
The following sample plugin adds the custom mod rewrite rules to .htaccess
when the user changes the permalink settings.
/* 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);
}
}
There are two problems I found with this.
$wp_rewrite->flush_rules()
performed at the plugin activation)For #2, I'm wondering if there is a good way to add the rules programmatically.
IIS (common on Windows servers) does not support mod_rewrite.
source: http://codex.wordpress.org/Using_Permalinks#Permalinks_without_mod_rewrite
It sounds like not all systems use .htaccess
. So directly editing the .htaccess
file may not be the best choice for a distributed plugin. I don't know. Probably I have to check if the server uses Apache and if so I need to check whether .htacess is writable and existing rules do not have the adding rules, then at last I can append the rules to it. Also when the user deactivate the plugin, the rules have to be erased. So it's kind of troublesome.
If WordPress can handle it with a built-in API or something, I'd like to leave it to WordPress. But the above example was what I could have found so far. So I appreciate your information.
Update
As pfefferle suggested, I could use $wp_rewrite->flush_rules()
. However, the problem #1 still persists; it won't take any effect when the default permalink settings is used. Any ideas?
/* 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);
}
}
Also, when deactivating the plugin, it doesn't change back to the previous rules. I just followed the codex example and just set it to flush the rules when deactivating the plugin. So there should be some code to delete the added rules.
As a side note, according to the codex,
Flushing the rewrite rules is an expensive operation, ... ... you should flush rewrite rules on the activation hook of a plugin, or when you know that the rewrite rules need to be changed
Remaining Issues:
Upvotes: 7
Views: 5273
Reputation: 2632
Unfortunately, there seems to be no effective solution for it at the moment.
Upvotes: 3
Reputation: 5609
You can use symfony's routing system like described here: http://pookey.co.uk/wordpress/archives/80-playing-with-symfony-routing-without-symfony
You can write a simple plugin to implement the ideea.
EDIT: there is already a plugin that edits .htaccess. http://plugins.svn.wordpress.org/wp-htaccess-editor/trunk/ Use it as an example.
NOTICE: Editing directly .htaccess means apache user has write access to the file and this can be dangerous. But i suppose you already know that. ;)
Upvotes: 1
Reputation: 503
You have to "flush" the rewrite rules after you add some changes: http://codex.wordpress.org/Function_Reference/flush_rewrite_rules
Upvotes: 2