Bagaimana cara membuat daftar taksonomi anak dan bukan orangtua mereka?

9

Saya membuat menu pilih usia di admin, diisi dari taksonomi age. Taksonomi bersifat hierarkis sebagai berikut:

  • 18-25 (orang tua, ID 183)
    • 18 (anak)
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 26-30 (orang tua, ID 184)
    • 26
    • 27
    • 28
    • 29
    • 30

Saya hanya ingin mendaftarkan anak-anak (18, 19 dll) dan bukan orang tua (18-25, 26-30) dll. Saat ini saya menggunakan get_termsdengan parentargumen, tetapi tidak menerima lebih dari 1 ID orang tua. Inilah yang saya miliki sejauh ini, yang menunjukkan anak-anak dari 18-25.

    $ages = get_terms( 'age', array(
        'hide_empty' => 0,
        'parent' => '183',
    ));

Inilah yang ingin saya lakukan, tetapi tidak didukung. Saya juga sudah mencobanya dengan array tetapi tidak berhasil.

    $ages = get_terms( 'age', array(
        'hide_empty' => 0,
        'parent' => '183,184',
    ));

Saya melihat ada fungsi get_term_children tapi saya tidak yakin bagaimana cara menggunakan ini karena sepertinya hanya menerima satu nilai juga. Contoh: Dalam contoh ini ia akan membuat daftar tidak terurut tetapi saya dapat memodifikasi untuk menu pilih.

<?php
    $termID = 183;
    $taxonomyName = "age";
    $termchildren = get_term_children( $termID, $taxonomyName );

    echo '<ul>';
    foreach ($termchildren as $child) {
    $term = get_term_by( 'id', $child, $taxonomyName );
    echo '<li><a href="' . get_term_link( $term->name, $taxonomyName ) . '">' . $term->name . '</a></li>';
    }
    echo '</ul>';
?> 
Andrew
sumber
Panggil get_termsdua kali dan gabungkan dua array hasil?
Mark Duncan
@ Mark Terima kasih, saya berpikir untuk melakukannya dengan cara ini, tetapi bahkan jika saya menggabungkan ID ke dalam array, saya tidak bisa melihat bagaimana itu akan bekerja karena itu akan sama dengan mendaftar secara manual - 183, 184, yang tidak t bekerja.
Andrew
Setelah membaca jawaban yang diterima saya sekarang menyadari pertanyaan Anda tidak sepenuhnya jelas, dari penampilan Anda ingin semua istilah, tidak termasuk yang tingkat atas .. (yang dapat Anda lakukan dengan satu get_termspanggilan). Pertanyaan Anda berbunyi seolah-olah Anda menginginkan semua anak dari 2 syarat orang tua tertentu ..
Mark Duncan

Jawaban:

14

Ini seharusnya bekerja untuk Anda:

$taxonomyName = "age";
//This gets top layer terms only.  This is done by setting parent to 0.  
$parent_terms = get_terms( $taxonomyName, array( 'parent' => 0, 'orderby' => 'slug', 'hide_empty' => false ) );   
echo '<ul>';
foreach ( $parent_terms as $pterm ) {
    //Get the Child terms
    $terms = get_terms( $taxonomyName, array( 'parent' => $pterm->term_id, 'orderby' => 'slug', 'hide_empty' => false ) );
    foreach ( $terms as $term ) {
        echo '<li><a href="' . get_term_link( $term ) . '">' . $term->name . '</a></li>';   
    }
}
echo '</ul>';
Manny Fleurmond
sumber
Terima kasih @Manny, bekerja dengan baik. Saya mengambil apa yang Anda berikan dan menumbuknya ke menu pilih yang saya cari. Hal yang bagus.
Andrew
Tidak masalah. Senang itu berhasil untuk Anda.
Manny Fleurmond
1
Lihat jawaban karimhossenbux di bawah ini untuk jawaban yang jauh lebih efisien.
dotancohen
$term->nametidak valid get_term_link(), hanya menerima ID istilah, siput atau objek
Pieter Goosen
14

Anda juga bisa:

$terms = get_terms($taxonomyName);
foreach($terms as $term) {
    if ($term->parent != 0) { // avoid parent categories
        //your instructions here
    }
}

Saya mencatat bahwa orang tua memiliki bidang "induk" sama dengan 0, dan seorang anak memiliki id induknya di dalamnya.

