【问题标题】:Define permalinks for custom post type by taxonomy按分类定义自定义帖子类型的永久链接
【发布时间】:2012-11-13 06:51:01
【问题描述】:

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

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

创建此产品后,用于查看此产品的所需的永久链接结构将是 像这样格式化 ->

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

【问题讨论】:

  • 能否请您阅读我前段时间写的this 文章。它几乎可以满足您的需求,只是它只支持两级分类固定链接。这意味着http://shop.com/products/lounge/chairs/red/fancy-chair 很可能不起作用。
  • 嗯,尝试将它与我的代码集成,也可以单独集成。它根本没有选择“FAQ”网址前缀......

标签: wordpress custom-post-type permalinks


【解决方案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);

【讨论】:

    【解决方案2】:

    解决方案

    在 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 个级别,因此它匹配产品类型,然后是产品,并将它们添加到匹配数组中,其中产品类型 = $matches1,产品 = $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 plugin。 (注意,这个插件没有任何管理菜单,它允许您通过创建数组在您的functions.php中为自定义帖子类型编写元框 - 强烈推荐!)

    【讨论】:

    • 我希望您能提供帮助 - 除了单级重写规则之外,您的示例效果很好 - 它似乎不起作用?我只是找不到页面。当我手动输入 index.php?product-type=chair 时,它会将我重定向到 /{taxonomy-slug-name}/chair 但确实有效?
    • 感谢您的解决方案!必须将 $term = $terms[0]->slug; 更改为 $first_key = reset($terms); $term = $first_key->slug; 才能使概览页面上的锚点正常工作!
    • 这适用于您应用它的cpt,但重定向规则会重写页面中显示的所有永久链接,甚至是其他cpt。我错过了什么吗?
    猜你喜欢
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多