Bagaimana cara menambahkan beberapa taksonomi ke URL?

8

Beberapa taksonomi dalam URL

Bagaimana cara menambahkan beberapa taksonomi ke URL memiliki yang berikut ini:

  • Jenis Posting: produk
  • Taksonomi: product_type
  • Taksonomi: product_brand


Menambahkan produk baru dan memilih jenis dan merek untuk produk ini:

Saat menambahkan produk baru , ada dua kotak taksonomi (product_type dan product_brand). Sebut postingan baru ini Test Product 1 . Hal pertama yang ingin kami lakukan adalah mencentang jenis produk yang saya tangani, katakanlah ponsel . Selanjutnya, saya ingin mencentang merek milik produk tersebut, katakanlah samsung.

Sekarang " Produk Uji 1 " dikaitkan dengan jenis "ponsel" dan merek "samsung" .

Hasil akhir yang diinginkan adalah:

/ produk
»Lihat semua posting khusus

/ produk / ponsel
»Lihat semua posting kustom dengan ponsel taksonomi

/ produk / ponsel-ponsel / samsung /
»Lihat semua posting kustom di mana taksonomi adalah ponsel DAN samsung

/ produk / telepon seluler / samsung / tes-produk-1
»Lihat produk (pos khusus tunggal)


Pertanyaan

Bagaimana seseorang memungkinkan ini terjadi? Pikiran awal saya menggunakan satu taksonomi, memiliki "ponsel" sebagai istilah induk dari "samsung" . Sebenarnya menambahkan taksonomi dan ketentuannya tidak begitu sulit. Tapi itu menyebabkan banyak masalah lain, beberapa terkenal, beberapa tidak begitu banyak. Pokoknya itu tidak berfungsi seperti itu karena memberikan 404 masalah dan WP tidak akan mengizinkan hal-hal tertentu.
WP.org »taksonomi-arsip-templat

Ini menuntun saya untuk memikirkan kembali struktur, harus meninggalkan taksonomi dan ketentuannya dan saya pikir; mengapa tidak membuat taksonomi kedua, dan kaitkan jenis posting dengan itu dan menambahkannya ke url?

Pertanyaan yang bagus memang, tapi bagaimana?

DRSK
sumber
dapatkah Anda memeriksa tautan ini? Saya punya masalah dengan hal yang sama stackoverflow.com/questions/34351477/...
Sanjay Nakate

Jawaban:

7

Ini tentu dimungkinkan dengan memanfaatkan beberapa aturan penulisan ulang Anda sendiri sampai batas tertentu. The WP_Rewrite API paparan fungsi yang memungkinkan Anda untuk menambahkan aturan penulisan ulang (atau 'peta') untuk mengkonversi permintaan untuk query.

Ada prasyarat untuk menulis aturan penulisan ulang yang baik, dan yang paling penting adalah pemahaman ekspresi reguler dasar. Mesin WordPress Rewrite menggunakan ekspresi reguler untuk menerjemahkan bagian dari URL ke kueri untuk mendapatkan posting.

Ini adalah tutorial singkat dan bagus tentang PHP PCRE (ekspresi reguler yang kompatibel dengan Perl).

Jadi, Anda telah menambahkan dua taksonomi, anggap saja namanya:

  • tipe produk
  • product_brand

Kita bisa menggunakan ini dalam kueri seperti:

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

Kueri akan menjadi ?product_type=cell-phones&product_brand=samsung. Jika Anda mengetiknya sebagai kueri, Anda akan mendapatkan daftar ponsel Samsung. Untuk menulis ulang /cell-phones/samsungke kueri itu, aturan penulisan ulang harus ditambahkan.

add_rewrite_rule()akan melakukan ini untukmu. Berikut ini contoh tampilan aturan penulisan ulang Anda untuk kasus di atas:

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

Anda harus flush_rewrite_rules()segera setelah Anda menambahkan aturan penulisan ulang untuk menyimpannya ke database. Ini dilakukan hanya sekali, tidak perlu melakukan ini dengan setiap permintaan, sekali aturan yang ada di sana. Untuk menghapusnya cukup siram tanpa aturan penulisan ulang yang ditambahkan.

Jika Anda ingin menambahkan pagination, Anda dapat melakukannya dengan melakukan sesuatu seperti:

