3

I want all my posts to have /ARTICLES/%post-name% structure.

But as soon as I modify the custom structure to that, for a reason that beats me, wordpress adds the articles prefix across the board.

So I end up with urls like this for my category pages with something like the following

mysite.com/articles/category/videos

here the videos is a category and since I did not change the category to anything else, I was expecting the urls to be well, mysite.com/category/videos ), not mysite.com/articles/category/whatever Obviously, such a URL does not make sense.

On the permalinks screen, under the Common Settings's Post name option, I get a grayed out ( uneditable ) sample link that shows something like mysite.com/sample-post.

I wished I could have edit that grayed out info

to mysite.com/articles/sample-post while keeping the other options as is.

But this does not seem to be possible.

Am I at a dead-end here?

Is there a way to only change the post urls without effecting the other urls?

3

4 Answers 4

8

1) Add this rewrite at the end of you function.php

function add_rewrite_rules( $wp_rewrite )
{
    $new_rules = array(
        'YOUR_PREFIX/(.+?)/?$' => 'index.php?post_type=post&name='. $wp_rewrite->preg_index(1),
    );

    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'add_rewrite_rules'); 

function change_blog_links($post_link, $id=0){

    $post = get_post($id);

    if( is_object($post) && $post->post_type == 'post'){
        return home_url('/YOUR_PREFIX/'. $post->post_name.'/');
    }

    return $post_link;
}
add_filter('post_link', 'change_blog_links', 1, 3);

2) Go to Settings > Permalinks and click Save Changes.

6
  • Thanks Fury, would this ( rewriting flexibility ) allow me to do the following? I got a permalink structure like this mysite.com/cat-base/cat-term and I'd like mysite.com/cat-term to serve that. ( if you do not have a "page" with the same category term, would that work? Would your function can pull that off as well? Oct 14, 2016 at 6:28
  • I am afriad not. This code just adds a /blog/ as prefix before all posts urls. How ever I am sure you can extent it hopefully you can get it work for your case.
    – Fury
    Oct 14, 2016 at 11:09
  • Thanks for your answer, It's working really well for me. May 2, 2018 at 13:45
  • Works for me in 2021, WP 5.8.1 Sep 29, 2021 at 17:40
  • This does not take into account paging, ex. /YOUR_PREFIX/page/4/ will not work Feb 28 at 8:12
2

Wordpress puts "/category/" by default as the category base in the permalinks even for a category page.

You have to change your custom permalink structure to:

/%category%/%postname%/

Put "articles" in the category base field and your permalinks for example at category page "Videos" will display in this form:

mysite.com/articles/videos

It won't work with post's permalinks thought as "articles" parts will be omitted from the permalink like this:

mysite.com/videos/postname
1

The WordPress SEO Plugin by Yoast has a section called permalinks where you can strip the category base (usually /category/) from the category URL.

1
<?php
/**
 * Add new rewrite rule
 */
function create_new_url_querystring() {
    add_rewrite_rule(
        'blog/([^/]*)$',
        'index.php?name=$matches[1]',
        'top'
    );
    add_rewrite_tag('%blog%','([^/]*)');
}
add_action('init', 'create_new_url_querystring', 999 );
/**
 * Modify post link
 * This will print /blog/post-name instead of /post-name
 */
function append_query_string( $url, $post, $leavename ) {
    if ( $post->post_type != 'post' )
            return $url;


    if ( false !== strpos( $url, '%postname%' ) ) {
            $slug = '%postname%';
    }
    elseif ( $post->post_name ) {
            $slug = $post->post_name;
    }
    else {
        $slug = sanitize_title( $post->post_title );
    }

    $url = home_url( user_trailingslashit( 'blog/'. $slug ) );
    return $url;
}
add_filter( 'post_link', 'append_query_string', 10, 3 );
/**
 * Redirect all posts to new url
 * If you get error 'Too many redirects' or 'Redirect loop', then delete everything below
 */
function redirect_old_urls() {
    if ( is_singular('post') ) {
        global $post;
        if ( strpos( $_SERVER['REQUEST_URI'], '/blog/') === false) {
           wp_redirect( home_url( user_trailingslashit( "blog/$post->post_name" ) ), 301 );
           exit();
        }
    }
}
add_filter( 'template_redirect', 'redirect_old_urls' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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