如何将多个分类法附加到URL?


8

URL中的多个分类法

如何将多个分类法附加到具有以下内容的URL:

  • 职位类型:产品
  • 分类法:product_type
  • 分类:product_brand


添加新产品并选择该产品的类型和品牌:

添加新产品时,有两个分类框(product_type和product_brand)。我们将此称为“ 测试产品1”。我们要做的第一件事是打勾我要处理的产品类型,例如手机。接下来,我想打勾该产品所属的品牌,比如说三星。

现在,“ 测试产品1 ”与类型“手机”和品牌“三星”相关联

所需的最终结果是:

/产品
»查看所有自定义帖子

/ products / cells手机
»使用分类手机查看所有自定义帖子

/ product / cell-phones / samsung /
»查看所有分类为手机三星的自定义帖子

/ products / cells-phones / samsung / test-product-1
»查看产品(单个自定义帖子)


问题

一个人如何做到这一点?我最初的想法是使用一种分类法,将“手机”作为“三星”的父项。实际上,附加分类法及其术语并不是那么困难。但这导致了许多其他问题,其中一些是众所周知的,有些不是很多。无论如何,它不能那样工作,因为它会发出404问题,而WP不允许某些事情。
WP.org»分类存档模板

这导致我重新考虑了结构,不得不离开分类法及其术语,我认为;为什么不创建第二分类法,并将其与帖子类型相关联,并将其附加到网址?

确实是个好问题,但是如何?


您可以检查这个环节我有同样的事情的问题stackoverflow.com/questions/34351477/...
桑杰Nakate

Answers:


7

通过一定程度地利用自己的一些重写规则,这当然是可能的。该WP_Rewrite API公开功能,允许您添加重写规则(或“地图”)转换为查询请求。

编写好的重写规则有先决条件,而最重要的一个是基本的正则表达式理解。WordPress重写引擎使用正则表达式将URL的一部分转换为查询以获取帖子。

是有关PHP PCRE(与Perl兼容的正则表达式)的简短教程。

因此,您添加了两个分类法,假设它们的名称为:

  • 产品类别
  • product_brand

我们可以在查询中使用它们,如下所示:

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

该查询将为?product_type=cell-phones&product_brand=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
我见过的关于Wordpress重写规则的最简单的文章。读了很多书,但是读完这些书,终于使事情正常了。谢谢!+1
evu '18

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'。由于我将两种分类法都分配给我的所有procut,具有类型和品牌,因此该代码似乎可以满足我的需求。如果有人有任何建议或改进,请随时回复!


优秀的。感谢您发布解决方案。一旦时间过去,请选择它作为答案。另外,建议您对所有有用的答案进行投票。
marfarma 2011年

我很难让它工作,不知道为什么。即使复制/粘贴到我的函数中,而不是尝试移植所做的更改,也会给我带来很多错误。我认为WordPress核心中的某些内容必须在撰写本文时(超过3年前)和今天之间有所变化。我试图找出同样的事情: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结构,但您可以获得:

/产品
»查看所有自定义帖子

/产品/类型/手机
»使用分类手机查看所有自定义帖子

/产品/类型/手机/品牌/三星
»查看所有分类为手机三星的自定义帖子

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

如果您绝对必须具有以下网址:

/ products / type / cells / 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);

现在,我只需要弄清楚如何在没有前导品牌标签的情况下重写品牌分类网址,并且我应该准确匹配您所需的网址。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.