web-dev-qa-db-ja.com

最後のURIセグメントがカスタム投稿タイプか分類用語かどうかを確認する方法

このスレッド でJeffsの提案に従って、ネストした親と子の分類用語を以下のようなパーマリンク内に作成してください。

url.com/custom-post-type/taxonomy-parent/taxonomy-child/cpt-entry

それは1つの問題を除いて大抵うまくいきます。

先に進む前に、galleryというカスタム投稿タイプとgallery_catという分類法があることに注意してください。


ワーキング

/gallery/ - archive-gallery.php
/gallery/wedding-cakes/ - parent taxonomy - taxonomy-gallery_cat.php     
/gallery/wedding-cakes/chocolate/ - child taxonomy - taxonomy-gallery_cat.php      
/gallery/wedding-cakes/chocolate/cpt-entry/ - CPT entry under child taxonomy - single-gallery.php

働いていない

/gallery/wedding-cakes/cpt-entry/ - CPT entry under parent taxonomy


これがfunctions.phpの私のコードです。

// ADD A GALLERY CUSTOM POST TYPE WITH GALLERY_CAT TAXONOMY
add_action('init', 'create_gallery_post_type');

function create_gallery_post_type() {

register_taxonomy(
    'gallery_cat',
    'gallery',
     array(
        'label' => 'Categories',
        'singular_label' => 'Category',
        'hierarchical' => true,
        'query_var' => true,
        'rewrite' => array('slug' => 'gallery', 'hierarchical' => true ),
    )
);

$labels = array(
    'name' => _x('Gallery', 'post type general name'),
    'singular_name' => _x('Photo', 'post type singular name'),
'add_new' => _x('Add New', 'gallery'),
);

$args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true,
    'query_var' => true,
    'capability_type' => 'post',
    'hierarchical' => false,
    'menu_position' => null,
    'supports' => array('title','editor','thumbnail', 'excerpt', 'author', 'comments'),
    'rewrite' => array(
        'slug' => 'gallery/%gallery_cat%',
        'with_front' => false
    ),
    'has_archive' => 'gallery',
    'menu_icon' => get_bloginfo('template_directory') . '/images/gallery-icon.png' //16x16 png if you want an icon
); 

register_post_type( 'gallery' , $args );
}



function filter_post_type_link($link, $post) {
if ($post->post_type != 'gallery')
    return $link;
if ($cats = get_the_terms($post->ID, 'gallery_cat')) {
    $link = str_replace('%gallery_cat%', rtrim(get_taxonomy_parents(array_pop($cats)->term_id, 'gallery_cat', false, '/', true),"/"), $link); // see custom function defined below
}
return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);


// my own function to do what get_category_parents does for other taxonomies
function get_taxonomy_parents($id, $taxonomy, $link = false, $separator = '/', $nicename = false, $visited = array()) {    
$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, $separator, $nicename, $visited);
}
if ($link) {
    // nothing, can't get this working :(
} else    
    $chain .= $name . $separator;
return $chain;    
}


//Rewrite rules
add_filter('rewrite_rules_array', 'gallery_rewrite_rules');
function gallery_rewrite_rules($rules) {
$newRules  = array();

$newRules['gallery/(.+)/(.+)/(.+)/?$'] = 'index.php?gallery=$matches[3]';   
$newRules['gallery/(.+)/(.+)/?$'] = 'index.php?gallery_cat=$matches[2]'; 
$newRules['gallery/(.+)/?$']      = 'index.php?gallery_cat=$matches[1]';

return array_merge($newRules, $rules);
}

さて、問題は、書き換えルールの配列に次の行を追加する必要があるところにあると思います。

$newRules['gallery/(.+)/(.+)/?$'] = 'index.php?gallery=$matches[2]';

cPTが親の分類法の下にある場合にのみ、2番目のURIセグメントになるので、私のカスタム構造では常に3番目のURIセグメントに投稿名があるとは限らないためです。

しかし、それを付け加えると、それは物事を壊します。私の一番の推測は、それがこの行と衝突しているということです...

$newRules['gallery/(.+)/(.+)/?$'] = 'index.php?gallery_cat=$matches[2]';

私がこれを this thread から遠ざけるのを手伝ってくれたJeffは、次のように述べています...

入れ子になった用語のレベルが異なる場合は、最後のURIセグメントがカスタム投稿タイプか、追加するルールを知るための分類用語かを確認する関数を作成する必要があります。

これを達成する方法を誰かが知っていますか?

ありがとう

1
serks

これをどのように行うことができるかを見るためには、 Query Overview Codexページ 、特にを読んでください。 セクション:

変数の値を保存した後で、クエリの指定を変更します(request filterまたはparse_requestアクション。条件付きタグテストを使用する場合は、parse_query変数が設定された後に実行されるpre_get_postsまたはis_アクションを使用します)。

この場合、requestクラスの parse_requestメソッドによって設定されたクエリ変数の配列になるWPをフィルタリングします (scrollフィルタが適用される場所を確認するには、この関数の最後まで進みます。

このフィルタでは、gallery_catが設定されているかどうか、および要求された用語が実際に既存のgallery_cat用語であるかどうかを確認します。そうでない場合は、それをgallery投稿と見なし、クエリvarsをリセットして、単語ではなく投稿に対するWordPressクエリを作成します。そのためには、3つの異なるクエリ変数galleryname、およびpost_typeを設定する必要があります。

function wpd_gallery_request_filter( $request ){
    if( array_key_exists( 'gallery_cat' , $request )
        && ! get_term_by( 'slug', $request['gallery_cat'], 'gallery_cat' ) ){
            $request['gallery'] = $request['gallery_cat'];
            $request['name'] = $request['gallery_cat'];
            $request['post_type'] = 'gallery';
            unset( $request['gallery_cat'] );
    }
    return $request;
}
add_filter( 'request', 'wpd_gallery_request_filter' );
4
Milo