nicer slug url rewrite plugin (done!)
-
Hi all.
(Sorry for my bad english. I tried to be verbose in order to avoid my bad english affect your understanding)
I wrote a plug-in, in order to have the best rewrite rules (in my opinion :p ) in the world.
this plugin achieves two things:
One: I need to show, in the URL, the logical parent-to-child relation between forums and topics, so
http://www.example.com/bbpress/topic/my-sweet-dog
URL has to show the forum that contains the topic, and become
http://www.example.com/bbpress/forum/pets-discussions/topic/my-sweet-dog
when performing the rewrite, the rules totally ignore the forum part, so it’s only a visual thing.
and, more difficult,
Two: I need to shorten the URL and have fewer subdirectories, so
http://www.example.com/bbpress/forum/pets-discussions/topic/my-sweet-dog
has to lose the useless “/forum/” and the useless “/topic/” parts, and become
http://www.example.com/bbpress/pets-discussions/my-sweet-dog
ATTENTION: you cannot do the second thing without the first thing. you must be able, in rewrite rules, to discriminate between a topic and a forum. you then will have that forums have one string (the forum slugged name), while topics have two strings (the forum slugged name and the topic slugged name), so you can do that, and /pets-discussion/my-sweet-dog will belong to “My Sweet Dog” topic in “Pets Discussions” forum
In order to do so, I need to
– modify forum link creation
– modify topic link creation
– modify rewrite rules
– avoid a forum to have a reserved name, as using bbpressfolder/forumname to reach a forum is risky! I have to prevent a forum from having a slugged name like “bb-admin”!!! here’s a list of reserved words:
– all words with a dot. those are files, like style.css and so on. the slugged names never have a dot. I have only to avoid rewrite of dotted words.
– all bbpress subfolders and special folders. these are all that start with
bb-* , my-*
– every other reserved word already used by rewrite engine:
tag, profiles, view, rss
All this is achieved adding a “r-” string in front of the slugged string. so a forum named “My Forum!” will have “r-my-forum” as slugged name. Unfortunately, this filter operates also for topic names and maybe other things. this mean that a topic named “rss” will have “r-rss” as slugged name. Not so bad, in facts.
So these are the operations:
– add a filter to get_forum_link (delete the “/forum” part)
– add a filter to get_topic_link (add the “forum/slug-forum-name” in the link, and eliminate the “/forum” and “/topic” parts)
– modify the rewrite rules (I used IIS isapirewrite, but apache is pretty the same)
– add a filter to bb_slug_sanitize (avoid a forum to have a reserved word as slugged-name, like “rss”, “profiles”, “my-plugins”, etc
And there is the code for these operations:
function my_get_forum_link_filter( $link , $forum_id = 0 ) {
//retrieve the forum object
$forum = get_forum( get_forum_id( $forum_id ));
//check for rewrite
$rewrite = bb_get_option( 'mod_rewrite' );
if ( $rewrite ) {
//what kind of rewrite there is? slug use "forum_slug" column, else the column is "forum_id"
$column = ($rewrite === 'slugs')?('forum_slug')'forum_id');
// change /forum/pets-discussions in /pets-discussions
// this work only if the rewrite module is modded!
// and this work only if the slugged name will NEVER
// be a reserved word like "rss" or "bb-images"
// and this is achieved by a filter on bb_slug_sanitize
$link = str_replace('forum/' . $forum->$column , $forum->$column, $link);
}
return $link; // Very important line!
}
add_filter( 'get_forum_link', 'my_get_forum_link_filter' );
function my_get_topic_link_filter( $link, $topic_id = 0) {
//retrieve the topic object
$topic = get_topic( get_topic_id( $topic_id ));
//retrieve the forum object that is the topic container
$forum = get_forum( get_forum_id( $topic->forum_id ));
//check for rewrite
$rewrite = bb_get_option( 'mod_rewrite' );
if ( $rewrite ) {
//what kind of rewrite there is? slug use "forum_slug" column, else the column is "forum_id"
$column = ($rewrite === 'slugs')?('forum_slug')'forum_id');
//create the "forum/pets-discussions" chunk to show the hierarchical relation forum->topic
$forum_nice_uri = "forum/" . $forum->$column . "/";
//attach the hierarchical chunk to the link
$link = str_replace(bb_get_option('uri'), bb_get_option('uri') . $forum_nice_uri, $link);
// change /forum/pets-discussions/topic/my-sweet-dog in /pets-discussions/my-sweet-dog
// this work only if the rewrite module is modded!
// and this work only if the slugged name will NEVER
// be a reserved word like "rss" or "bb-images"
// and this is achieved by a filter on bb_slug_sanitize
$link = str_replace('forum/' . $forum->$column , $forum->$column, $link);
$link = str_replace('topic/' . $topic->$column , $topic->$column, $link);
}
return $link; // Very important line!
}
add_filter( 'get_topic_link', 'my_get_topic_link_filter' );
function my_bb_slug_sanitize_filter( $text_slug, $text_original = '', $length = 0 ) {
// add "r-" by regex when the string begins with "bb-" or "my-" or is a reserved word
return preg_replace('/^(my-.*|bb-.*|rss|tags|view|profiles)$/', 'r-$1', $text_slug);
}
add_filter( 'bb_slug_sanitize', 'my_bb_slug_sanitize_filter' );And there’s the rewrite rules! ATTENTION!!!!! these rules are for IIS isapirewrite, so these are to be modded to work with apache! sorry but I don’t have any apache installation to play with. It’s a simple task, anyway. Every regex guru and regex accolite can do that. Even a regex wannabe can find out googling.
# first we rewrite the pages for normal slug-rewrite usage
RewriteRule /bbpress/tags/([^/?]+)/page/([0-9]+)(??(.*))? /forum2/tags.php?tag=$1&page=$2?3&$3: [I,L]
RewriteRule /bbpress/tags/([^/?]+)/?(??(.*))? /forum2/tags.php?tag=$1?2&$2: [I,L]
RewriteRule /bbpress/tags/?(??(.*))? /forum2/tags.php(?1?$1:) [I,L]
RewriteRule /bbpress/profile/([^/?]+)/page/([0-9]+)(??(.*))? /forum2/profile.php?id=$1&page=$2?3&$3: [I,L]
RewriteRule /bbpress/profile/([^/?]+)/([a-z-]+)(??(.*))? /forum2/profile.php?id=$1&tab=$2?3&$3: [I,L]
RewriteRule /bbpress/profile/([^/?]+)/([a-z-]+)/page/([0-9]+)(??(.*))? /forum2/profile.php?id=$1&tab=$2&page=$3?4&$4: [I,L]
RewriteRule /bbpress/profile/([^/?]+)/?(??(.*))? /forum2/profile.php?id=$1?2&$2: [I,L]
RewriteRule /bbpress/view/([a-z-]+)/page/([0-9]+)(??(.*))? /forum2/view.php?view=$1&page=$2?3&$3: [I,L]
RewriteRule /bbpress/view/([a-z-]+)(??(.*))? /forum2/view.php?view=$1?2&$2: [I,L]
RewriteRule /bbpress/rss/(??(.*))? /forum2/rss.php?1&$1: [I,L]
RewriteRule /bbpress/rss/forum/([0-9]+)(??(.*))? /forum2/rss.php?forum=$1?2&$2: [I,L]
RewriteRule /bbpress/rss/topic/([0-9]+)(??(.*))? /forum2/rss.php?topic=$1?2&$2: [I,L]
RewriteRule /bbpress/rss/tags/([a-z-]+)(??(.*))? /forum2/rss.php?tag=$1?2&$2: [I,L]
RewriteRule /bbpress/rss/profile/([0-9]+)(??(.*))? /forum2/rss.php?profile=$1?2&$2: [I,L]
# then we have a rule for special words, so they are left as they are, and the isapi module does not proceed further
RewriteRule /bbpress/(my-.*|bb-.*|rss|tags|view|profiles)(/.*)? /forum2/$1$2 [I,L]
# then we have the forum and topic rules.
# ATTENTION: we DO NOT rewrite a dottet word, because dotted words can be files like style.css and so on
# before there are the topic rewrites, that are longer
# ATTENTION: note that the forum name is totally skipped trough ?: notation. In facts, bbpress doesn't need the forum name when reading a topic
RewriteRule /bbpress/(?:[^./?]+)/([^./?]+)/page/([0-9]+)(??(.*))? /forum2/topic.php?id=$1&page=$2?3&$3: [I,L]
RewriteRule /bbpress/(?:[^./?]+)/([^./?]+)/?(??(.*))? /forum2/topic.php?id=$1?2&$2: [I,L]
# and after there are the forum rewrites, that are shorter
RewriteRule /bbpress/([^./?]+)/page/([0-9]+)(??(.*))? /forum2/forum.php?id=$1&page=$2?3&$3: [I,L]
RewriteRule /bbpress/([^./?]+)/?(??(.*))? /forum2/forum.php?id=$1?2&$2: [I,L]And that’s all. I hope someone can use this plugin
Gus
email: shiawase at gmail dot com
- You must be logged in to reply to this topic.