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

时间:2011-10-21 作者:DRSK

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

  • 帖子类型:productsproduct_typeproduct_brand

添加新产品并为此产品选择类型和品牌:添加新产品时product, 有两个分类框(product\\u type和product\\u brand)。我们把这个新帖子叫做Test Product 1. 我们要做的第一件事是勾选我正在处理的产品类型,比如cell-phones. 接下来,我想勾选产品属于哪个品牌,比方说samsung.

“现在”Test Product 1“”与类型关联"cell-phones" 以及品牌"samsung".

The desired end result is:

/products
»查看所有自定义帖子

/products/cell-phones
»使用taxonomy手机查看所有自定义帖子

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

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


问题是,如何才能做到这一点?我最初的想法是使用一种分类法"cell-phones" 作为的父项"samsung". 实际上,附加分类法及其术语并不是那么困难。但这导致了许多其他问题,有些是众所周知的,有些不是那么多。无论如何,它不是这样工作的,因为它提供了404个问题,WP不允许某些事情
WP.org » taxonomy-archive-template

这导致我重新思考了结构,不得不离开分类法及其术语,我想;为什么不创建第二个分类法,并将帖子类型与之关联,然后将其附加到url?

问得好,但怎么问?

4 个回复
SO网友:soulseekah

通过在某种程度上利用您自己的一些重写规则,这当然是可能的。这个WP_Rewrite API公开了允许您添加重写规则(或“映射”)以将请求转换为查询的函数。

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

This 是一篇关于PHP PCRE(Perl兼容正则表达式)的简短而优秀的教程。

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

我们可以在如下查询中使用这些选项:

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

SO网友:DRSK

最终结果

This is what I came up with partially using bits and pieces from all answers I\'ve got:

/**
 * 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,有一个类型和一个品牌,所以这段代码似乎满足了我的需要。如果有任何建议或改进,请随时回复!

SO网友:marfarma

虽然不是您想要的确切URL结构,但您可以获得:

/products
»查看所有自定义帖子

/products/type/cell-phones
»使用taxonomy手机查看所有自定义帖子

/products/type/cell-phones/brand/samsung
»查看分类法为手机的所有自定义帖子AND 三星

/brand/samsung
»查看分类法为samsung的所有自定义帖子

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

无需指定自定义重写规则。

但它确实要求您按照特定的顺序注册分类法和自定义帖子类型。诀窍是在注册自定义的post类型之前,先注册slug以post类型的slug开头的任何分类法。例如,假设以下段塞:

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\' );
UPDATE https://stackoverflow.com/questions/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\\u type\\u链接以创建所需的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。

SO网友:Luis Abarca

通过这种方式检查,它在品牌存档中仍然存在一些缺陷

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

结束

相关推荐

Multiple permalinks

我的博客使用/?p=378 多年的permalink构造。这对Google Analytics没有多大帮助,我想把它改为YEAR/MONTH/DAY/post-title 结构有没有一种方法可以做到这一点而不丢失向后兼容性,以便旧的链接可以工作?