URLに複数の分類法を追加するにはどうすればよいですか?


8

URLの複数の分類

次のようなURLに複数の分類法を追加するにはどうすればよいですか。

  • 投稿タイプ:製品
  • 分類:product_type
  • 分類:product_brand


新しい製品を追加し、この製品のタイプとブランドを選択します。

新しい商品を追加する場合、2つの分類ボックス(product_typeとproduct_brand)があります。この新しいポストをTest Product 1と呼びましょう。私たちが最初にしたいことは、私が扱っている製品の種類、たとえば携帯電話をチェックすることです。次に、製品がどのブランドに属しているかを確認したいと思います。たとえば、サムスンです。

現在、「Test Product 1」はタイプ「携帯電話」とブランド「samsung」に関連付けられています。

望ましい最終結果は次のとおりです。

/ products
»すべてのカスタム投稿を表示

/ products / cell-phones
»分類学の携帯電話に関するすべてのカスタム投稿を表示

/ product / cell-phones / samsung /
»分類が携帯電話 samsung であるすべてのカスタム投稿を表示

/ products / cell-phones / samsung / test-product-1
»製品を表示(単一のカスタム投稿)


質問

これをどのようにして可能にするのでしょうか?私の最初の考えは、「samsung」の親用語として「携帯電話」を使用して、1つの分類法を使用することでした。実際に分類法とその用語を追加することはそれほど難しくありませんでした。しかし、それは他の多くの問題につながりました。よく知られている問題もあれば、それほど多くない問題もあります。とにかく、404の問題が発生し、WPが特定のことを許可しないため、そのようには機能しません。 WP.org»taxonomy-archive-template

これにより、構造を再考し、分類法とその用語を残さなければならなくなったので、私は考えました。2番目の分類法を作成し、投稿タイプを関連付けてURLに追加しないのはなぜですか?

確かに良い質問ですが、どうやって?


私は同じことをして問題を持って、このリンクをチェックすることができますstackoverflow.com/questions/34351477/...
サンジャイNakate

回答:


7

これは確かに、ある程度の独自の書き換えルールを利用することで可能です。WP_Rewriteクエリにリクエストを変換するために書き換え規則(または「マップ」)を追加することができ、APIが公開する機能。

優れた書き換えルールを作成するには前提条件があり、最も重要なものは基本的な正規表現の理解です。WordPress Rewriteエンジンは正規表現を使用して、URLの一部をクエリに変換し、投稿を取得します。

これは、PHP PCRE(Perl互換の正規表現)に関する短くて良いチュートリアルです。

したがって、2つの分類法を追加しました。それらの名前が次のとおりであるとします。

  • 製品型
  • product_brand

これらを次のようなクエリで使用できます。

get_posts( array(
    'product_type' => 'cell-phones',
    'product_brand' => 'samsung'
) );

クエリはになります?product_type=cell-phones&product_brand=samsung。これをクエリとして入力すると、Samsungの電話のリストが表示されます。/cell-phones/samsungそのクエリに書き換えるには、書き換えルールを追加する必要があります。

add_rewrite_rule()あなたのためにこれを行います。上記の場合の書き換えルールの例を次に示します。

add_rewrite_rule( '^products/([^/]*)/([^/]*)/?',
    'index.php?product_type=$matches[1]&product_brand=$matches[2]',
    'top' );

flush_rewrite_rules()データベースに保存するための書き換えルールを追加したら、すぐにそれを行う必要があります。これは一度だけ実行されます。一度ルールがフラッシュされると、すべてのリクエストでこれを実行する必要はありません。削除するには、追加された書き換えルールなしでフラッシュするだけです。

ページネーションを追加したい場合は、次のようなことを行うことができます。

add_rewrite_rule( '^products/([^/]*)/([^/]*)/(\d*)?',
    'index.php?product_type=$matches[1]&product_brand=$matches[2]&p=$matches[3]',
    'top' );

1
ワードプレスの書き換えルールに関して私が見た最も単純な記事。たくさん読んでいますが、これを読んだ後、ようやくうまくいきました。ありがとう!+1
2018年

3

最終結果

これは私が得たすべての答えからビットと部分を部分的に使用して思いついたものです:

