I have created two custom post types in my wordpress project: city and property using the below query.
register_post_type('city',
array(
'labels' => array(
'name' => __('City', 'dc_qode'),
'singular_name' => __('City', 'dc_qode'),
),
'public' => true,
'show_in_menu' => true,
'rewrite' => array('slug' => 'city'),
'show_ui' => true,
'has_archive' => false,
'hierarchical' => true,
'show_tagcloud' => false,
'supports' => array(
'title',
'editor',
'thumbnail',
),
'can_export' => true,
'taxonomies' => array( 'city'),
)
);
register_post_type('property',
array(
'labels' => array(
'name' => __('Property', 'dc_qode'),
'singular_name' => __('Property', 'dc_qode'),
),
'public' => true,
'show_in_menu' => true,
'rewrite' => array('slug' => 'property'),
'show_ui' => true,
'has_archive' => false,
'hierarchical' => true,
'show_tagcloud' => false,
'supports' => array(
'title',
'editor',
'thumbnail',
),
'can_export' => true,
'taxonomies' => array( 'property'),
)
);
Using this, I can access any property using the url http://domain-name.com/property/property-name
. But I want to access the url as http://domain-name.com/city-name/property-name
(for eg. http://domain-name.com/toronto/abcproperty
). The city-name will be assigned with each property. I tried to use the slug, 'city', within property as:
'rewrite' => array('slug' => '%city%')
in place of
'rewrite' => array('slug' => 'property')
But it's not working.
How can I achieve this scenario?
You can make your custom posts to have parents like page. So there are three main thing you have to do:
Make you custom post to support Page attributes.
You have to register new rewrite rule, which will then define a new permastruct which will be used in the third step.
After registering the new rewrite rule, you should apply this rule to your custom posts' permalinks.
Complete working code
add_action('init', function(){
$labels = array(
"name" => "City",
"singular_name" => "City",
"menu_name" => "City",
"all_items" => "All City",
"add_new" => "Add New",
"add_new_item" => "Add New City",
"edit" => "Edit",
"edit_item" => "Edit City",
"new_item" => "New City",
"view" => "View",
"view_item" => "View City",
"search_items" => "Search City",
"not_found" => "No City Found",
"not_found_in_trash" => "No City Found in Trash",
"parent" => "Parent City",
);
$args = array(
"labels" => $labels,
"description" => "",
"public" => true,
"show_ui" => true,
"has_archive" => true,
"show_in_menu" => true,
"exclude_from_search" => false,
"capability_type" => "post",
"map_meta_cap" => true,
"hierarchical" => true,
"rewrite" => array( "slug" => "city", "with_front" => true ),
"query_var" => true,
"supports" => array( "title", "revisions", "thumbnail" )
);
register_post_type( "city", $args );
$labels = array(
"name" => "Properties",
"singular_name" => "Property",
);
$args = array(
"labels" => $labels,
"description" => "",
"public" => true,
"show_ui" => true,
"has_archive" => true,
"show_in_menu" => true,
"exclude_from_search" => false,
"capability_type" => "post",
"map_meta_cap" => true,
"hierarchical" => false,
"rewrite" => array( "slug" => "city/%city_name%", "with_front" => true ),
"query_var" => true,
"supports" => array( "title", "revisions", "thumbnail" )
);
register_post_type( "properties", $args );
});
add_action('add_meta_boxes', function() {
add_meta_box('properties-parent', 'City', 'properties_attributes_meta_box', 'properties', 'side', 'default');
});
function properties_attributes_meta_box($post) {
$pages = wp_dropdown_pages(array('post_type' => 'city', 'selected' => $post->post_parent, 'name' => 'parent_id', 'show_option_none' => __('(no parent)'), 'sort_column'=> 'menu_order, post_title', 'echo' => 0));
if ( ! empty($pages) ) {
echo $pages;
} // end empty pages check
}
add_action( 'init', function() {
add_rewrite_rule( '^city/(.*)/([^/]+)/?$','index.php?properties=$matches[2]','top' );
});
add_filter( 'post_type_link', function( $link, $post ) {
if ( 'properties' == get_post_type( $post ) ) {
//Lets go to get the parent city name
if( $post->post_parent ) {
$parent = get_post( $post->post_parent );
if( !empty($parent->post_name) ) {
return str_replace( '%city_name%', $parent->post_name, $link );
}
} else {
//This seems to not work. It is intented to build pretty permalinks
//when properties has not parent, but it seems that it would need
//additional rewrite rules
//return str_replace( '/%city_name%', '', $link );
}
}
return $link;
}, 10, 2 );