The post type query var is the same as the post type slug by default. Untested, but this should work-
function custom_rewrite_basic() {
add_rewrite_rule(
'^books/([^/]+)/([0-9]+)/([^/]+)/?',
'index.php?books=$matches[1]&chapter=$matches[2]',
'top'
);
}
add_action('init', 'custom_rewrite_basic');
$matches[3]
will contain the chapter slug, but if you don’t need that to retrieve the chapter, then you don’t have to set it.
Rewrite rules need to be flushed after they’re added / changed. Visiting the Settings > Permalinks page will flush them without having to call flush_rewrite_rules
yourself.
Rewrite rules only handle incoming requests, it’s up to you to generate the correct URLs for each chapter, but that should just be a matter of grabbing your chapter data and appending the numbers/titles to the post permalink. Something like this:
$rows = get_field('chapter');
foreach( $rows as $index => $row ){
echo get_permalink() . "https://wordpress.stackexchange.com/" . ( $index + 1 ) . "https://wordpress.stackexchange.com/" . sanitize_title( $row['title'] ) . "https://wordpress.stackexchange.com/";
}
Also- to keep your templates tidy, you can filter single_template
, check if the chapter
query var is set, and load a different template for chapters vs the main book page.