/**
 * Changes the permalink setting <:> post_type_link
 * Functions by looking for %product-type% and %product-brands% in the URL
 * 
  * products_type_link(): returns the converted url after inserting tags
  *
  * products_add_rewrite_rules(): creates the post type, taxonomies and applies the rewrites rules to the url
 *
 *
 * Setting:         [ produkter / %product-type%  / %product-brand% / %postname% ]
 * Is actually:     [ post-type / taxonomy        /  taxonomy       / postname   ]
 *                   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 * Desired result:  [ products  / cellphones      / apple           / iphone-4   ]
 */

    // Add the actual filter    
    add_filter('post_type_link', 'products_type_link', 1, 3);

    function products_type_link($url, $post = null, $leavename = false)
    {
        // products only
        if ($post->post_type != 'products') {
            return $url;
        }

        // Post ID
        $post_id = $post->ID;

        /**
         * URL tag <:> %product-type%
         */
            $taxonomy = 'product-type';
            $taxonomy_tag = '%' . $taxonomy . '%';

            // Check if taxonomy exists in the url
            if (strpos($taxonomy_tag, $url) <= 0) {

                // Get the terms
                $terms = wp_get_post_terms($post_id, $taxonomy);

                if (is_array($terms) && sizeof($terms) > 0) {
                    $category = $terms[0];
                }

                // replace taxonomy tag with the term slug » /products/%product-type%/productname
                $url = str_replace($taxonomy_tag, $category->slug, $url);
            }

        /** 
         * URL tag <:> %product-brand%
         */
        $brand = 'product-brand';
        $brand_tag = '%' . $brand . '%';

        // Check if taxonomy exists in the url
        if (strpos($brand_tag, $url) < 0) {
            return $url;
        } else { $brand_terms = wp_get_post_terms($post_id, $brand); }

        if (is_array($brand_terms) && sizeof($brand_terms) > 0) {
            $brand_category = $brand_terms[0];
        }

        // replace brand tag with the term slug and return complete url » /products/%product-type%/%product-brand%/productname
        return str_replace($brand_tag, $brand_category->slug, $url);

    }

    function products_add_rewrite_rules() 
    {
        global $wp_rewrite;
        global $wp_query;

        /**
         * Post Type <:> products
         */

            // Product labels
            $product_labels = array (
                'name'                  => 'Products',
                'singular_name'         => 'product',
                'menu_name'             => 'Products',
                'add_new'               => 'Add product',
                'add_new_item'          => 'Add New product',
                'edit'                  => 'Edit',
                'edit_item'             => 'Edit product',
                'new_item'              => 'New product',
                'view'                  => 'View product',
                'view_item'             => 'View product',
                'search_items'          => 'Search Products',
                'not_found'             => 'No Products Found',
                'not_found_in_trash'    => 'No Products Found in Trash',
                'parent'                => 'Parent product'
            );

            // Register the post type
            register_post_type('products', array(
                'label'                 => 'Products',
                'labels'                => $product_labels,
                'description'           => '',
                'public'                => true,
                'show_ui'               => true,
                'show_in_menu'          => true,
                'capability_type'       => 'post',
                'hierarchical'          => true,
                'rewrite'               => array('slug' => 'products'),
                'query_var'             => true,
                'has_archive'           => true,
                'menu_position'         => 5,
                'supports'              => array(
                                            'title',
                                            'editor',
                                            'excerpt',
                                            'trackbacks',
                                            'revisions',
                                            'thumbnail',
                                            'author'
                                        )
                )
            );

        /**
         * Taxonomy <:> product-type
         */
            register_taxonomy('product-type', 'products', array(
                'hierarchical' => true, 
                'label' => 'Product Types', 
                'show_ui' => true, 
                'query_var' => true, 
                'rewrite' => array('slug' => 'products/types'),
                'singular_label' => 'Product Types') 
            );

        /**
         * Taxonomy <:> product-type
         */
            register_taxonomy('product-brand', 'products', array(
                'hierarchical' => true, 
                'label' => 'Product Brands', 
                'show_ui' => true, 
                'query_var' => true, 
                'rewrite' => array('slug' => 'product/brands'),
                'singular_label' => 'Product Brands') 
            );

            $wp_rewrite->extra_permastructs['products'][0] = "/products/%product-type%/%product-brand%/%products%";

            // flush the rules
            flush_rewrite_rules();
    }

    // rewrite at init
    add_action('init', 'products_add_rewrite_rules');


いくつかの考え:

これは機能します。両方の分類法を各投稿に割り当てる必要がありますが、URLには末尾が付きます'/'» '/products/taxonomy//postname'。タイプとブランドを使用して、すべてのプロカットに両方の分類法を割り当てるつもりなので、このコードは私のニーズに合っているようです。誰か提案や改善点があれば、遠慮なく返信してください!


優秀な。ソリューションを投稿していただきありがとうございます。十分な時間が経過したら回答として選択してください。また、有用な回答があれば投票することをお勧めします。
marfarma

これを機能させるのに苦労しています。理由はわかりません。変更を移植するのではなく、関数にコピーして貼り付けても、大量のエラーが発生します。これが書かれたとき(3年以上前)と今日の間で、WordPressのコアの何かが変わったに違いないと思います。:私は同じことを把握しようとしているwordpress.stackexchange.com/questions/180994/...
JacobTheDev

