Home › Forums › General Issues › Change permalink of CPT to be child of another CPT › Reply To: Change permalink of CPT to be child of another CPT
To change the permalink of a Custom Post Type (CPT) in WordPress to act as a child of another CPT, you’ll need to customize the rewrite rules and manage the hierarchy through hooks in your theme’s functions.php
file or a custom plugin. Here’s a step-by-step guide:
Example Setup
– **Parent CPT**: parent_cpt
– **Child CPT**: child_cpt
– Desired permalink structure: /parent_cpt/child_cpt/
1. Register Custom Post Types
First, make sure both your parent and child CPTs are registered. The key is to set up the rewrite
rule correctly for the child CPT.
Parent CPT Registration
`php
function register_parent_cpt() {
$labels = array(
‘name’ => ‘Parent CPT’,
‘singular_name’ => ‘Parent CPT’,
);
$args = array(
‘labels’ => $labels,
‘public’ => true,
‘rewrite’ => array( ‘slug’ => ‘parent_cpt’ ),
);
register_post_type( ‘parent_cpt’, $args );
}
add_action( ‘init’, ‘register_parent_cpt’ );
`
Child CPT Registration (with rewrite)
`php
function register_child_cpt() {
$labels = array(
‘name’ => ‘Child CPT’,
‘singular_name’ => ‘Child CPT’,
);
$args = array(
‘labels’ => $labels,
‘public’ => true,
‘rewrite’ => array( ‘slug’ => ‘parent_cpt/%parent_cpt%/child_cpt’, ‘with_front’ => false ),
‘has_archive’ => true,
);
register_post_type( ‘child_cpt’, $args );
}
add_action( ‘init’, ‘register_child_cpt’ );
`
2. Add Rewrite Logic to Handle Permalinks
We need to intercept and replace %parent_cpt%
with the actual parent_cpt
slug. Here’s how to do that.
Handle Permalink Replacement
`php
function child_cpt_permalink($permalink, $post) {
if ($post->post_type !== ‘child_cpt’) {
return $permalink;
}
// Get the parent CPT ID
$parent_id = get_post_meta($post->ID, ‘parent_cpt_id’, true);
if ($parent_id) {
$parent_post = get_post($parent_id);
$parent_slug = $parent_post->post_name;
return str_replace(‘%parent_cpt%’, $parent_slug, $permalink);
}
return $permalink;
}
add_filter(‘post_type_link’, ‘child_cpt_permalink’, 10, 2);
`
3. Add Rewrite Rules
This rule tells WordPress how to parse URLs in the desired format.
`php
function add_custom_rewrite_rules() {
add_rewrite_rule(
‘^parent_cpt/([^/]+)/child_cpt/([^/]+)/?$’,
‘index.php?child_cpt=$matches[2]’,
‘top’
);
}
add_action(‘init’, ‘add_custom_rewrite_rules’);
`
4. Save Parent CPT as Post Meta
You need a way to associate the child post with its parent. You can do this via a meta box in the admin area or using a custom relationship field.
Here’s an example of saving a parent_cpt_id
as a post meta field:
`php
function save_child_cpt_meta($post_id, $post, $update) {
if ($post->post_type != ‘child_cpt’) {
return;
}
if (isset($_POST[‘parent_cpt_id’])) {
update_post_meta($post_id, ‘parent_cpt_id’, $_POST[‘parent_cpt_id’]);
}
}
add_action(‘save_post’, ‘save_child_cpt_meta’, 10, 3);
`
5. Flush Rewrite Rules
Whenever you add new rewrite rules, you need to flush them. You can do this temporarily by visiting the **Settings > Permalinks** page, or by adding this line temporarily to your code:
`php
flush_rewrite_rules();
`
Final Notes
– The parent-child relationship is stored using post meta (parent_cpt_id
), but you can adjust this based on how you’re managing relationships.
– If you’re using a plugin like Advanced Custom Fields (ACF) for relationships, the code can be modified accordingly.
This setup allows the child CPT to inherit the parent CPT’s slug in the URL structure.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.