Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I want to access my post with id 17 like this:

http://localhost/archives/17/moot-bla-foo-ramble

In other words, the id shall decide, everything thereafter may (or may not) be the slug or anything else. Much like these links leading to the same page (many other sites do the same):

I tried to define a rewrite-rule like this near the top of my .htaccess:

RewriteRule ^archives/(\d{1,12})(?:/.*) archives/$1 [NC]

This almost works, i.e. goes to the right page, but get's me a page-not-found then, because wordpress looks at PATH_INFO again (I think) and states $query_string now is string attachment=moot-bla-foo-ramble

I do not want to do a 301 redirect.

My favourite or course, if such thing existed in Permalink Settings:Custom Structure

/archives/%post_id%/%wildcard%

Albeit that would make the 'ramble' mandatory, so even better...

/archives/%post_id%(/%wildcard%)?

wishful thinking, I guess.

share|improve this question

3 Answers 3

You shouldn't use the htaccess instead you should use the WordPress APIs

e.g.

function custom_rewrite( $wp_rewrite ) {

    $feed_rules = array(
        'archives/(\d+)(?:/.*)+'    =>  'index.php?p='. $wp_rewrite->preg_index(1)
);

    // ( array merge must be done this way, to ensure new rule comes first )
    $wp_rewrite->rules = $feed_rules + $wp_rewrite->rules;
}
// refresh/flush permalinks in the dashboard if this is changed in any way
add_filter( 'generate_rewrite_rules', 'custom_rewrite' );
share|improve this answer
1  
Thank you, great solution! I edit-in the correct Reg-Exp. –  Fronker Apr 10 '12 at 11:50
    
And just for the record: RewriteRule ^archives/([0-9]+)(?:/.*) index.php?p=$1 [NC] aka _directly writing to the index.php GET-Form works, but gets you a 301 redirect (triggered by WP). Better than nothing... –  Fronker Apr 10 '12 at 11:52
    
hmm you unnaccepted my answer, does it no longer work for you? –  Tom J Nowell Apr 11 '12 at 14:37
    
it worked, but it broke my (normal, not in any way enhanced) tag and category urls... :-( Sorry! –  Fronker Apr 12 '12 at 22:03

Essentially the same as @Tom's answer, but using the provided add_rewrite_rule wrapper:

add_action('init','wpse48481_rewrite_rules');
function wpse48481_rewrite_rules(){
    add_rewrite_rule('^archives/([0-9]{1,})/','index.php?p=$matches[1]','top');
}

This will check for urls of the form:

 http://www.yoursite.com/archives/99/something-else

and interpret it as the post/page/cpt with ID =99. Of course the regex can be whatever you like...

share|improve this answer
    
Thank you! Does this wrapper save me (and my theme users) of the costly (around 200ms) resp. one-time-manual flush thing? –  Fronker Apr 10 '12 at 12:12
    
[0-9]{1,} <=> [0-9]+ :-) –  Fronker Apr 10 '12 at 12:12
    
re: manual flushing, nope afraid not. –  Stephen Harris Apr 10 '12 at 12:21
    
Does not work for me. As soon as I go for the actual use case with trailing stuff add_rewrite_rule('^archives/(\d+)(?:/.*)+$','index.php?p=$matches[1]','top'); I get a e404 with a query string of 'somthing-else' (much like my first htaccess attempt). I did ensure the function is called, I did ensure flush. Regardless of (non)use of ^ and $ –  Fronker Apr 10 '12 at 12:29
    
It works for me with/without trailing slash with the regex: '^archives/([0-9]+)(/.*)?' –  Stephen Harris Apr 10 '12 at 12:39

I am sorry to say, but all this brought me into kneep-deep troubles. Suddenly tag and category urls ceased to work, giving a "Well this is embarrassing" empty search page...

Even a neutral, non-changing callback triggered by flush w/o adding anyrules would break things like * /archives/tag/kiwis * /archives/categories/fruits

Removing it all and saving /wp-admin/options-permalink.php (i.e. numeric settings) fixes it again. Repeatedly. Very verified. Also see this thread at wordpress.org.

Basically, spending a day, I have come up with a very simple hack, that appears to work. adding this in the .htacces, before the wordpress block

RewriteRule ^archives/(\d{1,12})(?:/.*) archives/$1 [NC,L]

adding this in my theme's functions.php. Directly. No hook.

if ( isset($_SERVER["REDIRECT_URL"]) )
    $_SERVER["REQUEST_URI"] = $_SERVER["REDIRECT_URL"];

Yep, pretty dirty, writing to a $_SERVER variable. And voila, all my testcases work ( simple url, ramble-attached url, tags, category, ...) (nb: without the if your very start page ceases to work (never-ending redirect loop)

share|improve this answer
    
Clearly our rewrite rules worked, they just had the incorrect priority/ordering so they took priority over the tag and category rewrite rules. Adjusting the priority of the filter action etc would have corrected the issue (possibly even swapping the order of the array addition operation). You should've come back and made this apparent before spending a day on your own solution –  Tom J Nowell Apr 11 '12 at 14:41
    
How do I change priority / order? (other than manually fiddling with the array?) –  Fronker Apr 12 '12 at 22:04
    
well instead of A = B + A, you could try A = A + B when adding the new rules to the old ones. There's also the priority on the add_filter call, the third parameter? You needn't re-order the array, just the order of execution. Monkeyman rewrite rules will tell you more about ordering. –  Tom J Nowell Apr 13 '12 at 9:03
    
There is also the $position parameter on add_rewrite_rule in stephens answer which is currently set to 'top', perhaps a lower priority would work better? e.g. 'bottom' –  Tom J Nowell Apr 13 '12 at 9:03
    
I tried A = A + B. No luck :-( I am happy with my (arguably dodgy but lean)solution. Thank you for all your effort. –  Fronker Apr 17 '12 at 9:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.