flush_rewrite_rules()init?それをしないでください。基本的に、ページを読み込むたびに書き換えルールをリセットします。
honk31

1

この方法で確認してください。ブランドアーカイブにはまだいくつかのバグがあります

http://pastebin.com/t8SxbDJy

add_filter('post_type_link', 'products_type_link', 1, 3);

function products_type_link($url, $post = null, $leavename = false)
{
// products only
    if ($post->post_type != self::CUSTOM_TYPE_NAME) {
        return $url;
    }

    $post_id = $post->ID;

    $taxonomy = 'product_type';
    $taxonomy_tag = '%' . $taxonomy . '%';

    // Check if exists the product type tag
    if (strpos($taxonomy_tag, $url) < 0) {
        // replace taxonomy tag with the term slug: /products/%product_type%/samsumng/productname
        $url = str_replace($taxonomy_tag, '', $url);
    } else {
        // Get the terms
        $terms = wp_get_post_terms($post_id, $taxonomy);

        if (is_array($terms) && sizeof($terms) > 0) {
            $category = $terms[0];
            // replace taxonomy tag with the term slug: /products/%product_type%/samsumng/productname
            $url = str_replace($taxonomy_tag, $category->slug, $url);
        }
        }

    /* 
     * Brand tags 
     */
    $brand = 'product_brand';
    $brand_tag = '%' . $brand . '%';

    // Check if exists the brand tag 
    if (strpos($brand_tag, $url) < 0) {
        return str_replace($brand_tag, '', $url);
    }

    $brand_terms = wp_get_post_terms($post_id, $brand);

    if (is_array($brand_terms) && sizeof($brand_terms) > 0) {
        $brand_category = $brand_terms[0];
    }

    // replace brand tag with the term slug: /products/cell-phone/%product_brand%/productname 
    return str_replace($brand_tag, $brand_category->slug, $url);
}

function products_add_rewrite_rules() 
{
global $wp_rewrite;
global $wp_query;

register_post_type('products', array(
    'label' => 'Products',
    'description' => 'GVS products and services.',
    'public' => true,
    'show_ui' => true,
    'show_in_menu' => true,
    'capability_type' => 'post',
    'hierarchical' => true,
    'rewrite' => array('slug' => 'products'),
    'query_var' => true,
    'has_archive' => true,
    'menu_position' => 6,
    'supports' => array(
        'title',
        'editor',
        'excerpt',
        'trackbacks',
        'revisions',
        'thumbnail',
        'author'),
    'labels' => array (
        'name' => 'Products',
        'singular_name' => 'product',
        'menu_name' => 'Products',
        'add_new' => 'Add product',
        'add_new_item' => 'Add New product',
        'edit' => 'Edit',
        'edit_item' => 'Edit product',
        'new_item' => 'New product',
        'view' => 'View product',
        'view_item' => 'View product',
        'search_items' => 'Search Products',
        'not_found' => 'No Products Found',
        'not_found_in_trash' => 'No Products Found in Trash',
        'parent' => 'Parent product'),
    ) 
);

register_taxonomy('product-categories', 'products', array(
    'hierarchical' => true, 
    'label' => 'Product Categories', 
    'show_ui' => true, 
    'query_var' => true, 
    'rewrite' => array('slug' => 'products'),
    'singular_label' => 'Product Category') 
);

$wp_rewrite->extra_permastructs['products'][0] = "/products/%product_type%/%product_brand%/%products%";

    // product archive
    add_rewrite_rule("products/?$", 'index.php?post_type=products', 'top');

    /* 
     * Product brands
     */
    add_rewrite_rule("products/([^/]+)/([^/]+)/?$", 'index.php?post_type=products&product_brand=$matches[2]', 'top');
    add_rewrite_rule("products/([^/]+)/([^/]+)/page/([0-9]{1,})/?$", 'index.php?post_type=products&product_brand=$matches[2]&paged=$matches[3]', 'top');

    /*
     * Product type archive
     */
    add_rewrite_rule("products/([^/]+)/?$", 'index.php?post_type=products&product_type=$matches[1]', 'top');    
    add_rewrite_rule("products/([^/]+)/page/([0-9]{1,})/?$", 'index.php?post_type=products&product_type=$matches[1]&paged=$matches[1]', 'bottom'); // product type pagination

    // single product
    add_rewrite_rule("products/([^/]+)/([^/]+)/([^/]+)/?$", 'index.php?post_type=products&product_type=$matches[1]&product_brand=$matches[2]&products=$matches[3]', 'top');



flush_rewrite_rules();

}

