I have a custom post type called Communities, a custom post type called Community Posts, and a taxonomy under Community Posts called Communities.

The idea here is that whenever a new Community is added, a taxonomy term is generated matching that name (if it doesn't exist already). So the user can now write blog posts under the Community Posts post type and categorize it under the taxonomy term for that city.

Here is how the client needs the permalink structure:

Cities post type:

example.com/community/{community-name}

A single City Post categorized under the matching city name taxonomy:

example.com/community/{community-name}/{article-about-community}

Right now I have the following code in place:

add_action( 'init', 'register_post_type_city' );
function register_post_type_city() {

    $menu_name = 'Communities';
    $regular_name = 'Communities';
    $singular_name = 'Community';
    $register_name = 'city';
    $icon = 'dashicons-location-alt';

    $labels = array(
        'name'               => _x( $regular_name, 'post type general name', 'textdomain' ),
        'singular_name'      => _x( $singular_name, 'post type singular name', 'textdomain' ),
        'menu_name'          => _x( $menu_name, 'admin menu', 'textdomain' ),
        'name_admin_bar'     => _x( $singular_name, 'add new on admin bar', 'textdomain' ),
        'add_new'            => _x( 'Add New', $register_name, 'textdomain' ),
        'add_new_item'       => __( 'Add New ' . $singular_name, 'textdomain' ),
        'new_item'           => __( 'New ' . $singular_name, 'textdomain' ),
        'edit_item'          => __( 'Edit ' . $singular_name, 'textdomain' ),
        'view_item'          => __( 'View ' . $singular_name, 'textdomain' ),
        'all_items'          => __( 'All ' . $regular_name, 'textdomain' ),
        'search_items'       => __( 'Search ' . $regular_name, 'textdomain' ),
        'parent_item_colon'  => __( 'Parent ' . $regular_name . ':', 'textdomain' ),
        'not_found'          => __( 'No ' . $regular_name . ' found.', 'textdomain' ),
        'not_found_in_trash' => __( 'No ' . $regular_name . ' found in Trash.', 'textdomain' )
    );

    $args = array(
        'labels'             => $labels,
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite' => array( 
            'slug' => 'community',
            'with_front' => false
        ),
        'capability_type'    => 'post',
        'has_archive'        => 'community',
        'hierarchical'       => true,
        'menu_position'      => null,
        'menu_icon'          => $icon,
        'supports'           => array( 'title', 'editor', 'page-attributes', 'thumbnail'  )
    );
    register_post_type( $register_name, $args );
}

add_action( 'init', 'register_city_post_taxonomy', 0 );
function register_city_post_taxonomy() {
    register_taxonomy(
        'communities', 
        'city_post', 
        array(
            'labels' => array(
                'name'          => 'Communities',   
                'singular_name' => 'Community News',    
                'search_items'  => 'Search Communities',    
                'edit_item'     => 'Edit Community',    
                'add_new_item'  => 'Add New Community'
            ),  
            'hierarchical' => true,
            'show_ui' => true,
            'show_admin_column' => true,
            'query_var' => true,    
            'rewrite' => array(
                'slug' => 'community/communities', 
                'with_front' => false
            )
        )
    ); 
}
add_action( 'init', 'register_post_type_city_post' );
function register_post_type_city_post() {

    $menu_name = 'Community Posts';
    $regular_name = 'Community Posts';
    $singular_name = 'Community Post';
    $register_name = 'city_post';
    $icon = 'dashicons-format-status';

    $labels = array(
        'name'               => _x( $regular_name, 'post type general name', 'textdomain' ),
        'singular_name'      => _x( $singular_name, 'post type singular name', 'textdomain' ),
        'menu_name'          => _x( $menu_name, 'admin menu', 'textdomain' ),
        'name_admin_bar'     => _x( $singular_name, 'add new on admin bar', 'textdomain' ),
        'add_new'            => _x( 'Add New', $register_name, 'textdomain' ),
        'add_new_item'       => __( 'Add New ' . $singular_name, 'textdomain' ),
        'new_item'           => __( 'New ' . $singular_name, 'textdomain' ),
        'edit_item'          => __( 'Edit ' . $singular_name, 'textdomain' ),
        'view_item'          => __( 'View ' . $singular_name, 'textdomain' ),
        'all_items'          => __( 'All ' . $regular_name, 'textdomain' ),
        'search_items'       => __( 'Search ' . $regular_name, 'textdomain' ),
        'parent_item_colon'  => __( 'Parent ' . $regular_name . ':', 'textdomain' ),
        'not_found'          => __( 'No ' . $regular_name . ' found.', 'textdomain' ),
        'not_found_in_trash' => __( 'No ' . $regular_name . ' found in Trash.', 'textdomain' )
    );

    $args = array(
        'labels'             => $labels,
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite' => array( 
            'slug' => 'community/%communities%',
            'with_front' => false
        ),
        'capability_type'    => 'post',
        'has_archive'        => false,
        'hierarchical'       => true,
        'menu_position'      => null,
        'menu_icon'          => $icon,
        'supports'           => array( 'title', 'editor', 'page-attributes', 'thumbnail'  )
    );
    register_post_type( $register_name, $args );
}

add_filter('post_link', 'community_posts_type_permalink', 1, 3);
add_filter('post_type_link', 'community_posts_type_permalink', 1, 3);

function community_posts_type_permalink( $permalink, $post_id, $leavename ) {

    $post = get_post( $post_id );

    if ( strpos( $permalink, '%communities%' ) === FALSE || 'city_post' != get_post_type( $post ) ) {
        return $permalink; 
    }

    if ( ! $post ) {
        return $permalink;
    }

    $terms = wp_get_object_terms( $post->ID, 'communities' );

    if ( ! is_wp_error( $terms ) && ! empty( $terms ) && is_object( $terms[0] ) ) {
        $taxonomy_slug = $terms[0]->slug;
    } else {
        $taxonomy_slug = 'no-community';
    }

    return str_replace( '%communities%', $taxonomy_slug, $permalink );
}

Everything is working great except that I am getting 404 errors on the single Community Post pages. Any advice would be greatly appreciated!

  • Have you refreshed the permalinks? See this explanation. – Linnea Huxford Jan 5 '16 at 0:40
  • Yes @Linnea I have – Max Lutz Jan 5 '16 at 0:58
  • Well, I'm afraid, it won't work like this, because the way WP processes RewritrRules. It scans them in order and matches first one. So if cities is hierarchical, then any URL like community/x/y/z is matched as city structure. Why are you using 2 CPTs for this? Why not only one CPT and one taxonomy? – Krzysiek Dróżdż Sep 19 '16 at 5:00

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.