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

ree*_*ogi 9 wordpress permalinks custom-post-type

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

  1. 我创建了一个名为products的自定义帖子类型.
  2. 然后我为产品类型创建自定义分类.
  3. 然后我添加一个名为"Chairs"的产品类型,并在此类别中添加一个名为"Red Chair"的产品 .

创建此产品后,查看此产品所需的永久链接结构将被格式化为 - >

http://shop.com/products/chairs/red-chair
Run Code Online (Sandbox Code Playgroud)

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

如果可能的话,我还希望尽可能包括所选产品类别的任何父母(例如,如果'主席'类别是'休息室'类别的孩子,则永久链接结构将如下 - >

http://shop.com/products/lounge/chairs/red-chair
Run Code Online (Sandbox Code Playgroud)

以下是我创建自定义帖子类型和自定义分类的方法,我只需要帮助定义重写/ 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
    ));
}
Run Code Online (Sandbox Code Playgroud)

ree*_*ogi 15

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

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

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

  • 自定义帖子类型(register_post_type) - > "产品"
  • 分类法(register_taxonomy) - > "产品类型"

后端功能

我重写了保存在后端的永久链接结构,以便保存永久链接以包含自定义分类法类型 - "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;
}
Run Code Online (Sandbox Code Playgroud)

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

http://website.com/product/chairs/red-chair/
Run Code Online (Sandbox Code Playgroud)

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

前端功能

我们需要添加重写规则,以便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'
);
Run Code Online (Sandbox Code Playgroud)

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

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

product/chairs/red-chair/
Run Code Online (Sandbox Code Playgroud)

进入 - >

index.php?product-type=chair&product=red-chair
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

下行

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