首页 文章

通过分类法定义自定义帖子类型的永久链接

提问于
浏览
7

我想为产品和产品类型创建规范的永久链接 . 我有自定义的帖子类型和自定义分类法,但我不知道是否可以用分类法定义永久链接 . 所以我的工作流程就是这样......

  • 我创建了一个名为 products 的自定义帖子类型 .

  • 然后我为 product types 创建了一个自定义分类 .

  • 然后我添加名为 'Chairs' 的产品类型,并将名为 'Red Chair' 的产品添加到此类别 .

创建此产品后,查看此产品的 desired permalink structure 将被格式化为 - >

http://shop.com/products/chairs/red-chair

这在wordpress 3.4中是否可行?我的自定义帖子类型中的元框允许选择为我的自定义分类法定义的产品类型,每个产品只有一种类型 .

如果可能,我还希望尽可能包括所选产品类别的任何父级(例如,如果 'chairs' 类别是 'lounge' 类别的子级,则永久链接结构如下 - >

http://shop.com/products/lounge/chairs/red-chair

以下是我创建自定义帖子类型和自定义分类的方法,我只需要帮助定义重写/ slug规则以在永久链接中包含产品类型 .

/* Custom Post Type - Products ------- */
function products_init() {
    $args = array(
        'public' => true,
        'label' => 'Products'
    );
    register_post_type( 'products', $args );
}
add_action( 'init', 'products_init' );

/* Custom Taxonomy - Product Type ------- */
add_action( 'init', 'create_prodtype' );
function create_prodtype() {
    $labels = array(
        'name' => _x( 'Product Type', 'products' ),
        'singular_name' => _x( 'Product Category', 'product' ),
        'search_items' =>  __( 'Search Product Types' ),
        'all_items' => __( 'All Product Types' ),
        'parent_item' => __( 'Products' ),
        'parent_item_colon' => __( 'Products:' ),
        'edit_item' => __( 'Edit Product Type' ),
        'update_item' => __( 'Update Product Type' ),
        'add_new_item' => __( 'Add New Product Type' ),
        'new_item_name' => __( 'New Product Type' ),
    );
    register_taxonomy(
        'products',
        array('products'),
        array(
            'rewrite' => array(
                'slug' => 'products',
                'hierarchical' => true
            ), 
            'with_front' => false,
            'labels' => $labels
    ));
}

2 回答

  • 14

    Solution

    我在Jan Fabry的这些帖子的帮助下想出来了 - >

    https://wordpress.stackexchange.com/a/5478/10350 https://wordpress.stackexchange.com/a/22490/10350

    我已经设置了自定义帖子类型如下 - >

    • 自定义帖子类型(register_post_type) - > "product"

    • 分类法(register_taxonomy) - > "product-type"


    Back-end function

    我重写了保存在后端的永久链接结构,以便保存永久链接以包含自定义分类法类型 - “product-type”

    add_filter('post_type_link', 'product_type_permalink', 10, 4);
    function product_type_permalink($post_link, $post, $leavename, $sample) {
        //If is custom post type "product"
        if ($post->post_type == 'product') {
            // Get current post object
            global $post;
            // Get current value from custom taxonomy "product-type"
            $terms = get_the_terms($post->id, 'product-type');
            // Define category from "slug" of taxonomy object
            $term = $terms[0]->slug;
            // Re-structure permalink with string replace to include taxonomy value and post name
            $permalink = str_replace('product/', 'product/' . $term . '/', $post_link);
        }
        return $permalink;
    }
    

    permalink setting 设置为'Post name'并保存 . 如果将产品添加到类别并保存,则应重新编写永久链接以包括自定义分类法定义,在本例中为"product-type" . 因此,如果将"Red Chair"添加到"Chairs"类别,则URL的格式如下 - >

    http://website.com/product/chairs/red-chair/
    

    但是,如果您尝试转到此页面,则会出现404错误 . 这是因为wordpress还不知道如何使用此URL查询数据库,因此您必须编写它 .

    Front-end function

    我们需要添加重写规则,以便wordpress可以获取我们的URL并查询数据库 . 我们使用wordpress函数 add_rewrite_rule 将给定的永久链接转换为查询字符串 .

    add_rewrite_rule(
        // The regex to match the incoming URL
        'product/([^/]+)/([^/]+)/?',
        // The resulting internal URL: `index.php` because we still use WordPress
        // `pagename` because we use this WordPress page
        // `designer_slug` because we assign the first captured regex part to this variable
        'index.php?product-type=$matches[1]&product=$matches[2]',
        // This is a rather specific URL, so we add it to the top of the list
        // Otherwise, the "catch-all" rules at the bottom (for pages and attachments) will "win"
        'top'
    );
    

    在此函数中,matches数组由Wordpress定义,在每个斜杠处展开给定的字符串 . 因此,在此示例中,正则表达式 ([^/]+) 用于匹配每个斜杠之间的任何内容 . 在此示例中有2个级别,因此它匹配产品类型,然后匹配产品,并将它们添加到匹配数组,其中product-type = $匹配1,product = $匹配[2] .

    这个重写规则翻译了这个 - >

    product/chairs/red-chair/
    

    进入 - >

    index.php?product-type=chair&product=red-chair
    

    我们的数据库可用于查询数据库并返回带有格式化永久链接的正确产品页面 .

    这会抛弃产品类型的页面,因为url,product-type中只有一个级别 . 这意味着重写规则目前将始终尝试识别查询字符串中定义的产品名称 . 所以为此,我们还编写了一个单级重写规则:

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

    现在,这也将查询产品类型页面,因此如果我们想要显示各种产品类型,我们可以像往常一样循环分类,当我们尝试链接到它们时不会抛出404错误 .

    Downside

    这目前只采用单一级别的分类,因此自定义分类结构不能是分层的 . 如果指定多个分类,则将使用具有第一个ID的最多分类来定义永久链接 . 一个潜在的解决方法是隐藏自定义帖子类型的侧栏中显示的自定义分类菜单,并为分类法添加一个元框,其中只能使用选择框 . 我使用Meta Box plugin . (nb,这个插件没有任何管理菜单,它允许你只在创建数组时在你的functions.php中为自定义帖子类型编写元框 - 强烈推荐!)

  • 1

    @reekogi这适用于产品自定义帖子类型,但会中断所有其他帖子类型 .

    add_filter('post_type_link', 'product_type_permalink', 10, 4);
    function product_type_permalink($post_link, $post, $leavename, $sample) {
        //If is custom post type "product"
        if ($post->post_type == 'product') {
            // Get current post object
            global $post;
            // Get current value from custom taxonomy "product-type"
            $terms = get_the_terms($post->id, 'product-type');
            // Define category from "slug" of taxonomy object
            $term = $terms[0]->slug;
            // Re-structure permalink with string replace to include taxonomy value and post name
            $permalink = str_replace('product/', 'product/' . $term . '/', $post_link);
        }
        return $permalink;
    }
    

    A fix would be change vars $post_link and $permalink to $url

    function product_type_permalink($url, $post, $leavename, $sample) {
        //If is custom post type "product"
        if ($post->post_type == 'product') {
            // Get current post object
            global $post;
            // Get current value from custom taxonomy "product-type"
            $terms = get_the_terms($post->id, 'product-type');
            // Define category from "slug" of taxonomy object
            $term = $terms[0]->slug;
            // Re-structure permalink with string replace to include taxonomy value and post name
            $url = str_replace('product/', 'product/' . $term . '/', $url);
        }
        return $url;
    }
    add_filter('post_type_link', 'product_type_permalink', 10, 4);
    

相关问题