0

I have the following code in my functions.php file. I have a page projects. I have two custom post types: project and projecttype. An individual project post has it's own permalink /projects/project-name. Projecttypes do need to show the 'projects' page.

My code checks if the url is a subpage of /projects/. If the subpage is a projecttype, it loads the template for the projects page (id 8).

if(substr( $_SERVER['REQUEST_URI'], 0, 11 ) === '/projects/'){
  $request_subpage = str_replace('/', '', str_replace('/projects/', '', $_SERVER['REQUEST_URI']));
  if($request_subpage !== '') {
    $valid_subpage_url = false;
    $project_types = get_posts( array( 'post_type' => 'projecttype', 'posts_per_page' => -1 ) );
    foreach( $project_types as $project_type ) :
      if( $project_type->post_name === $request_subpage ) :
        $valid_subpage_url = true;
        break;
      endif;
    endforeach;
    //flush_rewrite_rules();
    if($valid_subpage_url) add_rewrite_rule( "^projects\/$request_subpage$", "index.php?page_id=8", 'top');

  }
}

When I uncomment flush_rewrite_rules(); my code works. When I don't flush the rewrite rules, it does not work (all projecttype subpages return a 404). Since flush is an expensive operation, I probably shouldn't use it.

What's going on here?

3
  • Sounds like projecttype could just be a taxonomy for projects? Commented May 3, 2019 at 8:25
  • @JKL For what purpose do you create projecttype posts that load the same page? As noted, the name suggests that projecttype could be taxonomy. What does projects page do? Depending on the projecttype displays different content?
    – nmr
    Commented May 4, 2019 at 6:32
  • @nmr the projects page shows content and displays projects (custom post type). When going to /projects/[projecttype]/ it displays the post content and title from the projecttype, and displays only the projects that have this projecttype (in an advanced custom field)
    – jnaklaas
    Commented May 6, 2019 at 6:16

1 Answer 1

0

Problem with rules occurs, because rule for a given projecttype is added when you visit relevant URL.

Every time you visit one of projects/{projectstype}/ addresses and flush rewrite rules, they are deleted and only one rule (only for current project type) is saved/created.

You can add your code to request filter hook, then there is no need to add rewrite rules. All query vars, that are set by rules (you set only page_id), you can set manually.

add_filter( 'request' , 'se336968_request' );
function se336968_request( $query_vars )
{
    if(substr( $_SERVER['REQUEST_URI'], 0, 11 ) === '/projects/'){
        $request_subpage = str_replace('/', '', str_replace('/projects/', '', $_SERVER['REQUEST_URI']));
        if($request_subpage !== '') {
            $project_types = get_posts( array( 'post_type' => 'projecttype', 'posts_per_page' => -1 ) );
            foreach( $project_types as $project_type ) {
                if( $project_type->post_name === $request_subpage ) {

                          // your current rewrite 
                    $query_vars['page_id'] = 8;
                    $query_vars['post_type'] = 'page';

                    //  --- to open "projecttype" type post from URL ---
                    // $query_vars['post_type'] = 'projecttype';
                    // $query_vars['projecttype'] = $request_subpage;
                    // unset( $query_vars['page_id'], $query_vars['p'], $query_vars['pagename'], $query_vars['name'] );

                    break;
                }
            }
        }
    }
    return $query_vars;
}

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.