10

我想为产品和产品类型创建规范的永久链接。我已经确定了自定义帖子类型和自定义分类法,但我不知道是否可以使用分类法定义永久链接。例如,我的工作流程是这样的……

  1. 我创建了一个名为products的自定义帖子类型。
  2. 然后我为产品类型创建了一个自定义分类法。
  3. 然后我添加一个名为“椅子”的产品类型,并将一个名为 “红色椅子”的产品添加到此类别。

一旦我创建了这个产品,查看这个产品所需的永久链接结构将被格式化为 ->

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

这在wordpress 3.4中可能吗?我的自定义帖子类型中的元框允许选择为我的自定义分类定义的产品类型,并且每个产品只会有一种类型。

如果可能的话,如果可能的话,我还想包括所选产品类别的任何父项(例如,如果“椅子”类别是“休息室”类别的子项,则永久链接结构如下 ->

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

2 回答 2

15

解决方案

在 Jan Fabry 的这些帖子的帮助下,我已经弄清楚了->

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

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

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

后端功能

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

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

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

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

但是如果你尝试去这个页面,你会得到一个 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'
);

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

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

product/chairs/red-chair/

进入这个->

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

我们的数据库可以使用它来查询数据库并使用格式化的永久链接返回正确的产品页面。

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

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

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

缺点

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

于 2012-11-26T16:53:05.120 回答
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;
}

解决方法是将变量 $post_link 和 $permalink 更改为 $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);
于 2015-08-21T13:47:37.653 回答