Làm cách nào để thêm nhiều phân loại vào URL?


8

Nhiều nguyên tắc phân loại trong URL

Làm cách nào để nối nhiều phân loại vào URL có các mục sau:

  • Loại bài viết: sản phẩm
  • Phân loại: sản phẩm_type
  • Phân loại: sản phẩm_brand


Thêm sản phẩm mới và chọn loại và nhãn hiệu cho sản phẩm này:

Khi thêm một sản phẩm mới , có hai hộp phân loại (sản phẩm_type và sản phẩm_brand). Hãy gọi bài đăng mới này Sản phẩm thử nghiệm 1 . Điều đầu tiên chúng tôi muốn làm là đánh dấu vào loại sản phẩm tôi đang xử lý, giả sử điện thoại di động . Tiếp theo, tôi muốn đánh dấu sản phẩm thuộc về thương hiệu nào, giả sử samsung.

Bây giờ " Sản phẩm thử nghiệm 1 " được liên kết với loại "điện thoại di động" và nhãn hiệu "samsung" .

Kết quả cuối cùng mong muốn là:

/ sản phẩm
»Xem tất cả các bài viết tùy chỉnh

/ sản phẩm / điện thoại di động
»Xem tất cả các bài đăng tùy chỉnh với điện thoại di động phân loại

/ sản phẩm / điện thoại di động / samsung /
»Xem tất cả các bài đăng tùy chỉnh trong đó phân loại là điện thoại di động samsung

/ sản phẩm / điện thoại di động / samsung / thử nghiệm sản phẩm-1
»Xem sản phẩm (bài đăng tùy chỉnh duy nhất)


Câu hỏi

Làm thế nào một người có thể làm điều này có thể? Suy nghĩ ban đầu của tôi là sử dụng một nguyên tắc phân loại, có "điện thoại di động" là thuật ngữ chính của "samsung" . Trên thực tế, việc nối thêm phân loại và các điều khoản của nó không quá khó khăn. Nhưng nó đã dẫn đến rất nhiều vấn đề khác, một số nổi tiếng, một số không quá nhiều. Dù sao nó cũng không hoạt động như vậy vì nó mang đến 404 vấn đề và WP sẽ không cho phép một số thứ nhất định.
WP.org »phân loại-lưu trữ-mẫu

Điều này dẫn đến việc tôi đã suy nghĩ lại về cấu trúc, phải rời khỏi các nguyên tắc phân loại và các điều khoản của nó và tôi nghĩ; tại sao không tạo phân loại thứ 2 và liên kết loại bài đăng với nó và nối nó vào url?

Câu hỏi tốt thực sự, nhưng làm thế nào?


bạn có thể kiểm tra liên kết này tôi có vấn đề với cùng một điều stackoverflow.com/questions/34351477/...
Sanjay Nakate

Câu trả lời:


7

Điều này chắc chắn là có thể bằng cách sử dụng một số quy tắc viết lại của riêng bạn ở một mức độ nào đó. Các WP_Rewrite phơi bày API chức năng cho phép bạn thêm các quy tắc viết lại (hoặc 'bản đồ') để chuyển đổi một yêu cầu truy vấn.

Có những điều kiện tiên quyết để viết các quy tắc viết lại tốt, và điều quan trọng nhất là hiểu biểu thức chính quy cơ bản. Công cụ viết lại WordPress sử dụng các biểu thức thông thường để dịch các phần của URL sang các truy vấn để nhận bài đăng.

Đây là một hướng dẫn ngắn và hay về PHP PCRE (biểu thức chính quy tương thích Perl).

Vì vậy, bạn đã thêm hai nguyên tắc phân loại, giả sử tên của chúng là:

  • Loại sản phẩm
  • thương hiệu sản phẩm

Chúng ta có thể sử dụng chúng trong các truy vấn như vậy:

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

Các truy vấn sẽ được ?product_type=cell-phones&product_brand=samsung. Nếu bạn nhập như là truy vấn của bạn, bạn sẽ nhận được một danh sách các điện thoại Samsung. Để viết lại /cell-phones/samsungvào truy vấn đó, một quy tắc viết lại phải được thêm vào.

add_rewrite_rule()sẽ làm điều này cho bạn. Dưới đây là một ví dụ về quy tắc viết lại của bạn có thể trông như thế nào đối với trường hợp trên:

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

Bạn sẽ cần flush_rewrite_rules()ngay sau khi bạn thêm quy tắc viết lại để lưu nó vào cơ sở dữ liệu. Điều này được thực hiện chỉ một lần, không cần phải làm điều này với mọi yêu cầu, một khi quy tắc được tuôn ra ở đó. Để loại bỏ nó chỉ đơn giản là tuôn ra mà không cần thêm quy tắc viết lại.