add_action('init', 'products_add_rewrite_rules');

1

希望する正確なURL構造ではありませんが、以下を取得できます。

/ products
»すべてのカスタム投稿を表示

/ products / type / cell-phones
»分類法の携帯電話に関するすべてのカスタム投稿を表示

/ products / type / cell-phones / brand / samsung
»分類が携帯電話 samsung であるすべてのカスタム投稿を表示

/ brand / samsung
»分類がsamsungであるすべてのカスタム投稿を表示

/ product / test-product-1
»製品を表示(単一のカスタム投稿)

カスタムの書き換えルールを指定する必要はありません。

ただし、分類とカスタム投稿タイプを特定の順序で登録する必要があります。トリックは、カスタムポストタイプを登録する前に、スラッグがポストタイプのスラッグで始まる分類を登録することです。たとえば、次のスラッグを想定します。

product_type taxonomy slug               = products/type
product custom_post_type slug            = product
product custom_post_type archive slug    = products
product_brand taxonomy slug              = brand

次に、次の順序でそれらを登録できます。

register_taxonomy( 
    'products_type', 
    'products', 
        array( 
            'label' => 'Product Type', 
            'labels' => $product_type_labels,
            'public' => true, 
            'show_ui' => true, 
            'show_in_nav_menus' => true, 
            'args' => array( 'orderby' => 'term_order' ),
            'rewrite' => array( 'slug' => 'products/type', 'with_front' => false  ),
            'has_archive' => true,
            'query_var' => true, 
        ) 
);

register_post_type('products', array(
    'labels' =>$products_labels,
    'singular_label' => __('Product'),
    'public' => true,
    'show_ui' => true,
    'capability_type' => 'post',
    'hierarchical' => false,
    'rewrite' => array('slug' => 'product', 'with_front' => false ),
    'has_archive' => 'products',
    'supports' => array('title', 'editor', 'thumbnail', 'revisions','comments','excerpt'),
 ));

register_taxonomy( 
    'products_brand', 
    'products', 
        array( 
            'label' => 'Brand', 
            'labels' => $products_brand_labels,
            'public' => true, 
            'show_ui' => true, 
            'show_in_nav_menus' => true, 
            'args' => array( 'orderby' => 'term_order' ),
            'rewrite' => array( 'slug' => 'brand', 'with_front' => false  ),
            'has_archive' => true,
            'query_var' => true, 
        ) 
);

次のようなURLが絶対に必要な場合:

/ products / type / cell-phones / brand / samsung / test-product-1
»製品を表示(単一のカスタム投稿)

次に、次のような書き換えルールが必要になります。

    add_rewrite_rule(
        '/products/type/*/brand/*/([^/]+)/?',
        'index.php?pagename='product/$matches[1]',
        'top' );

アップデート /programming/3861291/multiple-custom-permalink-structures-in-wordpress

シングルポストURLを正しく再定義する方法は次のとおりです。

カスタム投稿タイプのre-writeをfalseに設定します。(アーカイブはそのままにしておきます)分類や投稿を登録した後、以下の書き換えルールも登録します。

  'rewrite' => false

   global $wp_rewrite;
   $product_structure = '/%product_type%/%brand%/%product%';
   $wp_rewrite->add_rewrite_tag("%product%", '([^/]+)', "product=");
   $wp_rewrite->add_permastruct('product', $product_structure, false);

次に、post_type_linkをフィルタリングして、目的のURL構造を作成します-未設定の分類値を許可します。リンクされた投稿のコードを修正すると、次のようになります。

function product_permalink($permalink, $post_id, $leavename){
    $post = get_post($post_id);

    if( 'product' != $post->post_type )
         return $permalink;

    $rewritecode = array(
    '%product_type%',
    '%brand%',
    $leavename? '' : '%postname%',
    $leavename? '' : '%pagename%',
    );

    if('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft'))){

        if (strpos($permalink, '%product_type%') !== FALSE){

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

            if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0]))  
               $product_type = $terms[0]->slug;
            else 
               $product_type = 'unassigned-artist';         
        }

        if (strpos($permalink, '%brand%') !== FALSE){
           $terms = wp_get_object_terms($post->ID, 'brand');  
           if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) 
               $brand = $terms[0]->slug;
           else 
               $brand = 'unassigned-brand';         
        }           

        $rewritereplace = array(
           $product_type,
           $brand,
           $post->post_name,
           $post->post_name,
        );

        $permalink = str_replace($rewritecode, $rewritereplace, $permalink);
    }
    return $permalink;
}

add_filter('post_type_link', 'product_permalink', 10, 3);

次に、先頭のブランドタグなしでブランド分類URLを書き直す方法を理解する必要があります。目的のURLと正確に一致させる必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.