【问题标题】:Determine lowest level taxonomy term确定最低级别的分类术语
【发布时间】:2023-03-04 14:09:01
【问题描述】:

我有一个自定义的“位置”分类法,分为 3 个级别:城市 -> 地区 -> 郊区。

当访问带有城市、地区和郊区标签的单个帖子时,我还想检索附近的帖子。这意味着,同一郊区的其他帖子。

这给了我分配给帖子的所有位置术语:

$terms = wp_get_post_terms( $wp_query->post->ID, 'location' );

我发现如果一个术语的父级等于 0,它是一个城市(顶级)。

foreach ( $terms as $term ) {
    if ( $term->parent == 0 ) {

        //$term is a city

    }
}

我的问题是:如何确定哪个术语是郊区(最低级别)?

【问题讨论】:

  • 我有一个想法:使用 count 属性来比较所有的术语。用得少的一定是郊区。但是如果一个地区只有一个郊区呢?两者的计数相同

标签: wordpress custom-taxonomy


【解决方案1】:

我通过计算每个术语的祖先来解决这个问题。

使用 get_ancestors() 函数,您可以获得一个数组,其中包含层次结构中从最低到最高的父级。

这对我有用:

$terms = wp_get_post_terms( get_queried_object_id(), 'location', array( 'orderby' => 'id', 'order' => 'DESC' ) );

$deepestTerm = false;
$maxDepth = -1;

foreach ($terms as $term) {
    $ancestors = get_ancestors( $term->term_id, 'location' );
    $termDepth = count($ancestors);

    if ($termDepth > $maxDepth) {
        $deepestTerm = $term;
        $maxDepth = $termDepth;
    }
}

echo '<pre>';
print_r($deepestTerm);
echo '</pre>';

【讨论】:

    【解决方案2】:

    遇到了同样的问题,但更普遍。情况是一个未知的深度,在第一层选择了多个术语。这是我解决它的方法:

    function get_lowest_taxonomy_terms( $terms ) {
        // if terms is not array or its empty don't proceed
        if ( ! is_array( $terms ) || empty( $terms ) ) {
            return false;
        }
    
        $filter = function($terms) use (&$filter) {
    
            $return_terms = array();
            $term_ids = array();
    
            foreach ($terms as $t){
                $term_ids[] = $t->term_id;
            }
    
            foreach ( $terms as $t ) {
                if( $t->parent == false || !in_array($t->parent,$term_ids) )  {
                    //remove this term
                }
                else{
                    $return_terms[] = $t;
                }
            }
    
            if( count($return_terms) ){
                return $filter($return_terms);  
            }
            else {
                return $terms;
            }
    
        };
    
        return $filter($terms);
    }
    

    该函数使用递归返回具有最低级别的术语。在每次迭代中,它会删除没有父项(级别 1)的项和不再包含在过滤项集(级别 > 1)中的父项。递归结束时有一个空集并返回上一次迭代的结果。

    我的电话应该是这样的:

    get_lowest_taxonomy_terms(get_the_terms( get_the_ID(), 'item_location'));
    

    【讨论】:

      【解决方案3】:

      这是我的简单解决方案。试试这个兄弟!

      // Initialize variable
      $result = array();
      $getParentKeyInArray = array();
      
      // Get the terms
      $terms = get_the_terms($post_id, $taxonomy);
      
      // Check if $terms is not empty
      if($terms != null) :
      
          // Get all parent key in the array and add them inside another array
          foreach($terms as $term) :
              $getParentKeyInArray[] = $term->parent;
          endforeach;
      
          // Next, loop again and this time check if a category ID is not in 
          // $getParentKeyInArray if not then that's the lowest level taxonomy term
          foreach ($terms as $term) :
               if( !in_array($term->term_id, $getParentKeyInArray) ) :
                   $result = $term;
               endif;
          endforeach;
      
      endif;
      
      // Check the result
      echo '<pre>';
      print_r($result);
      echo '</pre>';
      

      祝你有美好的一天!

      【讨论】:

        【解决方案4】:

        这就是 ID 一词在父、子和孙子之间的工作方式。举个例子,在你的问题中,你有一个属于这三个的帖子,

        城市 -> 地区 -> 郊区

        city 的 ID 编号将低于 region,而 region 的 ID 编号将低于 suburb

        考虑到这一点,按照 ID 倒序排列您的术语,首先是最高 ID。看wp_get_post_terms。您执行以下操作

        $terms = wp_get_post_terms( get_queried_object_id(), 'location', array( 'orderby' => 'id', 'order' => 'DESC' ) );
        

        然后您可以获取该数组中的第一个条目,这将是您的孙词或最深层次词,即具有最高 ID 的词

        【讨论】:

        • 请看我的更新。完全忘了order参数,语法错误
        • 这个答案是错误的,因为不能保证层次结构中较低级别的术语具有比其父级更高的 ID。
        • 错误答案!正如@rocknrollcanneverdie 所写。
        猜你喜欢
        • 2021-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-15
        • 1970-01-01
        相关资源
        最近更新 更多