Combine multiple CPT names to create valid permalinks

I have three different Custom Post Types:

  1. Company
  2. Employee
  3. Project

They are connected with ACF relationship fields so as the Company can have multiple Employees and each Employee can have a project attached. The get_field() function retrieves attached post objects to create some sort of relationship.

What I need to do is create three permalink structures for these CPT:

  1. For Companies: www.somepage.com/%company_name%
  2. For Employees: www.somepage.com/%company_name%/%employee_name%
  3. For Projects: www.somepage.com/%company_name%/%employee_name%/%project_name%

What I have already managed to do is to set permalink structure to them with this piece of code:

function dd_custom_permalinks($permalink, $post, $leavename) {
    $post_id = $post->ID;
    if(($post->post_type != 'project' && $post->post_type != 'employee' && $post->post_type != 'company') || empty($permalink) || in_array($post->post_status, array('draft', 'pending', 'auto-draft')))
        return $permalink;

    if (get_field("employees", $post->ID)) {
        $permalink = str_replace('%company%', $post->post_name, $permalink);
    } elseif (get_field("company", $post->ID)) {
        $permalink = str_replace('%company%', get_field("company", $post->ID)[0]->post_name, $permalink);
        $permalink = str_replace('%employee%', $post->post_name, $permalink);
    } elseif (get_field("employee", $post->ID)) {
        $employee= get_field("employee", $post->ID)[0];
        $company= get_field("company", $employee->ID)[0];
        $permalink = str_replace('%company%', $company->post_name, $permalink);
        $permalink = str_replace('%employee%', $employee->post_name, $permalink);
        $permalink = str_replace('%project%', $post->post_name, $permalink);
    }

    return $permalink;
}
add_filter('post_type_link', 'dd_custom_permalinks', 10, 3);

The problem is I cannot find a way to make them valid, as the structure always leads to Company (first part of the custom url structure). Probably I have to bind the further with the CPT query somehow?

I have also tried using custom rewrite rules, but I can’t understand how should this be done to be fair. Here’s what I got so far (not working):

function dd_custom_rewrite_rules() {
    add_rewrite_tag('%company%', '([^/]+)', 'company=');
    add_permastruct('company', '/%company%', false);
    add_rewrite_rule('^company/([^/]+)/([^/]+)/?','index.php?company=$matches[2]','top');

    add_rewrite_tag('%employee%', '([^/]+)', 'employee=');
    add_permastruct('employee', '/%company%/%employee%', false);
    add_rewrite_rule('^employee/([^/]+)/([^/]+)/?','index.php?employee=$matches[2]','top');
    
    add_rewrite_tag('%project%', '([^/]+)', 'project=');
    add_permastruct('project', '/%company%/%employee%/%project%', false);
    add_rewrite_rule('^project/([^/]+)/([^/]+)/?','index.php?project=$matches[2]','top');

}
add_action( 'init', 'dd_custom_rewrite_rules' );

Any ideas how (or maybe IF) can I get this to work properly?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Sally CJ commented an important detail that helped me reach what I needed.

Apart from that I struggled with what seemed to be regex error – one of my rules was overriding another because there was no $ character in regex to end the string.

Working solution for custom rewrites:

function dd_custom_rewrite_rules() {
    add_rewrite_tag('%company%', '([a-z0-9-]+)', 'company=');
    add_rewrite_tag('%employee%', '([a-z0-9-]+)', 'employee=');
    add_rewrite_tag('%project%', '([a-z0-9-]+)', 'project=');

    add_permastruct('project', '/company/%company%/%employee%/%project%', false);
    add_permastruct('employee', '/company/%company%/%employee%', false);
    add_permastruct('company', '/company/%company%', false);

    add_rewrite_rule('^company[/]%company%[/]?','index.php?company=$matches[1]','top');
    add_rewrite_rule('^company[/]([a-z0-9-]+)[/]([a-z0-9-]+)[/]?$','index.php?employee=$matches[2]','top');
    add_rewrite_rule('^company[/]([a-z0-9-]+)[/]([a-z0-9-]+)[/]([a-z0-9-]+)[/]?$','index.php?project=$matches[3]','top');

}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x