web-dev-qa-db-ja.com

複数の投稿タイプ - 同じReWriteスラッグを共有しますか?

私は別の素晴らしい404号に出くわした。私は同じ書き換えナメクジを共有する2つの別々の投稿タイプを持つことを試みています。私は私の書き換え規則を洗い流しました、そして私が1つのCPT作品だけをテストするとき - 他は404を得ます。両方に使用したい私の書き換えは次のとおりです。

'rewrite' => array('slug' => 'team/%teamtype%'),

誰もがこれを処理する方法を知っていますか?

add_action( 'init', 'create_rider_type' );

function create_rider_type() {

register_post_type('riders', 
array(  
    'description' => 'rider custom post type',
    'show_ui' => true,
    'menu_position' => 5,
    'menu_icon' => get_stylesheet_directory_uri() . '/images/riders.png',
    'exclude_from_search' => false,
    'labels' => array(
        'name' => 'Team Riders',
        'singular_name' => 'Rider',
        'add_new' => 'Add New rider',
        'add_new_item' => 'Add New rider',
        'edit' => 'Edit riders',
        'edit_item' => 'Edit rider',
        'new_item' => 'New rider',
        'view' => 'View rider',
        'view_item' => 'View rider',
        'search_items' => 'Search riders',
        'not_found' => 'No riders found',
        'not_found_in_trash' => 'No riders found in Trash',
        'parent' => 'Parent rider',
    ),
    'hierarchical' => false,
    'supports' => array('title','editor','excerpt', 'trackbacks','custom-fields', 'comments','revisions','thumbnail','author','page-attributes'),
    'public' => true,
    'rewrite' => array('slug' => 'team/%teamtype%'),
    'taxonomies' => array('teamtype')
    ) 
);


}





add_action( 'init', 'create_sponsor_type' );

function create_sponsor_type() {

register_post_type('sponsors', 
array(  
    'description' => 'sponsor custom post type',
    'show_ui' => true,
    'menu_position' => 5,
    'menu_icon' => get_stylesheet_directory_uri() . '/images/sponsors.png',
    'exclude_from_search' => false,
    'labels' => array(
        'name' => 'Team sponsors',
        'singular_name' => 'sponsor',
        'add_new' => 'Add New sponsor',
        'add_new_item' => 'Add New sponsor',
        'edit' => 'Edit sponsors',
        'edit_item' => 'Edit sponsor',
        'new_item' => 'New sponsor',
        'view' => 'View sponsor',
        'view_item' => 'View sponsor',
        'search_items' => 'Search sponsors',
        'not_found' => 'No sponsors found',
        'not_found_in_trash' => 'No sponsors found in Trash',
        'parent' => 'Parent sponsor',
    ),
    'hierarchical' => false,
    'supports' => array('title','editor','excerpt', 'trackbacks','custom-fields', 'comments','revisions','thumbnail','author','page-attributes'),
    'public' => true,
    'rewrite' => array('slug' => 'team/%teamtype%'),
    'taxonomies' => array('teamtype')
    ) 
);

}

************* 更新***********************************

私が投稿したオリジナルのCPT書き換えコードは単純化されていますので、もっと簡単に説明することができます。ただし、私のカスタム分類法でこれらのパーマリンクをどのように処理しているかを理解できればもっと理にかなっています。表示するコードを更新しました。

私は本当にそれらを別々の投稿タイプとして整理したい - 組織のためだけでなくそれぞれのために別々のメタボックスとして。以下の私の分類法の設定と同様にCPTのために更新された書き換えをチェックしてください:

add_action( 'init', 'create_team_taxonomies' );

function create_team_taxonomies() {
register_taxonomy( 
'teamtype', 
array('riders','sponsors'),
array( 
    'labels' => array(
        'name' => 'Team Types',
        'singular_name' => 'Team Type',
        'search_items' =>  'Search Team Types',
        'popular_items' => 'Popular Team Types',
        'all_items' => 'All Team Types',
        'parent_item' => 'Parent Team Type',
        'parent_item_colon' => 'Parent Team Type:',
        'edit_item' => 'Edit Team Type', 
        'update_item' => 'Update Team Type',
        'add_new_item' => 'Add New Team Type',
        'new_item_name' => 'New Team Type Name'
    ), 
'hierarchical' => true, 
'public' => true,
'show_ui' => true,
'query_var' => 'teamtype',
'show_tagcloud' => true,
'rewrite' => array( 'slug' => 'team', 'with_front' => false) 
) 
);

}

そして、分類法を選択して投稿を公開するときに書き換えを設定する方法は次のとおりです。

add_filter('post_link', 'teamtypepermalink', 10, 3);
add_filter('post_type_link', 'teamtypepermalink', 10, 3);

function teamtypepermalink($permalink, $post_id, $leavename) {
if (strpos($permalink, '%teamtype%') === FALSE) return $permalink;

    // Get post
    $post = get_post($post_id);
    if (!$post) return $permalink;

    // Get taxonomy terms
    $terms = wp_get_object_terms($post->ID, 'teamtype');    
    if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) $taxonomy_slug = $terms[0]->slug;
    else $taxonomy_slug = 'not-specified';

return str_replace('%teamtype%', $taxonomy_slug, $permalink);
}
4
Joe

私は2つのカスタム投稿タイプが同じスラッグを共有する必要があるというプロジェクトをやったばかりです。 トリックはrequestフィルタを介してクエリ変数を上書きすることです 。投稿タイプを 'foo'と 'bar'と呼びましょう。それらはスラッグ 'foo'を共有します。

次のコードは、おおまかな例であり、メモリからのものです。味に塩、コピー&ペーストしないでください:

add_filter('request', 'overwriteQueryVars', 10, 1);

