是否从自定义分类中显示某些术语,但排除‘父’术语?

时间:2011-05-05 作者:RodeoRamsey

我有一个自定义的帖子类型“mycustom\\u products”(层次结构),它具有称为“categories”和“tags”的自定义分类法(与许多其他自定义帖子类型一样)。我的自定义类别称为“myprod\\u category”(也是分层的),我的标记分类法称为“product\\u tag”(非分层的)。

我想显示仅对应于特定产品类别的产品标签列表。

例如,“soap”等产品类别;“乳液”,可能会有“蓝莓”或“薰衣草”(香味)的标签,但“珠宝”会有“银”或“金”等标签。我希望能够有一个仅“气味”标签的列表(这将是仅与“肥皂”和“乳液”类别相对应的标签。我不希望包括“珠宝”标签。因此,在这些类别中输入的产品上使用的任何标签都将包括在内,而在其他类别中使用的任何标签都不会包括在内。

显然,我可以将所有内容硬编码到主题中,但如果/当客户端添加更多标记时,我将不得不重新编码所有内容,我希望避免这样做。

我试过使用<?php wp_tag_cloud( array( \'taxonomy\' => \'product_tag\', format => \'list\' ) ); ?> 列出我所有的标签,但我似乎无法得到排除参数来阻止显示整个“产品类别”。似乎我可以使用tag\\u ID来完成这项工作,但这会很乏味,而且会让我重新将它们硬编码到主题中,并且每次添加新标记时都必须进行更新。

是否有筛选器或其他可用于排除类别的内容?或者有没有更好的方式以这种方式列出标签。谢谢

2 个回复
最合适的回答,由SO网友:TheDeadMedic 整理而成

如果您有很多产品,那么定制sql查询可能是更好的选择。

我可能会建议你走这条路线。自定义查询可能会“讨厌”,但在大多数情况下,它会减轻资源负担,并且会稍微快一点*

我已经编写了一个函数,它完成了大部分工作,在其他场景中可能会派上用场(我用“soft”一词表示关系不明确)。

/**
 * Get terms that are indirectly associated with others through the posts they
 * are attached to.
 * 
 * @see http://codex.wordpress.org/Function_Reference/WP_Query#Taxonomy_Parameters
 * @link http://wordpress.stackexchange.com/questions/16393/
 * 
 * @param string|array $taxonomy The taxonomy(s) of the terms you wish to obtain.
 * @param array $tax_query A tax query for the posts you want to make the association with.
 * @return array Array of term IDs.
 */
function get_terms_soft_associated( $taxonomy, $tax_query  )
{
    global $wpdb;

    // so you can pass a single tax query rather than wasted nested array
    if ( isset( $tax_query[\'taxonomy\'] ) )
        $tax_query = array( $tax_query );

    $tax = new WP_Tax_Query( $tax_query );
    extract( $tax->get_sql( $wpdb->posts, \'ID\' ) );

    if ( empty( $join ) || ( !$posts = $wpdb->get_col( "SELECT $wpdb->posts.ID FROM $wpdb->posts $join WHERE 1=1 $where" ) ) )
        return array();

    $taxonomy = implode( "\',\'", array_map( \'esc_sql\', ( array ) $taxonomy ) );
    $posts = implode( \',\', wp_parse_id_list( $posts ) );

    return $wpdb->get_col(
        "SELECT DISTINCT t.term_id FROM $wpdb->terms AS t " .
        "INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id " .
        "INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id " .
        "WHERE tt.taxonomy IN(\'$taxonomy\') AND tr.object_id IN($posts)"
    );
}
您也可以退房the codex on tax queries 有关更多帮助$tax_query. 这是我们用来过滤帖子的查询,然后再进行反向查找以收集帖子的所有术语,以用于另一种分类法。

现在开始解决方案;

// suggestion 1 - for a single post
$product_cats = get_the_terms( get_the_ID(), \'myprod_category\' );

// suggestion 2 - for a product category archive
$product_cats = get_queried_object_id();

// suggestion 3 - for all posts on the current page of an archive
foreach( $wp_query->posts as $_post ) {
    $_product_cats = get_the_terms( $_post->ID, \'myprod_category\' );
    foreach ( $_product_cats as $_product_cat )
        $product_cats[] = $_product_cat->term_id;
}

// now get the \'associated\' tag IDs
$product_assoc_tags = get_term_soft_association( \'product_tag\', array(
    \'taxonomy\' => \'myprod_category\',
    \'field\'    => \'term_id\',
    \'terms\'    => $product_cats
) );

wp_tag_cloud( array( \'taxonomy\' => \'product_tag\', \'include\' => $product_assoc_tags ) );
请注意,这些建议是如何获取所有产品类别以供以后查询的示例,具体取决于您的情况以及您希望影响结果的帖子(仅使用其中一个建议,或您自己的建议!)。

如果您发现它没有像您预期的那样工作,那么我们可能只需要调整函数第二个参数的税务查询。

*Footnote: 本机post查询提取所有post数据,而我们只需要使用ID。把内存保存在你可以帮助的地方,正如@Daniel所说,如果我们谈论很多帖子,我们也谈论了很多内存。

我还说,在开箱即用的条件下,我们使用的数据库查询要少得多;比我们使用的函数get_terms()get_posts().

SO网友:MZAweb

如果我理解正确,我认为没有直接的选择。

您应该查询所需类别内的所有产品,迭代这些记录,并获取每个产品的标签。如果你有很多产品,这会很慢。

类似于(这是针对常规类别/标记的,您应该将其修改为自定义分类法)

    $posts = get_posts("cat=5&numberposts=-1");
$tags = Array();
foreach ($posts as $ipost){
    $posttags = get_the_tags($ipost->ID);
    foreach ($posttags as $posttag){
        if (!in_array($posttag->term_id, $tags)){
            array_push($tags, $posttag->term_id);

        }
    }
}
现在,您在$tags中找到了要查找的标记的唯一ID。

如果您有很多产品,那么定制sql查询可能是更好的选择。

结束

相关推荐

Creating tags via API

我正在研究使用wpapi通过AJAX插入帖子。向自定义帖子类型动态添加标签的正确方法是什么?这些标记不是预定义的,而是由用户根据需要创建的。目前我正在做: $tags = explode(\" \", $_POST[\'post_tags\']); $new_entry = array( \'post_title\' => $_POST[\'post_title\'], \'pos