3

My problem is one that i can't seem to find a solution to.

I have 2 Custom Post Types, Mangas and Chapters, every chapter published will always be connected to a manga via the ACF relationship field.

The current permalink structure for the chapter is site.com/chapters/chapter-title and what i want is site.com/mangas/connected-manga/chapter-title

Since wordpress doesn't offer much in the way of post-to-post relationships the ACF relationship field is great for this and i have everything figured out except for this... the permalink.

Any help would be appreciated. Please bear in mind that i don't want to use an extra plugin for this.

3
  • Just curious if you ever found a solution for this? I'm in a similar situation. Thanks!
    – dkeeling
    Aug 9, 2018 at 14:38
  • Any particular reason why manga and chapter need to be custom post types rather than custom taxonomies or parest-post/child-post?
    – Slam
    Nov 30, 2018 at 15:48
  • Some mangas have dozens and dozens of chapters, parent-child relationships is to display a manga (post) with all the info of it and below it display a full list of the chapters in correct order and also to be able to travel between chapters back and forward in the correct order as well, taxonomies are just to categorize which is not what i was going for.
    – ACast59
    Dec 2, 2018 at 8:36

2 Answers 2

1
+100

The following you could add as a plugin or into your themes functions.php file. What we need to do is add a rewrite tag, custom query var, and finally replace the rewrite tag with the related post slug. Some things may vary from my code to yours. I assume chapters is the post type slug and that the relational field is returning an ID instead of an object, you may need to change these things based on your setup.

One thing you'll need to do is when you're creating your chapters post type, you'll need to add in the placeholder on the rewrite slug:

/**
 * Create Rewrite Tag
 * We'll be able to hook in and replace this placeholder
 * 
 * @return void
 */
function wpse285382_chapters_setup() {

    // Add rewrite tag
    add_rewrite_tag(
        '%manga%',  // Placeholder
        '([^&]+)',  // Regex
        'manga='    // Expected query var
    );

    // Assign rewrite tag in post registation
    register_post_type( 'chapters', array(
        /* ... */
        'rewrite' => array( 'slug' => 'mangas/%manga%', 'with_front' => false ),
        /* ... */
    ) );

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


/**
 * Replace the placeholder rewrite tag with expected manga
 * 
 * @param String $post_link
 * @param WP_Post $post
 * 
 * @return String $post_link
 */
function wpse285382_chapter_link_replacements( $post_link, $post ) {

    // No Post ID? Drop out
    if( empty( $post ) ) {
        return $post_link;
    }

    // Make sure our post type is correct
    if( empty( $post ) || 'chapters' !== $post->post_type ) {
        return $post_link;
    }

    // Get related manga field
    $manga = get_field( 'related_manga', $post->ID );

    if( ! empty( $manga ) ) {

        // Grab Post Slug
        $manga_slug = get_post_field( 'post_name', $manga );

        // Replace rewrite tag in the given URL
        $post_link = str_replace( '%manga%', $manga_slug, $post_link );

    }

    return $post_link;

}
add_filter( 'post_type_link', 'wpse285382_chapter_link_replacements', 9, 2 );

This last bit should redirect any mismatched posts. We make sure that we have a slug to work with, we have a related post ID assigned, and the given slug and related post slug are the same, if they're not we redirect them back to the archive page ( or where-ever you need to point them to ).

/**
 * Redirect mismatched related posts
 * 
 * @return void
 */
function wpse285382_chapter_redirects() {

    global $post, $wp_query;

    if( ! is_singular( 'chapterss' ) ) {
        return;
    }

    $redirect_to    = get_post_type_archive_link( 'chapters' );
    $given_slug     = $wp_query->get( 'manga' );
    $expected_manga = get_field( 'related_manga', $post->ID );

    if( empty( $given_slug ) || empty( $expected_manga ) ) {
        wp_redirect( $redirect_to );
        exit();
    }

    $expected_slug = get_post_field( 'post_name', $expected_manga );

    if( $given_slug !== $expected_slug ) {
        wp_redirect( $redirect_to );
        exit();
    }

}
add_action( 'template_redirect', 'wpse285382_chapter_redirects' );
2
  • 1
    add_rewrite_tag adds the query var for you, you don't need the query_vars filter.
    – Milo
    Nov 28, 2018 at 5:05
  • Really cool what you have built here but sadly i'm no longer part of the project :(
    – ACast59
    Dec 2, 2018 at 8:37
0

I think you need to use plugin Custom Post Type Permalinks to do it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.