function overwriteQueryVars($query)
{
    if ( empty($query['post_type']) || $query['post_type']!='foo' ) {
        return $query;
    }

    // Run an SQL query that looks like this, against both post types
    $sql = "SELECT ID FROM wp_posts WHERE post_type='foo' and post_name='%s'";
    $post_name = urlencode($query['name']);

    // If you've found that the row exists for post_type 'bar' but not 'foo',
    // then simply return the $query array unaltered
    if ( in_foo_but_not_bar ) {
        return $query;
    }

    // If you've found that the row exists for post_type 'bar' but not 'foo',
    // then rewrite the $query array:

    // Original:
    $query = array (
        'page' => '',
        'foo' => 'some-Nice-post',
        'post_type' => 'foo',
        'name' => 'some-Nice-post',
    );

    // Make it look like this:
    $query = array (
        'page' => '',
        'bar' => 'some-Nice-post',
        'post_type' => 'bar',
        'name' => 'some-Nice-post',
    );

}
1
dotancohen

私の知る限りでは、それはできません。すべてのスラッグは、特定のオブジェクトタイプ(分類法または投稿タイプ)を照会するquery_vars項目に変換されます。 WP_Queryを分析すると、それが最初の投稿タイプを照会していることがわかります。

たぶんここでWP忍者はこれで私たちを啓発することができますが、私はあなたがそれをすることができないことをほぼ確実に確かめます。あるいは、少なくとも、そうすべきではありません。

1
MZAweb

CPT(そしてそれに関しては投稿/ページ)が構築されるので、それは不可能です。スラッグは特定のタイプのために予約されており、2 CPT = 2つの異なるタイプのコンテンツであることが理解されています。

あなたのコードに基づいて、あなたがCPTに持っているアイテムのそれぞれがカスタムCPTとしてよりよく役立たれるように思えます(両方とも単一のCPTに結び付けられています)

1
Norcross

この質問は非常に古いものですが、私が同様の問題の解決策を探していたとき、この質問は私が達成しようとしていたものに最も近いものになりました。利用可能なより良い解決策。それで、私が後で考え出した解決策を追加するつもりです。

私は同様の問題を抱えていました。スラッグを別の投稿タイプと共有する新しいカスタム投稿タイプを作成したいと思いました。私の場合はcountry-infoという投稿タイプがあり、標準のpage投稿タイプと同じパーマリンク構造を使いたいと思いました。

言い換えれば、私はexample.com/page-name/の代わりにexample.com/country-info/page-nameを使ってアクセスできるようにしたかったのです。

これが私がそれを解決した方法です:

// I found it easiest to grab the request in the parse_request hook. There you can see
// the requested slug, as well as if the requested page existed or not.

add_action('parse_request', 'overwriteRequest', 10, 1);
function overwriteRequest($query) {

    // If the request matched an existing page, the query_vars array will contain the
    // post_type, but otherwise it will only contain an error.
    // So we only execute our code if the post_type is empty
    // On the top page, the query_vars is an empty array, so we check for that too!
    if ( count($query->query_vars) > 0 && empty($query->query_vars['post_type'])) {

        // The request contains the string that was requested.
        $pageName = $query->request;
        $postType = 'country-info';

        // Check if post with the requested slug exists in your custom post type
        $result = get_posts(array(
            'post_type' => $postType,
            'name' => $pageName
        ));

        // If it doesn't, just return the query
        if (count($result) < 1) {

            return $query;

        // If it does, create a new query_vars array to replace the old one.
        } else {
            $new_query = array(
                'page' => '',
                'country-info' => $pageName,
                'post_type' => $postType,
                'name' => $pageName
            );
            $query->query_vars = $new_query;
            return $query;
        }

    } else {
        return $query;
    }
}

ご注意ください:

私の場合は、example.com/page-nameのようにドメインのルートレベルにあるすべての場所を探していましたが、カスタム投稿タイプがexample.com/some-directory/post-name/のようなディレクトリ内にある場合は、コードで1つ変更する必要があります。

$pageName = $query->request;

する必要があります

$pageName = preg_replace('/my-directory-name\//', '', $query->request)

そうでなければ、get_postsはスラッグがあなたのディレクトリを含む投稿を見つけようとしますが、それは常にあなたにゼロの結果を与えるでしょう。このpreg_replaceは単にあなたのディレクトリ名を文字列から削除します。

my-directory-nameを実際のディレクトリ名に置き換えてください。

この解決方法はテスト済みでWordPress 4.9.7で動作します

0
Azer

あなたの書き換えルールはお互いを上書きするでしょう、そしてWordPressはポストタイプの1つのみを問い合わせます。私はそれが「勝つ」ことが登録されている最新のものだと思うので、/testslug/bmw/は常にslug bmwと投稿タイプsponsorsで投稿を問い合わせます。あなたが/testslug/some-name/に行き、some-nameがライダーである場合、それはまだ投稿タイプsponsorsおよびpost slug some-nameを問い合わせます。これはWordPressがテンプレートページをロードする前に、あなたに代わって実行する "default"クエリで発生するので、例えばsingle-sponsors.phpテンプレートファイルでこれを解決することはできません。あなたは404.phpに入れることができました、しかしそれからそれは醜くなります)。

最も明確な解決策は、このURL解析を行うロジックの一部を置き換えて、「あいまいな」URLを受け入れるようにすることです。それがライダーかスポンサーかをテストし、WordPressがライダーかスポンサーのどちらかで続行するようにパラメータを変更します。 Mike かつてこれを行う方法を提供しました ページや分類法を使用して、投稿のみを処理するようにこれを拡張することが可能になるはずです。

0
Jan Fabry