custom permalinks for category archive ( custom base and no parent slug )

All you have to do to achieve this is to modify the category taxonomy arguments by using register_taxonomy() again at the init hook after the category taxonomy has been registered. This can be done with any taxonomy as in the following snippet.

Code for Taxonomies in General (Code for this use case below):

function mytheme_change_category_args() {

    // Get the taxonomy.
    $category = get_taxonomy( 'category' );

    // change the rewrite slug on the taxonomy itself.
    // Note that if your permalink structure is currently 
    // "/post/%postname%", this should be changed to "c", and 
    // "with_front" should be set to "true".
    $category->rewrite['slug'] = 'post/c'; 

    // do not use the text that comes before the first 
    // rewrite tag (%...%) in the permalink settings, unless the
    // setting is "/post/%postname%" as explained above. 
    $category->rewrite['with_front'] = false; 

    // Keep the category hierarchical, but make the permalinks flat.
    $category->rewrite['hierarchical'] = false;

    // register_taxonomy() is used to create OR modify a taxonomy. 
    // make sure the taxonomy object is cast to an array.
    register_taxonomy( 'category', 'post', (array) $category ); 

}

// Make sure this happens after the original tax is init. Priority 10 is fine.
add_action( 'init', 'mytheme_change_category_args', 10 );

Note:

Go to Settings->Permalinksand hit “Save Changes” to flush the rewrite rules. No need to filter term links, add rewrite rules, or anything else.


To answer your question specifically:

In order to do this with the core WP taxonomies like category and post_tag, we have to keep in mind the Category and Tag permalink settings at Settings->Permalinks Which the above example does not. The best way to do this is actually the simplest way too.

Code for this use case:

Option 1:

function mytheme_change_category_args() {

    $category = get_taxonomy( 'category' );
    $post_tag = get_taxonomy( 'post_tag' );

    $category->rewrite['hierarchical'] = false;
    $category->rewrite['with_front'] = false;
    $post_tag->rewrite['with_front'] = false;

    register_taxonomy( 'category', 'post', (array) $category ); 
    register_taxonomy( 'post_tag', 'post', (array) $post_tag ); 

}

add_action( 'init', 'mytheme_change_category_args', 50 );

All you have to do is set category to non-hierarchical permalinks, and set with_front to false on both category and post_tag. then set your permalinks at Settings->Permalinks as in the image below 😉

Cat Tag Permalinks

Option 2:

function mytheme_change_category_args() {

    $category = get_taxonomy( 'category' );
    $post_tag = get_taxonomy( 'post_tag' );

    $category->rewrite['hierarchical'] = false;
    $category->rewrite['with_front'] = true;
    $post_tag->rewrite['with_front'] = true;

    register_taxonomy( 'category', 'post', (array) $category ); 
    register_taxonomy( 'post_tag', 'post', (array) $post_tag ); 

}

add_action( 'init', 'mytheme_change_category_args', 50 );

In this case, what you have to do is set category to non-hierarchical permalinks (as in Option 1), and set with_front to true on both category and post_tag. Then, set your permalinks at Settings->Permalinks as in the image below, keeping in mind that any plain text tags that you place before the first rewrite tag (%...%) of the POST PERMALINK setting will appear before the cat/tag permalink base. If this is set to /post/%...%/%...%/%...%/, this is the best option, for sure.

Permalink Settings Screen Shot