一个分类法的术语可以按单独的分类法排序吗?

时间:2014-10-24 作者:streetfire

我需要一些建议。例如,我有一个名为“电影”的帖子类型。

在电影里面,我有两种分类法:类型和分级

根据评级,我的条件是五星、四星、三星等。

在流派下,有古典、浪漫、喜剧等。

现在,事情变得棘手了。

我有一个页面显示分类法“流派”中的术语列表。我需要做的是,根据与帖子类型中的每个帖子相关联的分级分类法,按类别对术语进行排序。因此,我需要先列出五星级流派,并按排名中拥有最多五星级帖子的术语进行排序。在这之后,我们将继续通过四星类型(按照大多数帖子有四星的顺序),到三星,等等。

此外,如果一个术语与其他术语具有相同的X星评级帖子,则可以按字母顺序排列。

如果有任何问题,请告诉我,我是否可以在这里澄清我的负担:-)

我不是PHP或MySQL专家,所以如果这是非常广泛的。我可能需要招募一些有报酬的助手来做一些事情。

1 个回复
SO网友:Pieter Goosen

正如我所说,这是可行的,但我们需要仔细规划,因为这是一项相当繁重的行动。在我的测试安装中,只有13篇文章,每个分类法有3个术语,访问db 20次,完成操作需要0.03613秒。我尝试了几种解决方案,而这一种是迄今为止最快的。

我们稍后将研究一种解决方法,以节省db调用和加载时间。首先让我们看看整个操作是什么样子以及它是如何工作的

PREPHASE

在我们开始之前,请注意几点。本规范的制定基于以下内容

每个帖子在这两种分类法中必须至少有一个术语。如果一篇文章只有一个属于这两种分类法之一的术语,那么代码将失败

在我的测试安装中,我的帖子类型是cameras, 我的分类法是brandsevent_cat, 因此,请确保相应地更改此选项

它的工作原理

STEP 1

在数组中添加分类法。这将用于获取与这两个分类法相关的所有术语

$taxonomies = [ \'event_cat\', \'brands\' ];

STEP 2

如步骤1所述,您需要按照分类法获取所有术语。get_terms() 将用于检索术语。将跳过空术语

$terms = get_terms( $taxonomy );

STEP 3

下一步是获取属于特定术语的所有职位。术语slug和分类名称将用于tax_query 在里面get_posts 检索帖子。由于您不需要任何post数据,因此只需检索post ID

$args = array(
    \'post_type\' => \'cameras\',
    \'fields\' => \'ids\',
    \'tax_query\' => array(
        array(
            \'taxonomy\' => $taxonomy,
            \'field\'    => \'slug\',
            \'terms\'    => $term->slug,
        ),
    ),
);
$posts = get_posts( $args );

STEP 4

现在将使用post ID、术语名称和分类名称创建一个数组,该数组将用于创建我们的列表

foreach ( $posts as $post ) {
    $all_posts[$post][$taxonomy] = $term->name;
}
您的创建数组将如下所示

array(13) {
  [586]=>
  array(2) {
    ["event_cat"]=>
    string(6) "3 star"
    ["brands"]=>
    string(7) "Classic"
  }
  [582]=>
  array(2) {
    ["event_cat"]=>
    string(6) "3 star"
    ["brands"]=>
    string(7) "Romance"
  }
  [331]=>
  array(2) {
    ["event_cat"]=>
    string(6) "3 star"
    ["brands"]=>
    string(7) "Classic"
  }
  [329]=>
  array(2) {
    ["event_cat"]=>
    string(6) "3 star"
    ["brands"]=>
    string(6) "Comedy"
  }
  [585]=>
  array(2) {
    ["event_cat"]=>
    string(6) "4 star"
    ["brands"]=>
    string(7) "Romance"
  }
  [583]=>
  array(2) {
    ["event_cat"]=>
    string(6) "4 star"
    ["brands"]=>
    string(7) "Romance"
  }
  [401]=>
  array(2) {
    ["event_cat"]=>
    string(6) "4 star"
    ["brands"]=>
    string(7) "Classic"
  }
  [330]=>
  array(2) {
    ["event_cat"]=>
    string(6) "4 star"
    ["brands"]=>
    string(6) "Comedy"
  }
  [328]=>
  array(2) {
    ["event_cat"]=>
    string(6) "4 star"
    ["brands"]=>
    string(6) "Comedy"
  }
  [587]=>
  array(2) {
    ["event_cat"]=>
    string(6) "5 star"
    ["brands"]=>
    string(7) "Romance"
  }
  [584]=>
  array(2) {
    ["event_cat"]=>
    string(6) "5 star"
    ["brands"]=>
    string(7) "Romance"
  }
  [581]=>
  array(2) {
    ["event_cat"]=>
    string(6) "5 star"
    ["brands"]=>
    string(6) "Comedy"
  }
  [327]=>
  array(2) {
    ["event_cat"]=>
    string(6) "5 star"
    ["brands"]=>
    string(6) "Comedy"
  }
}