Nếu bạn muốn thêm phân trang, bạn có thể làm như vậy bằng cách:

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

1
Bài viết đơn giản nhất mà tôi đã thấy liên quan đến các quy tắc viết lại wordpress. Đã đọc rất nhiều nhưng sau khi đọc nó, cuối cùng mọi thứ đã hoạt động. Cảm ơn! +1
evu

3

Kết quả cuối cùng

Đây là những gì tôi đã đưa ra bằng cách sử dụng một phần bit và miếng từ tất cả các câu trả lời tôi đã nhận được:

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


Một vài suy nghĩ:

Điều này không hoạt động. Mặc dù bạn 'bắt buộc' phải gán cả hai nguyên tắc phân loại cho mỗi bài đăng hoặc URL sẽ có dấu vết '/'» '/products/taxonomy//postname'. Vì tôi sẽ gán cả hai nguyên tắc phân loại cho tất cả các sản phẩm của mình, có một loại và nhãn hiệu, mã này dường như đang hoạt động cho nhu cầu của tôi. Nếu bất cứ ai có bất kỳ đề nghị hoặc cải tiến hãy trả lời!


Thông minh. Cảm ơn đã đưa ra giải pháp của bạn. Vui lòng chọn nó làm câu trả lời một khi đủ thời gian đã qua. Ngoài ra, nên bỏ phiếu bất kỳ câu trả lời hữu ích nào.
marfarma

Tôi đang có một thời gian khó khăn để làm việc này, không biết tại sao. Ngay cả việc sao chép / dán vào các chức năng của tôi thay vì cố gắng chuyển qua các thay đổi của bạn cũng mang lại cho tôi vô số lỗi. Tôi đang nghĩ một cái gì đó trong cốt lõi của WordPress phải thay đổi giữa khi nó được viết (hơn 3 năm trước) và ngày nay. Tôi đang cố gắng tìm ra điều tương tự: wordpress.stackexchange.com/questions/180994/NH
JacobTheDev 12/03/2015

flush_rewrite_rules()trên init? đừng với nó về cơ bản, bạn đang đặt lại quy tắc viết lại của mình với mỗi lần tải trang.
honk31

1

Kiểm tra theo cách này, nó vẫn có một số lỗi với kho lưu trữ thương hiệu

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

Mặc dù không phải là cấu trúc URL mong muốn chính xác của bạn, bạn có thể nhận được:

/ sản phẩm
»Xem tất cả các bài viết tùy chỉnh

/ sản phẩm / loại / điện thoại di động
»Xem tất cả các bài đăng tùy chỉnh với điện thoại di động phân loại

/ sản phẩm / loại / điện thoại di động / nhãn hiệu / samsung
»Xem tất cả các bài đăng tùy chỉnh trong đó phân loại là điện thoại di động samsung

/ brand / samsung
»Xem tất cả các bài đăng tùy chỉnh trong đó phân loại là samsung

/ sản phẩm / thử nghiệm-sản phẩm-1
»Xem sản phẩm (bài đăng tùy chỉnh duy nhất)

mà không phải xác định quy tắc viết lại tùy chỉnh.

Nó yêu cầu bạn phải đăng ký phân loại và các loại bài tùy chỉnh theo một thứ tự cụ thể. Mẹo nhỏ là đăng ký bất kỳ phân loại nào trong đó sên bắt đầu bằng sên sau loại của bạn trước khi bạn đăng ký loại bài tùy chỉnh đó. Ví dụ: giả sử các sên sau:

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

Sau đó, bạn có thể đăng ký chúng theo thứ tự này:

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

Nếu bạn hoàn toàn phải có một URL như:

/ sản phẩm / loại / điện thoại di động / nhãn hiệu / samsung / thử nghiệm sản phẩm-1
»Xem sản phẩm (bài đăng tùy chỉnh duy nhất)

Sau đó, bạn sẽ yêu cầu một quy tắc viết lại một cái gì đó như thế này:

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

CẬP NHẬT /programming/3861291/multipl-custom-permalink- cấu trúc-in-wordpress

Đây là cách bạn xác định lại chính xác URL bài đăng duy nhất.

Đặt viết lại thành false cho loại bài tùy chỉnh. (Để nguyên kho lưu trữ) và sau đó sau khi đăng ký các nguyên tắc phân loại và bài đăng, cũng đăng ký các quy tắc viết lại sau đây.

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

Sau đó, lọc post_type_link để tạo cấu trúc URL mong muốn - cho phép bỏ đặt các giá trị phân loại. Sửa đổi mã từ bài đăng được liên kết, bạn sẽ có:

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

Bây giờ tôi chỉ cần tìm ra cách viết lại url phân loại thương hiệu mà không cần thẻ thương hiệu hàng đầu và tôi phải khớp chính xác URL mong muốn của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.