Search code examples
phpwordpresscustom-post-typepermalinks

Custom Post Type URL rewrite with Post Type Template


I am building a Wordpress site for a video production company. They produce videos for adults as well as for kids and therefore I split the posts in the backend to keep a structure. So the setup is the following:

  • Two Custom Post Types named productions_big and productions_small
  • A page named Productions, placed in the main navigation with links to For Big and For Small pages
  • One page listing the posts of productions_big, one listing posts of productions_small. The page names are for-big and for-small and both are children of the Productions page
  • The URLs are perfectly fine for the pages as I made a parent/child relation of the relevant pages. example.com/productions leads to the right page as well as example.com/productions/for-big and example.com/productions/for-small do.
  • For reasons that are irrelevant to this question the templates for the CPTs differ, but in some occasions template-big is used for productions_small and vice versa. There is no actual logic behind this and therefore the decision on which template to use is done in the backend via the Post Type Template feature introduced with Wordpress 4.7

What I want to achieve is a logical URL structure like example.com/productions/for-big/name-of-adult-production. Right now I have URLs like example.com/productions_big/name-of-adult-production as productions_big is the name of the CPT.

I am familiar with the rewrite argument you should pass when registering custom post types. I have done this in all the ways suggested at stackoverflow but it is just not working. Here is an excerpt of the code I use to register my CPTs:

add_action('init', 'all_custom_post_types');

function all_custom_post_types() {

  $types = array(

    array('the_type' => 'productions_big',
                ...

    array('the_type' => 'productions_small',
                ...

);

  foreach ($types as $type) {

  $the_type = $type['the_type'];
    ...

  $args = array(
    'labels'        => $labels,
    'public'        => true,
    'publicly_queryable' => true,
    'show_ui'       => true,
    'query_var'     => true,
    'rewrite'       => true,
    'capabilities'  => array(
      ...),
    'rewrite'       => array('has_archive' => false, 'slug' => 'bla', 'with_front' => false),
    'has_archive'   => false,
    'map_meta_cap'  => true,
    'hierarchical'  => false,
    'menu_position' => 5,
    'supports'      => array('title','editor','thumbnail', 'taxonomies'),
    'taxonomies'    => array( 'category' )
  );

    register_post_type($the_type, $args);

  }

}

As you see I tried 'rewrite' => array('slug' => 'bla') because I wanted to know if it does not work because of a conflict of page names when I write 'rewrite' => array('slug' => 'productions/for-big')

But whatever value I give the slug, it always redirects me to index.php.

I thought the reason why it is not working is caused by the way I am assigning post templates (remember: as a post attribute in the backend, not a dedicated single-xxx.php file) but I couldn't find a solution anywhere. All solution-seekers posting their questions were assigning templates the good old fashioned single-name_of_cpt.php way (which is not possible for me).

Sidenote: The ultimate goal would be to make the slug "dynamic". Meaning that it changes in case the page names are altered in the backend. I might try this approach but beforehand I'll have to get rid of the basic problems described here.

Any idea is much appreciated. And thank you for reading this far.


Solution

  • Oh boy, seems you have to post your questions in order to find an answer yourself. After trying to setup another CPT everything worked like a charm.

    That made me investigate the registration of the previous CPTs. As you can see above I tried to register my CPTs inside of one function

    function all_custom_post_types() {
    
      $types = array(
        array('the_type' => 'productions_big', ...
        array('the_type' => 'productions_small', ...
      );
    
      foreach ($types as $type) {
    
      $args = array(...
        'rewrite'       => array('slug' => 'bla'),...
      );
    
      register_post_type($the_type, $args);
    
      }
    
    }
    

    So ultimately there was no conflict between the slugs of my pages and custom post types but a conflict of giving one and the same slug to two different post types.