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.

  • Just curious if you ever found a solution for this? I'm in a similar situation. Thanks! – dkeeling Aug 9 '18 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 '18 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 '18 at 8:36
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' );
  • 1
    add_rewrite_tag adds the query var for you, you don't need the query_vars filter. – Milo Nov 28 '18 at 5:05
  • Really cool what you have built here but sadly i'm no longer part of the project :( – ACast59 Dec 2 '18 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, privacy policy and cookie policy

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