Skip to main content
replaced http://wordpress.stackexchange.com/ with https://wordpress.stackexchange.com/
Source Link

I also tried a solution given here http://wordpress.stackexchange.com/a/101077/86838https://wordpress.stackexchange.com/a/101077/86838 where it allowed to remove the parent slug from child permalink, but I was still unsuccessful

I also tried a solution given here http://wordpress.stackexchange.com/a/101077/86838 where it allowed to remove the parent slug from child permalink, but I was still unsuccessful

I also tried a solution given here https://wordpress.stackexchange.com/a/101077/86838 where it allowed to remove the parent slug from child permalink, but I was still unsuccessful

Source Link
Kuuak
  • 81
  • 1
  • 1
  • 7

Custom rewrite rule for hierarchical custom post type

Working on a client site I've encounter my worst enemy... WP URL rewrite :(. I actually can't figure it out and after many days trying and searching, I can't make it work.

What I'm trying to get is a permalink like this company.com/product/%product-name%/ regardless of the /parent/child/ nesting depth. I do need the functionalities of the hierarchical pages for other reasons, but it should not appear in the URL.

Here is my set up:

  • Wordpress 4.4.1

  • Permalink settings set to Post name

  • I created a hierarchical custom post type product with rewrite parameter to false.

      $args = array(
          'label'                 => __( 'Product', 'domain' ),
          'description'           => __( 'Company products', 'domain' ),
          'labels'                => $labels,
          'supports'              => array( 'title', 'editor', 'excerpt', 'thumbnail', 'revisions', 'page-attributes' ),
          'taxonomies'            => array( 'category', 'post_tag' ),
          'hierarchical'          => true,
          'public'                => true,
          'show_ui'               => true,
          'show_in_menu'          => true,
          'menu_position'         => 5,
          'show_in_admin_bar'     => true,
          'show_in_nav_menus'     => false,
          'can_export'            => true,
          'has_archive'           => true,
          'exclude_from_search'   => false,
          'publicly_queryable'    => true,
          'rewrite'               => false,
          'capability_type'       => 'page',
      );
      register_post_type( 'product', $args );
    

At this point the products don't have a pretty permalink, they look like this and they both work:

  1. First level: company.com/?product=my-first-product -> ok
  2. Second level: company.com/?product=my-first-product/child-product -> ok

After that, I registered the rewrite rule and permastruct then flushed the rewrite rules by saving changes in the permalink settings page

    function bvt_product_rewrite_rule() {
        add_rewrite_rule( 
            '^product/([^/]+)/?$',
            'index.php?post_type=product&pagename=$matches[1]',
            'top'
        );
        add_permastruct( 'product', '/product/%product%/' );
    }
    add_action( 'init', 'bvt_product_rewrite_rule', 10 );

Now the permalinks where correctly displayed for first level page but not correct for child page. Also both levels gave me a 404 error.

  1. First Level: company.com/product/my-first-product/ -> 404
  2. Second Level: company.com/product/my-first-product/child-product/ -> 404

I also tried a solution given here http://wordpress.stackexchange.com/a/101077/86838 where it allowed to remove the parent slug from child permalink, but I was still unsuccessful

function bvt_product_flatten_hierarchies( $post_link, $post ) {
    if ( 'product' != $post->post_type ) {
        return $post_link;
    }

    $uri = '';
    foreach ( $post->ancestors as $parent ) {
        $uri = get_post( $parent )->post_name . "/" . $uri;
    }

    return str_replace( $uri, '', $post_link );
}
add_filter( 'post_type_link', 'bvt_product_flatten_hierarchies', 10, 2 );

I installed two plugins debug-bar and monkeyman-rewrite-analyzer to analyse the rewrite and query, but I keep can't make it work.

My last try was with wp-permastructure plugin with allow to set custom permalink to custom post type. Which enables the custom setting permastruct in the rewrite array option of the register_post_type.

[...]
'publicly_queryable'    => true,
'rewrite'               => array(
    'permastruct'   => '/%postname%/',
),
'capability_type'       => 'page',
[...]

With this setting and both previous custom rewrite/permatruct/flatten_hierarchies desabled, it worked as stated by the plugin description

  1. First Level: company.com/my-first-product/ -> ok
  2. Second Level: company.com/child-product/ -> ok

But now the /product/ level is missing, and if I try to put it in the 'permastruct' => '/product/%postname%/' config it brings me back to both a 404 error.

Which leads to my main question.

Is it possible to do what I need to or only as close as I could go with the latest plugin ?

Thanks already for anybody who will take the time to answer me, and maybe save me from my poor situation. Thanks

PS I can't insert more than two links in the body so here is the mentioned plugin links:

https://wordpress.org/plugins/debug-bar/
https://wordpress.org/plugins/monkeyman-rewrite-analyzer/
https://wordpress.org/plugins/wp-permastructure/