karimhossenbux
sumber
4
Jawaban yang diterima menjalankan N get_terms () panggilan dan berjalan dalam waktu polinomial. Jawaban ini menjalankan satu panggilan get_terms () dan berjalan dalam waktu linier. Ini jawaban yang jauh lebih baik.
dotancohen
@dotancohen Anda dapat melakukan ini tanpa harus mengecualikan istilah tingkat atas pada output, Anda dapat menghapus istilah tingkat atas dengan wpse_exclude_topparameter yang ditambahkan ke argumen kueri ;-). Namun saya setuju, ini lebih cepat dari jawaban yang diterima
Pieter Goosen
1
@PieterGoosen: Terima kasih Pieter. Saya baru saja mengambil kode sumber 4.4.2 untuk string wpse_exclude_topdan exclude_toptetapi tidak menemukannya. Juga tidak google tahu tentang itu. Di mana itu didokumentasikan?
dotancohen
1
@dotancohen dalam jawaban saya ;-)
Pieter Goosen
5

Kami dapat mengecualikan orang tua tingkat atas dengan memfilter mereka menggunakan terms_clausesfilter untuk mengubah kueri SQL sebelum dijalankan. Dengan cara ini kita tidak perlu melewati orang tua di foreachloop terakhir karena mereka tidak dalam array istilah yang dikembalikan, ini menghemat pekerjaan dan pengkodean yang tidak perlu

Anda dapat mencoba yang berikut ini:

add_filter( 'terms_clauses', function (  $pieces, $taxonomies, $args )
{
    // Check if our custom arguments is set and set to 1, if not bail
    if (    !isset( $args['wpse_exclude_top'] ) 
         || 1 !== $args['wpse_exclude_top']
    )
        return $pieces;

    // Everything checks out, lets remove parents
    $pieces['where'] .= ' AND tt.parent > 0';

    return $pieces;
}, 10, 3 );

Untuk mengecualikan orang tua tingkat atas, kami sekarang dapat meneruskan 'wpse_exclude_top' => 1dengan berbagai argumen kami. wpse_exclude_topParameter baru didukung oleh filter di atas

$terms = get_terms( 'category', ['wpse_exclude_top' => 1] );
if (    $terms
     && !is_wp_error( $terms )
) {
    echo '<ul>';
        foreach ($terms as $term) {
            echo '<li><a href="' . get_term_link( $term ) . '">' . $term->name . '</a></li>';  
        }
    echo '</ul>';
}

Hanya sebuah catatan, get_term_link()jangan tidak menerima nama istilah, hanya, siput, ID atau objek istilah lengkap. Untuk kinerja, selalu selalu meneruskan objek jangka ke get_term_link()jika objek jangka tersedia ( seperti dalam kasus ini )

Pieter Goosen
sumber
2

Mengapa Anda tidak bisa mengatur childlessargumen itu menjadi benar?

$ages = get_terms( array(
    'taxonomy' => 'age',
    'childless' => true
    )
);
Yaron
sumber
mengatur childlessargumen ke true berarti Anda hanya bisa masuk 1 level, jadi ini tidak berfungsi untuk taksonomi dengan 3 level atau lebih.
GeckoSEO
-1

Jika Anda menampilkan beberapa anak orang tua, Anda dapat mencoba ini. Tampilkan sebutkan istilah id istilah anak.

$termIds = array(367, 366, 365, 364, 363, 362);
$taxonomyName = "age";

$args = array(
    'orderby'           => 'term_id', 
    'order'             => 'DESC',                      
    'hide_empty'        => false,                       
    'childless'         => false,
); 

$terms = get_terms( $taxonomyName, $args );

if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
$inc = 1;
foreach ( $terms as $term ) {                           
 if (in_array($term->parent, $termIds)) {
  echo '<option value="'.$term->term_id.'"><font><font>'.$term->name.'</font></font></option>';
    }
  }
}
Jakir Hossain
sumber
1
Tolong jelaskan mengapa menurut Anda kode ini harus bekerja. Juga, saya cukup yakin bahwa solusi hard-coded bukan cara terbaik.
s_ha_dum
Pertanyaan menyebutkan dengan id, untuk alasan ini saya telah menjawab think terkait.
Jakir Hossain