如何从类别段塞中获得子类别?

时间:2020-05-04 作者:Christhofer Natalius

所以我有这个类别结构

- Recipes
   |-- Asian Food
        |-- Chinese Food
        |-- Japanese Food
        |-- Taiwanese Food
        |-- etc...
   |-- European Food
        |-- etc...
   |-- American Food
        |-- etc...
   |-- etc...
- Articles
   |-- News
        |-- etc...
   |-- Tutorial
        |-- etc...
   |-- Gossip
   |-- etc...
如果我有分类食谱(slug:Recipes),如何直接得到它的孩子[亚洲食品、欧洲食品、美国食品]?

如果我有亚洲食品(slug:亚洲食品),如何获得(中国食品、日本食品、台湾食品)?

这就是我所尝试的。

function getChild ($slug) {
   return get_terms(\'category\', [\'parent\' => $slug]);
}

// $parentSlug = explode(\'/\', trim(parse_url($_SERVER[\'REQUEST_URI\'], PHP_URL_PATH), \'/\'))[0];
$parentSlug = \'recipes\';
$children = getChild($parentSlug); // returns blank array

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

您可以使用get_term_children() 获取术语的子项,但它只返回ID,因此您可以使用get_term_by() 将其转换为id

方法3

此方法基于WP内置的get\\u term\\u children()和\\u get\\u term\\u hierarchy(),但已转换为支持slug。这里提供了整套函数供参考。

类似内置版本,返回unlimited number of children

// this is based on WP Core, return the immediate 1 level of children
function get_term_children_in_slug( $term_slug, $taxonomy ) {
    if ( ! taxonomy_exists( $taxonomy ) ) {
        return new WP_Error( \'invalid_taxonomy\', __( \'Invalid taxonomy.\' ) );
    }

    $term_data = _get_term_hierarchy_in_slug( $taxonomy );
    $terms = $term_data[\'children\'];
    $term_slug_ids = $term_data[\'term_slug_ids\'];

    if ( ! isset( $term_slug_ids[ $term_slug ] ) ) {
        return array();
    }

    if( ! isset( $terms[ $term_slug_ids[ $term_slug ] ] ) ) {
        return array();
    }

    $children = $terms[ $term_slug_ids[ $term_slug ] ];

    // find children of children
    foreach ( (array) $terms[ $term_slug_ids[ $term_slug ] ] as $child_slug => $child_id ) {
        if ( $term_slug === $child_slug ) {
            continue;
        }

        if ( isset( $terms[ $term_slug_ids[ $child_slug ] ]) ) {
            $children = array_merge( $children, get_term_children_in_slug( $child_slug, $taxonomy ) );
        }
    }

    return $children;
}

// this is based on WP Core for get_term_children() but support slug instead
function _get_term_hierarchy_in_slug( $taxonomy ) {
    if ( ! is_taxonomy_hierarchical( $taxonomy ) ) {
        return array();
    }

    // WP Builtin with cache by saving to option, reduce performance hit
    $children = get_option( "{$taxonomy}_children_slug" );

    if ( is_array( $children ) ) {
        return $children;
    }

    $children = array();
    $terms = get_terms( \'category\', array(
        \'hide_empty\' => false,
        // \'orderby\'                => \'id\', // haven\'t used in test, optional
        \'fields\'                 => \'all_with_object_id\',
    ) );

    $term_ids = []; // as cache to find out terms parent slug
    $compare = [];

    // all parents become level 1 id => level 2 id structure
    foreach ( $terms as $key => $term ) {
        $term_ids[ $term->slug ] = $term->term_id;
        if ( $term->parent > 0 ) {
            // $compare[ $term->slug ][] = $term->parent;
            $children[ $term->parent ][$term->slug] = $term->term_id;
        } 
    }

    update_option( "{$taxonomy}_children_slug", $children );

    // children for use, term ids for matching
    return array(
        \'children\' => $children,
        \'term_slug_ids\' => $term_ids
    );
}

// add clean up cache logic together with builtin clean up
add_action( \'clean_taxonomy_cache\', \'custom_clean_up_term_cache\' );
function custom_clean_up_term_cache( $taxonomy ) {
    delete_option( "{$taxonomy}_children_slug" );
}
方法2(推荐的方法,因为它是最简单的方法)Asker将第一个答案中的get\\u term\\u by()与get\\u categories()结合使用此方法

取决于args,可以返回直系后代或包括grandchilren在内的所有子代引用posts

// this method only return 1 level of immediate children
function get_term_children_in_slug_approach2( $term_slug ) {
    $parent = get_term_by( \'slug\', $term_slug, \'category\' );
    $term_slugs = (get_categories([
        \'taxonomy\' => \'category\',
        \'parent\' => $parent->term_id,
        \'hide_empty\' => false, // in the test, have no posts
    ]));

    return $term_slugs;
}

// the following return children and grandchildren
function get_term_children_in_slug_approach2( $term_slug ) {
    $parent = get_term_by( \'slug\', $term_slug, \'category\' );
    $term_slugs = (get_categories([
        \'taxonomy\' => \'category\',
        \'child_of\' => $parent->term_id,
        \'hide_empty\' => false, // in the test, have no posts
    ]));

    return $term_slugs;
}
方法1因为WP内置工具是基于ID的,所以使用内置get\\u term\\u chilren()并不简单,需要进行ID-to-slug搜索。

返回the first immediate level of children

function getChild ( $slug ) {
    $term = get_term_by( \'slug\', $slug, \'category\' );
    $term_children = get_term_children( $term->term_id, \'category\' );

    // return a list of children id
    if( $term_children ) {
        return get_term_children( $term->term_id, \'category\' );
    }

    return $term_children;
}
获得子id列表后,可以将其转换回slug

// helper for retrieve slug from $term ID
function get_term_slug( $id ) {
    $term = get_term_by( \'id\', $id, \'category\' );
    // var_dump($term);
    if( $term ) {
        return $term->slug;
    }

    return $term;
}

// get a list of terms slug from term id
$term_slugs = [];
$term_children_ids = getChild( \'level1\' ); // example

foreach ($term_children_ids as $key => $term_id) {
    $term_slugs[] = get_term_slug( $term_id );
}

相关推荐

WIDGET_POSTS_ARGS未使用WIDGET中的帖子数

所以我用的是widget_posts_args 筛选以在核心“最近的帖子”小部件中拉入自定义帖子类型的帖子。代码如下:add_filter(\'widget_posts_args\', function() { $params[\'post_type\'] = array(\'post\', \'recipe\'); return $params; }); 因此,使用上面的过滤器,它实际上是在拉入所有的“post”和“recipe”自定义帖子类型,这是我想