get_terms custom order

时间:2015-04-17 作者:Duncan Morley

我正在使用get_terms 函数按字母顺序排列自定义分类法的所有术语。然而,我的客户现在要求将其中一个术语放在最后(因此不按字母顺序排列)。有人对如何实现这一目标的最佳方式有什么建议吗?

4 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

这可以通过您自己的自定义函数轻松完成。你要做的是,从get_terms() 它将保存您的术语对象,检查您的唯一键是否设置为参数,然后根据该设置,删除该键/对并将其添加到后面

现在,让我们将其转化为代码:(我已经对代码进行了注释,以便于理解)

这是PHP 5.5之前的版本,但仍然需要至少PHP 5.4

function get_term_to_end( $taxonomy = \'\', $args = [] )
{
    $terms = get_terms( $taxonomy, $args );

    /*
     * Return $terms if our new argument term_to_end is not set or empty
     */
    if ( !isset( $args[\'term_to_end\'] ) || empty( $args[\'term_to_end\'] ) ) 
        return $terms;

    /*
     * If term_to_end is set and has a value, continue to process
     * Return $terms if a wp error is returned or if $terms is empty
     */
    if ( is_wp_error( $terms ) || empty( $terms ) )
        return $terms;
     /*
      * We have came this far, now we can finish this off
      */
    foreach ( $terms as $term ) {
        /*
         * Check the term ids against our new argument term_to_end
         */
        if ( $term->term_id == $args[\'term_to_end\'] ) {
            $end[] = $term;
        } else {
            $terms_array[] = $term;
        }
    }
    /*
     * Merge the two arrays together, adding the term_to_end right at the back
     */
    $terms = array_merge( $terms_array, $end );

    /*
     * For uniformaty, type cast the resultant array to an object
     */
    return (object) $terms;
}
如果您使用的是PHP 5.5+,则可以使用array_searcharray_column 并跳过foreach 函数内部的循环

function get_term_to_end( $taxonomy = \'\', $args = [] )
{
    $terms = get_terms( $taxonomy, $args );

    /*
     * Return $terms if our new argument term_to_end is not set or empty
     */
    if ( !isset( $args[\'term_to_end\'] ) || empty( $args[\'term_to_end\'] ) ) 
        return $terms;

    /*
     * If term_to_end is set and has a value, continue to process
     * Return $terms if a wp error is returned or if $terms is empty
     */
    if ( is_wp_error( $terms ) || empty( $terms ) )
        return $terms;

     /*
      * We have came this far, now we can finish this off
      *
      * We need to convert the multidimensional objects to a multidimensional array. Lets used
      * json_encode and json_decode. Now we can use 
      * array_search to and array_column to determine the position of the term_to_end
      */
    $terms_array = json_decode( json_encode( $terms ), true );
    $end_term_position = array_search( $args[\'term_to_end\'], array_column( $terms_array, \'term_id\'));

    /*
     * First check if $end_term_position in not false (array_search returns false on failure), 
     * if false, return $terms
     */
    if ( !$end_term_position )
        return $terms;

    /*
     * Get the key value pair for term_to_end, unset it from $terms and reset term_to_end pair at the back
     */
    $end_term_pair[] = $terms[$end_term_position];
    unset( $terms[$end_term_position] );
    $new_terms_array = array_merge( (array) $terms, $end_term_pair );

    /*
     * We are done!! Now we can just return $new_terms_array as an object
     */
    return (object) $new_terms_array;
}
示例用例:

移动属于分类法的id为15的术语mytax 到术语数组的后面。按名称保留默认排序

$terms = get_term_to_end( \'mytax\', [\'term_to_end\' => 15] );

$args = [
    \'term_to_end\' => 15
];
$terms = get_term_to_end( \'mytax, $args );
以上几点注意事项

上面的代码都未经测试,可能有问题。我已经把这写在平板电脑上了。

对于旧版本(PHP 5.4之前),使用第一个代码块,只需更改新的数组语法([]) 到旧语法(array())

新参数,term_to_end 使用术语移动到结束术语的ID。您可以对其进行修改,以使用术语名称或术语slug,无论您需要什么。您还可以修改此选项以处理所有这些值

新函数使用的参数与get_terms(). 唯一的额外添加是term_to_end 参数

作为get_terms, 新函数返回WP_Error 对象,如果分类不存在,则返回一个ampty数组(如果未找到任何术语)。请记住,以与您相同的方式检查这些事件get_terms

如果term_to_end 参数设置后fields 参数不能设置为除all (这是默认设置)。任何其他值都将中断该函数。通过构建一些规范检查并更改foreach 在第一个代码块中或更改array_search 在第二个代码块中

如果需要,您可以很容易地更改功能,将所选术语移到前面。您还可以调整函数以接受多个要移动的术语

有关此功能使用的任何其他信息,请参阅get_terms

编辑

现在,此代码已按预期进行了测试和工作。

SO网友:Stephen S.

也许有更好的方法可以做到这一点,但您可能只需要执行两个查询。可能是这样的(未经测试):

$loner_term = X; //put whatever the id of the term you want at end
$taxonomies = \'YOUR_TAXONOMY_NAME\';
)
// get all of the alphabetical terms and exclude the one you need at the end
$alpha_args = array(
    \'orderby\' => \'name\',
    \'exclude\' => $loner_term
);
$alpha_terms = get_terms($taxonomies, $alpha_args);

// only get the term you need to come at the end
$na_args = array(
    \'include\' => $loner_term
);
$na_terms = get_terms($taxonomies, $na_args);

echo \'<ul>\';
// loop through the alphabetical terms
foreach ($alpha_terms as $alpha_term) {
    echo \'<li>\'. $alpha_term->name.\'</li>\';
}
// then loop through the loner term
foreach ($na_terms as $na_term) {
    echo \'<li>\'. $na_term->name.\'</li>\';
}    
echo \'</ul>\';
已编辑以正确使用get\\u术语!

SO网友:Dmitry Mayorov

最近我偶然发现了类似的问题。如果您对使用插件感到满意,可以安装Custom Taxonomy Sort. 尽管两年多没有更新,但它为我解决了这个问题。基本上,它允许您从仪表板手动对术语进行排序。

SO网友:Sammy Nordström

我想到的一个想法是,在分类法中添加一个名为“append”的术语,然后将要附加的术语列在术语末尾,列出该术语的子项。然后,只需进行适当的术语查询,即使用append作为其父项获取所有术语,然后在查询其余术语时将其排除。通过这种方式,您可以对这个自定义排序对象进行编辑控制,而不必将任何内容硬编码到模板中。

结束