add_rewrite_rule( '^products/([^/]*)/([^/]*)/(\d*)?',
    'index.php?product_type=$matches[1]&product_brand=$matches[2]&p=$matches[3]',
    'top' );
soulseekah
sumber
1
Artikel paling sederhana yang pernah saya lihat mengenai aturan penulisan ulang wordpress. Sudah banyak membaca tetapi setelah membaca ini, akhirnya semuanya berjalan lancar. Terima kasih! +1
evu
3

Hasil akhirnya

Inilah yang saya buat sebagian menggunakan bit dan potongan dari semua jawaban yang saya dapatkan:

/**
 * 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');


Beberapa pemikiran:

Ini berhasil. Meskipun Anda 'diharuskan' untuk menetapkan taksonomi kedua untuk setiap posting atau URL akan memiliki trailing '/'» '/products/taxonomy//postname'. Karena saya akan menetapkan kedua taksonomi untuk semua procuts saya, memiliki tipe dan merek, kode ini tampaknya berfungsi untuk kebutuhan saya. Jika ada yang punya saran atau peningkatan, silakan balas!

DRSK
sumber
Luar biasa. Terima kasih telah memposting solusi Anda. Silakan pilih sebagai jawaban setelah waktu yang cukup telah lewat. Juga, disarankan untuk memilih-pilih jawaban yang bermanfaat.
marfarma
Saya mengalami kesulitan mendapatkan ini untuk bekerja, tidak yakin mengapa. Bahkan menyalin / menempel ke fungsi saya daripada mencoba porting perubahan Anda memberi saya banyak kesalahan. Saya sedang memikirkan sesuatu di inti WordPress yang pasti telah berubah antara saat ini ditulis (lebih dari 3 tahun yang lalu) dan hari ini. Saya mencoba mencari tahu hal yang sama: wordpress.stackexchange.com/questions/180994/...
JacobTheDev
flush_rewrite_rules()pada init? jangan lakukan itu. pada dasarnya Anda mengatur ulang aturan penulisan ulang Anda dengan setiap halaman memuat.
membunyikan 31
1

Lihat dengan cara ini, masih ada beberapa bug dengan arsip merek

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');
Luis Abarca
sumber
1

Meskipun bukan struktur URL yang diinginkan, Anda bisa mendapatkan:

/ produk
»Lihat semua posting khusus

/ produk / tipe / ponsel
»Lihat semua posting kustom dengan ponsel taksonomi

/ products / type / cell-phone / brand / samsung
»Lihat semua posting kustom di mana taksonomi adalah ponsel DAN samsung

/ brand / samsung
»Lihat semua posting khusus tempat taksonominya adalah samsung

/ produk / test-product-1
»Lihat produk (pos khusus tunggal)

tanpa harus menentukan aturan penulisan ulang kustom.

Itu memang mengharuskan Anda mendaftarkan taksonomi dan jenis pos kustom dalam urutan tertentu. Caranya adalah dengan mendaftarkan taksonomi apa pun di mana siput dimulai dengan siput tipe-posting Anda sebelum Anda mendaftarkan tipe posting khusus itu. Misalnya, asumsikan siput berikut:

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

Kemudian Anda bisa mendaftarkannya dalam urutan ini:

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, 
        ) 
);

Jika Anda benar-benar harus memiliki URL seperti:

/ produk / tipe / telepon seluler / merek / samsung / test-product-1
»Lihat produk (pos khusus tunggal)

Maka Anda akan membutuhkan aturan penulisan ulang sesuatu seperti ini:

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

UPDATE /programming/3861291/multiple-custom-permalink-structures-in-wordpress

Inilah cara Anda mendefinisikan ulang URL satu posting dengan benar.

Setel tulis ulang menjadi false untuk jenis posting khusus. (Biarkan arsip apa adanya) dan kemudian setelah mendaftarkan taksonomi dan posting, daftarkan juga aturan penulisan ulang berikut.

  '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);

Kemudian filter post_type_link untuk membuat struktur URL yang diinginkan - memungkinkan untuk nilai taksonomi yang tidak disetel. Mengubah kode dari pos tertaut, Anda harus:

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);

Sekarang saya hanya perlu mencari cara untuk menulis ulang url taksonomi merek tanpa label merek terkemuka, dan saya harus mencocokkan URL yang Anda inginkan dengan tepat.

marfarma
sumber