1

I have a unique kind of question that I've been wrapping my brain around. Google is penalizing us with duplicate content because you can access our single blog posts both by going to:

http://www.domain.com/blog/the-post-slug

as well as :

http://www.domain.com/the-post-slug

The option we really want is:

http://www.domain.com/blog/the-post-slug

and if a user or googlebot happens to goto:

http://www.domain.com/the-post-slug 

redirect them to:

http://www.domain.com/blog/the-post-slug

I know this is a particular situation, but we have many custom post types in our system. So our structure looks like this.

http://www.domain.com/food/pizza
http://www.domain.com/ice-cream/strawberry
http://www.domain.com/fireworks/bottle-rockets

Ideally, what I would like to do is find some kind of filter that logically checks if the post_type is post and redirect:

http://www.domain.com/the-post-slug 

to

http://www.domain.com/blog/post-slug

I tried modifying the register_post_type for the post object, and adding with_front => false and adding blog to the slug, but that doesn't work.

I was able to add /blog/%postname%/ to the permalink structure, and I was successfully able to have a decent structure going that was working, but I got stuck on the taxonomies. When I went to a taxonomy page, I had to goto:

http://www.domain.com/blog/the-taxonomy/flavors

and:

http://www.domain.com/the-taxonomy/flavors 

was giving me a 404. So even if I can find a way to make the taxonomies work to where I can do:

http://www.domain.com/the-taxonomy/flavors

that would be awesome! As another side note, I also added with_front to the register_taxonomy, but that was not doing anything either. I even hard flushed the rewrites on all the changes I did.

I know this is a lot, but my brain cannot go any further.. lol

TIA!

Any insight on this?

1
  • 'rewrite' => array( 'with_front' => false ) is your answer, add your taxonomy registration code to your question if it's not working for you.
    – Milo
    Commented Nov 8, 2013 at 22:22

1 Answer 1

2

First of all set your permalink structure to /%postname%.

After that add a rewrite rule to rewrite all request like example.com/blog/postname to the appropriate query:

add_action('init', 'blog_front');

function blog_front() {
  add_rewrite_rule('^blog/([^/]+)/?','index.php?name=$matches[1]','top');
}

Now you have to prevent the duplicate url, sending a 301 redirect when example.com/postname is requested:

add_action('template_redirect', 'say_hello_to_google');

function say_hello_to_google() {
  if ( is_main_query() && is_single() && ( empty( get_post_type() ) || (get_post_type() === 'post') ) ) {
    if ( strpos( trim( add_query_arg( array() ), '/' ), 'blog' ) !== 0 ) {
      global $post;
      $url = str_replace( $post->post_name, 'blog/' . $post->post_name, get_permalink( $post ) );
      wp_safe_redirect( $url, 301 );
      exit(); 
    }
  }
}

Finally you have to create permalink for your post with 'blog/' in front:

add_filter('the_permalink', 'post_permalink_w_blog');

function post_permalink_w_blog( $link ) {
  global $post;
  if ( $post->post_type === 'post' ) {
    $link = str_replace( $post->post_name, 'blog/' . $post->post_name, get_permalink( $post ) );
  }
  return $link; 
}

Last thing to is flush rewrite rules and... test.


Edit

As @Milo pointed out in comments, all of this can be avoided by setting permalink structure to /blog/%postname% and then use the param 'rewrite' having 'with_front' to false for all CPTs and all taxonomies.

'rewrite' => array( 'with_front' => false )

The problem is that most times, in a average WP install with a lot of CPT and taxonomies, there are chances that some of them are registred via 3rd party plugins... in that case if that plugins register the CPTs/taxonomies not using 'with_front' => false it's a problem and the solution posted above is the last chance.

In addiction I have to say that standard categories and tags are registered with 'with_front' = true, so using this alternative method also standard category and tag must be re-registered with with_front param setted to false.

6
  • none of this is necessary if the permalink structure is /blog/%postname%/ and taxonomies are correctly registered to not use the /blog/ front. I think the issue is that OP just didn't register the taxonomies with the correct arguments.
    – Milo
    Commented Nov 8, 2013 at 22:47
  • same for CPTs, register them with 'rewrite' => array( 'with_front' => false ) and they won't be prepended with /blog/
    – Milo
    Commented Nov 8, 2013 at 22:59
  • @Milo updated answer.
    – gmazzap
    Commented Nov 8, 2013 at 23:22
  • I tried the quick fix of just adding with_front to the register_taxonomy, and changed the permalink structure to /blog/%postname%/ and when I go to domain.com/work-type/graphic-design I get a 404, and if I goto domain.com/blog/work-type/graphic-design I also get a 404 error. What I did before to register the taxonomies was use the Custom Post Type plugin. I then generated the code from the plugin, put it in my functions.php and deleted the taxonomy from the plugin, basically it's only getting registered with the functions.php. Here is my tax: pastebin.com/MSydZbZN
    – Aaron Olin
    Commented Nov 9, 2013 at 1:40
  • @AaronOlieOlin your code contains an error: 'rewrite' => array('with_front' => false) is inside 'labels' array. Try this and flush rewrite rules. Also remember that you have to re-register standard category and standard tags if you don't want '/blog' in front of them.
    – gmazzap
    Commented Nov 9, 2013 at 2:05

Your Answer

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

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