STEP 5

此新数组将作为将显示的列表的基础。使用此数组要做的第一件事是使用它创建一个新数组,该数组将使用ratings 术语作为键和genre 术语作为值

$group_ratings = [];
foreach ( $all_posts as $value ) {
    $group_ratings[$value[\'event_cat\']][] = $value[\'brands\'];
}
您的$group_ratings 现在看起来像这样

array(3) {
  ["3 star"]=>
  array(4) {
    [0]=>
    string(7) "Classic"
    [1]=>
    string(7) "Romance"
    [2]=>
    string(7) "Classic"
    [3]=>
    string(6) "Comedy"
  }
  ["4 star"]=>
  array(5) {
    [0]=>
    string(7) "Romance"
    [1]=>
    string(7) "Romance"
    [2]=>
    string(7) "Classic"
    [3]=>
    string(6) "Comedy"
    [4]=>
    string(6) "Comedy"
  }
  ["5 star"]=>
  array(4) {
    [0]=>
    string(7) "Romance"
    [1]=>
    string(7) "Romance"
    [2]=>
    string(6) "Comedy"
    [3]=>
    string(6) "Comedy"
  }
}

STEP 6

因为你需要5 star 首先出现的术语和1 star 最后一个术语,我们可以使用krsort 相应地对数组排序

krsort($group_ratings);

STEP 7

现在将通过foreach 环现在将使用array_count_values, 然后,生成的数组将按数组值和键值进行排序array_multisort. 分类让我有点头疼,所以我不得不去寻求帮助。我找到了here 感谢@theark

foreach ( $group_ratings as $key=>$value ) {
    echo $key;
    $counted_values = array_count_values($value);
    array_multisort(array_values($counted_values), SORT_DESC, array_keys($counted_values), SORT_ASC, $counted_values);
//MORE TO COME

STEP 8

最后,现在可以显示列表。保存术语名称的数组键将用作术语名称,保存术语post计数的数组值将用于显示该特定术语的post计数

foreach ( $counted_values as $counted_values_keys=>$counted_value ) {
    echo \'<li>\' . $counted_values_keys . \' (\' . $counted_value . \') </li>\';
}
正如我所说,这项工作相当繁重。为了加快速度,您需要利用transients. 我们要做的是存储$group_ratings. 这是保存所有重要信息的变量

这将显著减少db调用量和加载时间。对于瞬态,仅记录2 db的点击,总时间仅为0.00098秒。请注意,我已将瞬时到期时间设置为24小时,您可以根据需要修改此时间。设置的好时机将取决于您添加新帖子的频率

ALL TOGETHER NOW!!

下面是完整代码的外观

if ( false === ( $group_ratings = get_transient( \'term_list\' ) ) ) {
    $taxonomies = [ \'event_cat\', \'brands\' ];
    $all_posts = [];
    foreach ( $taxonomies as $taxonomy ) {
        $terms = get_terms( $taxonomy );
        foreach ( $terms as $term ) {
            $args = array(
                \'post_type\' => \'cameras\',
                \'fields\' => \'ids\',
                \'tax_query\' => array(
                    array(
                        \'taxonomy\' => $taxonomy,
                        \'field\'    => \'slug\',
                        \'terms\'    => $term->slug,
                    ),
                ),
            );
            $posts = get_posts( $args );

            foreach ( $posts as $post ) {
                $all_posts[$post][$taxonomy] = $term->name;
            }
            unset($post);
        }
    }

    $group_ratings = [];
    foreach ( $all_posts as $value ) {
        $group_ratings[$value[\'event_cat\']][] = $value[\'brands\'];
    }

    krsort($group_ratings);

    set_transient( \'term_list\', $group_ratings, 24 * HOUR_IN_SECONDS );
}


echo \'<ul>\';
foreach ( $group_ratings as $key=>$value ) {
    echo $key;
    $counted_values = array_count_values($value);
    array_multisort(array_values($counted_values), SORT_DESC, array_keys($counted_values), SORT_ASC, $counted_values);

    foreach ( $counted_values as $counted_values_keys=>$counted_value ) {
        echo \'<li>\' . $counted_values_keys . \' (\' . $counted_value . \') </li>\';
    }
}
echo \'</ul>\';
您只需要根据需要对其进行样式设置和修改。下面是您的列表

enter image description here

BUT WAIT, WE\'RE NOT DONE

还有最后一步。只有在过渡期到期时,才会更新过渡期。如果在过渡期有效期间发布新帖子,这将是一个问题。您所做的更改只有在瞬态过期并更新后才会显示。

您需要做的是在发布新帖子时以某种方式删除临时帖子。可以使用transition_post_status 此处由@tosho in描述的挂钩this post

我们需要稍微修改该代码,以便仅在发布新帖子时,以及在以特定帖子类型发布新帖子时,才会删除瞬态。这就是代码的样子(进入functions.php,只需记住更改post类型名称)

add_action( \'transition_post_status\', \'a_new_post\', 10, 3 );

function a_new_post( $new_status, $old_status, $post )
{
    if ( \'publish\' !== $new_status or \'publish\' === $old_status )
        return;

    if ( \'cameras\' !== $post->post_type )
        return; // restrict the filter to a specific post type

    delete_transient( \'term_list\' );
}

WE\'RE DONE!!!

结束

相关推荐

Wacky taxonomy in wordpress

我有我的主要网站,www.whatsthatbug。com和一个测试站点test。什么是臭虫。com。据我所知,它们是相同的——相同版本的wordpress,相同版本的相同插件,相同主题,相同修改。然而。www上的category小部件显示父类别的计数,但不包括计数中的子类别,而在测试中(以及它直到最近在www上的工作方式),类别计数包括子类别的小计。和在wp管理/编辑标签中。php?分类法=www上的类别,我没有看到任何类别的子类别。这让一些事情变得困难。这意味着有些东西坏了。在测试中,子类别按其应有的

一个分类法的术语可以按单独的分类法排序吗? - 小码农CODE - 行之有效找到问题解决它

一个分类法的术语可以按单独的分类法排序吗?

时间:2014-10-24 作者:streetfire

我需要一些建议。例如,我有一个名为“电影”的帖子类型。

在电影里面,我有两种分类法:类型和分级

根据评级,我的条件是五星、四星、三星等。

在流派下,有古典、浪漫、喜剧等。

现在,事情变得棘手了。

我有一个页面显示分类法“流派”中的术语列表。我需要做的是,根据与帖子类型中的每个帖子相关联的分级分类法,按类别对术语进行排序。因此,我需要先列出五星级流派,并按排名中拥有最多五星级帖子的术语进行排序。在这之后,我们将继续通过四星类型(按照大多数帖子有四星的顺序),到三星,等等。

此外,如果一个术语与其他术语具有相同的X星评级帖子,则可以按字母顺序排列。

如果有任何问题,请告诉我,我是否可以在这里澄清我的负担:-)

我不是PHP或MySQL专家,所以如果这是非常广泛的。我可能需要招募一些有报酬的助手来做一些事情。

1 个回复
SO网友:Pieter Goosen

正如我所说,这是可行的,但我们需要仔细规划,因为这是一项相当繁重的行动。在我的测试安装中,只有13篇文章,每个分类法有3个术语,访问db 20次,完成操作需要0.03613秒。我尝试了几种解决方案,而这一种是迄今为止最快的。

我们稍后将研究一种解决方法,以节省db调用和加载时间。首先让我们看看整个操作是什么样子以及它是如何工作的

PREPHASE

在我们开始之前,请注意几点。本规范的制定基于以下内容

每个帖子在这两种分类法中必须至少有一个术语。如果一篇文章只有一个属于这两种分类法之一的术语,那么代码将失败

在我的测试安装中,我的帖子类型是cameras, 我的分类法是brandsevent_cat, 因此,请确保相应地更改此选项

它的工作原理

STEP 1

在数组中添加分类法。这将用于获取与这两个分类法相关的所有术语

$taxonomies = [ \'event_cat\', \'brands\' ];

STEP 2

如步骤1所述,您需要按照分类法获取所有术语。get_terms() 将用于检索术语。将跳过空术语

$terms = get_terms( $taxonomy );

STEP 3

下一步是获取属于特定术语的所有职位。术语slug和分类名称将用于tax_query 在里面get_posts 检索帖子。由于您不需要任何post数据,因此只需检索post ID

$args = array(
    \'post_type\' => \'cameras\',
    \'fields\' => \'ids\',
    \'tax_query\' => array(
        array(
            \'taxonomy\' => $taxonomy,
            \'field\'    => \'slug\',
            \'terms\'    => $term->slug,
        ),
    ),
);
$posts = get_posts( $args );

STEP 4

现在将使用post ID、术语名称和分类名称创建一个数组,该数组将用于创建我们的列表

foreach ( $posts as $post ) {
    $all_posts[$post][$taxonomy] = $term->name;
}
您的创建数组将如下所示

array(13) {
  [586]=>
  array(2) {
    ["event_cat"]=>
    string(6) "3 star"
    ["brands"]=>
    string(7) "Classic"
  }
  [582]=>
  array(2) {
    ["event_cat"]=>
    string(6) "3 star"
    ["brands"]=>
    string(7) "Romance"
  }
  [331]=>
  array(2) {
    ["event_cat"]=>
    string(6) "3 star"
    ["brands"]=>
    string(7) "Classic"
  }
  [329]=>
  array(2) {
    ["event_cat"]=>
    string(6) "3 star"
    ["brands"]=>
    string(6) "Comedy"
  }
  [585]=>
  array(2) {
    ["event_cat"]=>
    string(6) "4 star"
    ["brands"]=>
    string(7) "Romance"
  }
  [583]=>
  array(2) {
    ["event_cat"]=>
    string(6) "4 star"
    ["brands"]=>
    string(7) "Romance"
  }
  [401]=>
  array(2) {
    ["event_cat"]=>
    string(6) "4 star"
    ["brands"]=>
    string(7) "Classic"
  }
  [330]=>
  array(2) {
    ["event_cat"]=>
    string(6) "4 star"
    ["brands"]=>
    string(6) "Comedy"
  }
  [328]=>
  array(2) {
    ["event_cat"]=>
    string(6) "4 star"
    ["brands"]=>
    string(6) "Comedy"
  }
  [587]=>
  array(2) {
    ["event_cat"]=>
    string(6) "5 star"
    ["brands"]=>
    string(7) "Romance"
  }
  [584]=>
  array(2) {
    ["event_cat"]=>
    string(6) "5 star"
    ["brands"]=>
    string(7) "Romance"
  }
  [581]=>
  array(2) {
    ["event_cat"]=>
    string(6) "5 star"
    ["brands"]=>
    string(6) "Comedy"
  }
  [327]=>
  array(2) {
    ["event_cat"]=>
    string(6) "5 star"
    ["brands"]=>
    string(6) "Comedy"
  }
}

STEP 5

此新数组将作为将显示的列表的基础。使用此数组要做的第一件事是使用它创建一个新数组,该数组将使用ratings 术语作为键和genre 术语作为值

$group_ratings = [];
foreach ( $all_posts as $value ) {
    $group_ratings[$value[\'event_cat\']][] = $value[\'brands\'];
}
您的$group_ratings 现在看起来像这样

array(3) {
  ["3 star"]=>
  array(4) {
    [0]=>
    string(7) "Classic"
    [1]=>
    string(7) "Romance"
    [2]=>
    string(7) "Classic"
    [3]=>
    string(6) "Comedy"
  }
  ["4 star"]=>
  array(5) {
    [0]=>
    string(7) "Romance"
    [1]=>
    string(7) "Romance"
    [2]=>
    string(7) "Classic"
    [3]=>
    string(6) "Comedy"
    [4]=>
    string(6) "Comedy"
  }
  ["5 star"]=>
  array(4) {
    [0]=>
    string(7) "Romance"
    [1]=>
    string(7) "Romance"
    [2]=>
    string(6) "Comedy"
    [3]=>
    string(6) "Comedy"
  }
}

STEP 6

因为你需要5 star 首先出现的术语和1 star 最后一个术语,我们可以使用krsort 相应地对数组排序

krsort($group_ratings);

STEP 7

现在将通过foreach 环现在将使用array_count_values, 然后,生成的数组将按数组值和键值进行排序array_multisort. 分类让我有点头疼,所以我不得不去寻求帮助。我找到了here 感谢@theark

foreach ( $group_ratings as $key=>$value ) {
    echo $key;
    $counted_values = array_count_values($value);
    array_multisort(array_values($counted_values), SORT_DESC, array_keys($counted_values), SORT_ASC, $counted_values);
//MORE TO COME

STEP 8

最后,现在可以显示列表。保存术语名称的数组键将用作术语名称,保存术语post计数的数组值将用于显示该特定术语的post计数

foreach ( $counted_values as $counted_values_keys=>$counted_value ) {
    echo \'<li>\' . $counted_values_keys . \' (\' . $counted_value . \') </li>\';
}
正如我所说,这项工作相当繁重。为了加快速度,您需要利用transients. 我们要做的是存储$group_ratings. 这是保存所有重要信息的变量

这将显著减少db调用量和加载时间。对于瞬态,仅记录2 db的点击,总时间仅为0.00098秒。请注意,我已将瞬时到期时间设置为24小时,您可以根据需要修改此时间。设置的好时机将取决于您添加新帖子的频率

ALL TOGETHER NOW!!

下面是完整代码的外观

if ( false === ( $group_ratings = get_transient( \'term_list\' ) ) ) {
    $taxonomies = [ \'event_cat\', \'brands\' ];
    $all_posts = [];
    foreach ( $taxonomies as $taxonomy ) {
        $terms = get_terms( $taxonomy );
        foreach ( $terms as $term ) {
            $args = array(
                \'post_type\' => \'cameras\',
                \'fields\' => \'ids\',
                \'tax_query\' => array(
                    array(
                        \'taxonomy\' => $taxonomy,
                        \'field\'    => \'slug\',
                        \'terms\'    => $term->slug,
                    ),
                ),
            );
            $posts = get_posts( $args );

            foreach ( $posts as $post ) {
                $all_posts[$post][$taxonomy] = $term->name;
            }
            unset($post);
        }
    }

    $group_ratings = [];
    foreach ( $all_posts as $value ) {
        $group_ratings[$value[\'event_cat\']][] = $value[\'brands\'];
    }

    krsort($group_ratings);

    set_transient( \'term_list\', $group_ratings, 24 * HOUR_IN_SECONDS );
}


echo \'<ul>\';
foreach ( $group_ratings as $key=>$value ) {
    echo $key;
    $counted_values = array_count_values($value);
    array_multisort(array_values($counted_values), SORT_DESC, array_keys($counted_values), SORT_ASC, $counted_values);

    foreach ( $counted_values as $counted_values_keys=>$counted_value ) {
        echo \'<li>\' . $counted_values_keys . \' (\' . $counted_value . \') </li>\';
    }
}
echo \'</ul>\';
您只需要根据需要对其进行样式设置和修改。下面是您的列表

enter image description here

BUT WAIT, WE\'RE NOT DONE

还有最后一步。只有在过渡期到期时,才会更新过渡期。如果在过渡期有效期间发布新帖子,这将是一个问题。您所做的更改只有在瞬态过期并更新后才会显示。

您需要做的是在发布新帖子时以某种方式删除临时帖子。可以使用transition_post_status 此处由@tosho in描述的挂钩this post

我们需要稍微修改该代码,以便仅在发布新帖子时,以及在以特定帖子类型发布新帖子时,才会删除瞬态。这就是代码的样子(进入functions.php,只需记住更改post类型名称)

add_action( \'transition_post_status\', \'a_new_post\', 10, 3 );

function a_new_post( $new_status, $old_status, $post )
{
    if ( \'publish\' !== $new_status or \'publish\' === $old_status )
        return;

    if ( \'cameras\' !== $post->post_type )
        return; // restrict the filter to a specific post type

    delete_transient( \'term_list\' );
}

WE\'RE DONE!!!

相关推荐

如何在使用wp_set_Object_Terms时返回新添加的术语

我正在使用wp\\u set\\u object\\u terms向我们的WooCommerce产品添加术语(属性):wp_set_object_terms($id, array($migrate_case), \'pa_case\'); 这为我们提供了自动创建不存在的术语的优势(而不是使用wp\\u set\\u post\\u terms)。有没有办法让wp\\u set\\u object\\u terms()告诉我是否必须创建新的术语?提前感谢您的帮助。