this is my situation:
I have a Custom Post Type named struttura (like accommodation):
function custom_post_struttura() {
$labels = array(
'name' => _x( 'Strutture', 'post type general name' ),
'singular_name' => _x( 'Struttura', 'post type singular name' ),
'add_new' => _x( 'Aggiungi nuova', 'book' ),
'add_new_item' => __( 'Aggiungi nuova Struttura' ),
'edit_item' => __( 'Modifica Struttura' ),
'new_item' => __( 'Nuova Struttura' ),
'all_items' => __( 'Tutte le Strutture' ),
'view_item' => __( 'Vedi Struttura' ),
'search_items' => __( 'Cerca Struttura' ),
'not_found' => __( 'Nessuna Struttura trovata' ),
'not_found_in_trash' => __( 'Nessuna Struttura trovata nel cestino' ),
'parent_item_colon' => '',
'menu_name' => 'Strutture'
);
$args = array(
'labels' => $labels,
'description' => 'Inserisci una nuova struttura',
'public' => true,
'menu_position' => 5,
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ),
'has_archive' => true,
'hierarchical' => true,
'rewrite' => array('slug' => 'strutture/%regione%'),
'query_var' => true,
);
register_post_type( 'struttura', $args );
}
add_action( 'init', 'custom_post_struttura' );
and a Custom Taxonomy named regione:
function taxonomies_regione() {
$labels = array(
'name' => _x( 'Regioni', 'taxonomy general name' ),
'singular_name' => _x( 'Regione', 'taxonomy singular name' ),
'search_items' => __( 'Cerca Regione' ),
'all_items' => __( 'Tutte le Tipologie' ),
'parent_item' => __( 'Parent Regione' ),
'parent_item_colon' => __( 'Parent Regione:' ),
'edit_item' => __( 'Modifica Regione' ),
'update_item' => __( 'Aggiorna Regione' ),
'add_new_item' => __( 'Aggiungi nuova Regione' ),
'new_item_name' => __( 'Nuova Regione' ),
'menu_name' => __( 'Regione' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'public' => true,
'query_var' => true,
'rewrite' => array(
'slug' => 'strutture',
'hierarchical' => true
),
);
register_taxonomy( 'regione', 'struttura', $args );
}
add_action( 'init', 'taxonomies_regione', 0 );
Now I add into Taxonomy regione these hierarchical categories:
- Tuscany
- Florence
- Empoli
- Vinci
- Florence
where Tuscany is parent-category, Florence is sub-parent-category and Empoli / Vinci are a sub-sub-parent-category.
I wanted to obtain a permalink structure like these:
www.example.com/tuscany
www.example.com/tuscany/florence
www.example.com/tuscany/florence/vinci
www.example.com/tuscany/florence/vinci/postname
So I added these three function:
add_filter('rewrite_rules_array', 'mmp_rewrite_rules');
function mmp_rewrite_rules($rules) {
$newRules = array();
$newRules['strutture/(.+)/(.+)/(.+)/(.+)/?$'] = 'index.php?struttura=$matches[4]';
$newRules['strutture/(.+)/?$'] = 'index.php?regione=$matches[1]';
return array_merge($newRules, $rules);
}
function filter_post_type_link($link, $post) {
if ($post->post_type != 'struttura')
return $link;
if ($cats = get_the_terms($post->ID, 'regione')) {
$link = str_replace('%regione%', get_taxonomy_parents(array_pop($cats)->term_id, 'regione', false, "https://wordpress.stackexchange.com/", true), $link);
}
return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);
function get_taxonomy_parents($id, $taxonomy, $link = false, $nicename = false, $visited = array()) {
// removed $seperator="https://wordpress.stackexchange.com/" after $link, otherwise there was a double slash before the post name in the link
$chain = '';
$parent = &get_term($id, $taxonomy);
if (is_wp_error($parent)) {
return $parent;
}
if ($nicename)
$name = $parent -> slug;
else
$name = $parent -> name;
if ($parent -> parent && ($parent -> parent != $parent -> term_id) && !in_array($parent -> parent, $visited)) {
$visited[] = $parent -> parent;
$chain .= get_taxonomy_parents($parent -> parent, $taxonomy, $link, $nicename, $visited); //removed $seperator after $link
$chain .= "https://wordpress.stackexchange.com/"; //add a / after every category
}
if ($link) {
// nothing, can't get this working :(
} else
$chain .= $name; //don't need the . $separator anymore
return $chain;
}
Everything works but I obtain this kind of permalink:
www.example.com/strutture/tuscany
www.example.com/strutture/tuscany/florence
www.example.com/strutture/tuscany/florence/vinci
www.example.com/strutture/tuscany/florence/vinci/postname
where strutture is basename. I want to specify that the default post hello-world works.
Now comes the fun part.
I want to add another Custom Taxonomy named tipologia (type) to CPT struttura:
function taxonomies_tipologia() {
$labels = array(
'name' => _x( 'Tipologie', 'taxonomy general name' ),
'singular_name' => _x( 'Tipologia', 'taxonomy singular name' ),
'search_items' => __( 'Cerca Tipologia' ),
'all_items' => __( 'Tutte le Tipologie' ),
'parent_item' => __( 'Parent Tipologia' ),
'parent_item_colon' => __( 'Parent Tipologia:' ),
'edit_item' => __( 'Modifica Tipologia' ),
'update_item' => __( 'Aggiorna Tipologia' ),
'add_new_item' => __( 'Aggiungi nuova Tipologia' ),
'new_item_name' => __( 'Nuova Tipologia' ),
'menu_name' => __( 'Tipologia' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'public' => true,
'query_var' => true
);
register_taxonomy( 'tipologia', 'struttura', $args );
}
add_action( 'init', 'taxonomies_tipologia', 0 );
Tipologia has two categories:
- hotel
- villa
Now I want to obtain these kind of permalink:
www.example.com/tuscany
www.example.com/tuscany/florence
www.example.com/tuscany/florence/vinci
www.example.com/hotel/tuscany/florence/vinci
www.example.com/hotel
www.example.com/hotel/tuscany/florence/vinci/postname
So I have made some change to the functions:
In the Custom Post Type struttura I modify the rewrite rules
'rewrite' => array('slug' => 'strutture/%tipologia%/%regione%'),
I have changed the mmp_rewrite_rules
function
add_filter('rewrite_rules_array', 'mmp_rewrite_rules');
function mmp_rewrite_rules($rules) {
$newRules = array();
$newRules['strutture/(.+)/(.+)/(.+)/(.+)/?$'] = 'index.php?struttura=$matches[4]';
$newRules['strutture/(.+)/(.+)/?$'] = 'index.php?regione=$matches[2]';
$newRules['strutture/(.+)/?$'] = 'index.php?tipologia=$matches[1]';
return array_merge($newRules, $rules);
}
I have added this function
function filter_post_type_link_due($link, $post) {
if ($post->post_type != 'struttura')
return $link;
if ($cats = get_the_terms($post->ID, 'tipologia')) {
$link = str_replace('%tipologia%', get_taxonomy_parents(array_pop($cats)->term_id, 'tipologia', false, "https://wordpress.stackexchange.com/", true), $link);
}
return $link;
}
add_filter('post_type_link', 'filter_post_type_link_due', 10, 2);
With this configuration I obtain this kind of permalink structure:
www.example.com/regione/tuscany
www.example.com/regione/tuscany/florence
www.example.com/regione/tuscany/florence/vinci
www.example.com/strutture/hotel/tuscany/florence/vinci
error 404www.example.com/hotel/tuscany/florence/vinci
error 404www.example.com/tipologia/hotel
www.example.com/strutture/hotel/tuscany/florence/vinci/postname
where regione is the name of Custom Taxonomy, tipologia is the name of Custom Taxonomy and strutture is a basename. The default post name hello-world works.
If I change something into rewrite rule like slugs I obtain 404.
My questions are:
is it possible to obtain this kind of permalink structure?
www.example.com/tuscany
www.example.com/tuscany/florence
www.example.com/tuscany/florence/vinci
www.example.com/hotel/tuscany/florence/vinci
www.example.com/hotel
www.example.com/hotel/tuscany/florence/vinci/postname
How can I remove the basename from CPT, CT and permalinks?
Is this the right way to obtain this structure?
I saw this permalink strategy here:
http://www.agriturismo.net/tuscany/
http://www.agriturismo.net/tuscany/florence/
http://www.agriturismo.net/tuscany/florence/vinci/
http://www.agriturismo.net/villa/tuscany/florence/vinci/
http://www.agriturismo.net/villa
Thank you in advance.
PS: I go into permalink page to flush rewrite every time. I’m trying this strategy from five weeks.