Получить прямых потомков пользовательской таксономии
Я много гуглил и старался изо всех сил, но я просто не могу заставить работать детей первого уровня пользовательской таксономии в приведенном ниже коде! Он отображает только родительский уровень. Чего я пытаюсь добиться, так это следующего:
Level 1 <--- at the moment, it only displays this level
Level 2 <-- I want to display this level too
Level 3 <-- but NOT this level
Это мой код до сих пор:
function my_dropdown_categories( $taxonomy, $current_selected = '', $include = null ) {
// Get all terms of the chosen taxonomy
$terms = get_terms($taxonomy, array('orderby' => 'name'));
// our content variable
$list_of_terms = '<select id="location" class="selectboxSingle" name="location">';
if ( ! is_wp_error( $terms ) ) foreach($terms as $term){
// If include array set, exclude unless in array.
if ( is_array( $include ) && ! in_array( $term->slug, $include ) ) continue;
$select = ($current_selected == $term->slug) ? "selected" : ""; // Note: ==
if ($term->parent == 0 ) {
// get children of current parent.
// $tchildren = get_term_children($term->term_id, $taxonomy); <- gets ALL children
$uchildren =get_terms( $taxonomy, array('hide_empty' => 0, 'parent' => $term->term_id ));
$children = array();
foreach ($uchildren as $child) {
$cterm = get_term_by( 'id', $child, $taxonomy );
// If include array set, exclude unless in array.
if ( is_array( $include ) && ! in_array( $cterm->slug, $include ) ) continue;
$children[$cterm->name] = $cterm;
}
ksort($children);
// PARENT TERM
if ($term->count > 0) {
$list_of_terms .= '<option class ="group-result" value="'.$term->slug.'" '.$select.'>' . $term->name .' </option>';
} else {
$list_of_terms .= '<option value="'.$term->slug.'" '.$select.'>'. $term->name .' </option>';
};
// now the CHILDREN.
foreach($children as $child) {
$select = ($current_selected == $child->slug) ? "selected" : ""; // Note: child, not cterm
$list_of_terms .= '<option class="result-sub" value="'.$child->slug.'" '.$select.'>'. $child->name.' </option>';
} //end foreach
}
}
$list_of_terms .= '</select>';
return $list_of_terms;
}
Если кто-нибудь сможет помочь мне с этим зверем, ты будешь моим чертовым героем!
РЕДАКТИРОВАТЬ (дополнительная информация основана на ответе Питера):
Это то, что выводится (все родители):
Родитель 1
--Родитель 1
--Родитель 2
--Родитель 3
--Родитель 4
Родитель 2
--Родитель 2
--Родитель 1
--Родитель 3
И т.д.
2 answers
У вас здесь две проблемы, одна из которых связана с производительностью, другая - большая проблема, которая должна возвращать кучу ошибок, если вы включите отладку
Проблема с производительностью здесь - ваш первый случай, когда вы получаете условия. Похоже, что ваша цель здесь - получить только условия высшего уровня, но вы получаете все. Я бы просто добавил 'parent' => 0
к аргументам, чтобы получить только термины верхнего уровня. Затем вы можете удалить условие, в котором вы проверяете if ( $term->parent == 0 )
, потому что все термины будут терминами верхнего уровня, которые будут у всех есть 0
в качестве родителя термина, поэтому это условие всегда будет возвращать значение true
Ваша большая проблема связана с этим кодом, и я не понимаю вашей логики здесь
$uchildren =get_terms( $taxonomy, array('hide_empty' => 0, 'parent' => $term->term_id ));
$children = array();
foreach ($uchildren as $child) {
$cterm = get_term_by( 'id', $child, $taxonomy );
// If include array set, exclude unless in array.
if ( is_array( $include ) && ! in_array( $cterm->slug, $include ) ) continue;
$children[$cterm->name] = $cterm;
}
ksort($children);
Вы правы, получив своих прямых детей, поэтому ваше заявление о $uchildren
в порядке. С этого момента все идет наперекосяк
Почему вы используете
get_term_by()
здесь.$child
уже содержит свойства термина, как вы использовалиget_terms()
для извлечения терминов.Ты не такой просто неправильно используйте здесь
get_term_by()
, но ваши аргументы недействительны, и вы также передаете ему полный объект. Вы должны проконсультироваться с кодексом для правильного использования этой функции. В общем, этот раздел следует удалить из вашего кода
Этот раздел должен выглядеть примерно так
$uchildren =get_terms( $taxonomy, array('hide_empty' => 0, 'parent' => $term->term_id ));
$children = array();
foreach ($uchildren as $child) {
if ( is_array( $include ) && ! in_array( $child->slug, $include ) ) continue;
$children[$child->name] = $child;
}
ksort($children);
РЕДАКТИРОВАТЬ
Вот полный рабочий код с исправленной парой ошибок. Пожалуйста, смотрите мои комментарии в коде для обновлений
function my_dropdown_categories( $taxonomy, $current_selected = '', $include = null )
{
/*
* Declare your variable first. Without this, your code has a bug if no terms are found
*/
$list_of_terms = '';
/**
* Get all parent terms. Note we use 'parent' => 0 to only get top level terms
*
* @see get_terms
* @link http://codex.wordpress.org/Function_Reference/get_terms
*/
$terms = get_terms( $taxonomy, array( 'orderby' => 'name', 'parent' => 0 ) );
/*
* Use curlies here to enclose your statement. Also, check whether or not you have terms
*/
if ( $terms && ! is_wp_error( $terms ) ) {
/*
* Moved this section inside your if statement. We don't want to display anything on empty terms
*/
$list_of_terms .= '<select id="location" class="selectboxSingle" name="location">';
foreach ( $terms as $term ) {
// If include array set, exclude unless in array.
if ( is_array( $include ) && ! in_array( $term->slug, $include ) ) continue;
$select = ($current_selected == $term->slug) ? "selected" : ""; // Note: ==
/*
* Use the parent term term id as parent to get direct children of the term
* Use child_of if you need to get all descendants of a term
*/
$uchildren = get_terms( $taxonomy, array('hide_empty' => 0, 'parent' => $term->term_id ));
$children = array();
foreach ($uchildren as $child) {
// If include array set, exclude unless in array.
if ( is_array( $include ) && ! in_array( $child->slug, $include ) ) continue;
$children[$child->name] = $child;
}
ksort($children);
// PARENT TERM
if ($term->count > 0) {
$list_of_terms .= '<option class ="group-result" value="'.$term->slug.'" '.$select.'>' . $term->name .' </option>';
} else {
$list_of_terms .= '<option value="'.$term->slug.'" '.$select.'>'. $term->name .' </option>';
};
// now the CHILDREN.
foreach($children as $child) {
$select = ($current_selected == $child->slug) ? "selected" : ""; // Note: child, not cterm
$list_of_terms .= '<option class="result-sub" value="'.$child->slug.'" '.$select.'>'. $child->name.' </option>';
} //end foreach
}
/*
* Moved this section inside your if statement. We don't want to display anything on empty terms
*/
$list_of_terms .= '</select>';
}
return $list_of_terms;
}
Проверьте этот код
$uchildren =get_terms( 'category', array('hide_empty' => false, 'parent' => $term->term_id ));
$children = array();
foreach ($uchildren as $child) {
$cterm = get_term_by( 'id', $child, $taxonomy );
// If include array set, exclude unless in array.
if ( is_array( $include ) && ! in_array( $cterm->slug, $include ) ) continue;
$children[$cterm->name] = $cterm;
}
Эта строка
$cterm = get_term_by( 'id', $child, $taxonomy );
Предполагает, что $child будет идентификатором (и целым числом), тогда как:
foreach ($uchildren as $child) {
Это также является причиной того, что это работает не так, как вы хотите:
if ( is_array( $include ) && ! in_array( $cterm->slug, $include ) ) continue;
Отсюда мусор, который я разместил, но здравый смысл возобладал, пока...
Давайте сделаем самую забавную часть:
var_dump($term):
Обратите внимание на тип каждого свойства:
object(stdClass)(9) {
...
["parent"]=>
string(1) "0"
...
}
Смотрите parent
. Это строка. Я знаю, логически это должно быть целое число, но это строка. Это отстой, верно!
Итак, ваше условие if ($term->parent == 0 ) {
не выполняется. Попробуйте вместо этого:
if ( empty( $term->parent ) ) {
Здесь