get_terms nu va afișa product_cat sau alte taxonomii personalizate când sunt specificate
Mă întreb dacă ați putea avea câteva idei despre această problemă. Am căutat pe Google zile întregi dar nu pot găsi o soluție.
Iată unde mă aflu:
Am o meta box pentru tipul de postare 'products' din Woocommerce. În interiorul meta box există un 'type' => 'select'
pe care vreau să-l populez cu o listă a tuturor 'taxonomy' => 'product_cat'
disponibile.
Pot face caseta de selectare să se populeze și să funcționeze cu categoriile standard de postări, 'taxonomy' => 'category'
folosind următorul cod:
function product_cats() {
$options = array();
$categories = get_terms( array( 'taxonomy' => 'category' ) );
foreach( $categories as $category ) {
$options[$category->term_id] = array(
'label' => $category->name,
'value' => $category->slug
);
}
// returnează array('options'=>$options);
return $options;
}
Totul se strică însă când încerc să folosesc 'taxonomy' => 'product_cat'
sau orice altă taxonomie personalizată pe care o am.
Am crezut că problema era că încerc să accesez taxonomia personalizată înainte de a fi înregistrată, așa că am schimbat ordinea unor declarații/apeluri în fișierul function.php (cele care apelează CPT, meta boxes și woocommerce) pentru a schimba potențial ordinea în care rulează lucrurile, dar fără succes.
DAR, bazat pe întrebarea și răspunsul de mai jos, pot confirma acum că funcția poate 'vedea' și afișa toate termenele, în toate taxonomiile. Dacă exclud 'taxonomy =>'
din argumente, returnează termeni din toate tipurile de postări personalizate și taxonomii.
În mod ideal funcția de bază ar arăta așa:
function product_cats() {
$options = array();
$categories = get_terms( array( 'taxonomy' => 'product_cat' ) );
foreach( $categories as $category ) {
$options[$category->term_id] = array(
'label' => $category->name,
'value' => $category->slug
);
}
// returnează array('options'=>$options);
return $options;
}
Mă întrebam dacă aveți vreo părere generală? Știu că e dificil fără a vedea întreaga bază de cod, dar m-am gândit că merită să întreb.
Versiune WordPress 4.7.2
Versiune WooCommerce 2.6.14
ACTUALIZARE:
Încet încerc să-mi localizez problema.
Se pare că 'product_cat'
poate fi accesat până la urmă (bine) dar returnează un array care nu se afișează corect.
Acest lucru mă confuză deoarece dacă folosesc simplu get_terms()
fără parametri, sau specificând 'taxonomy' => 'category'
codul de mai sus funcționează perfect
Celelalte bucăți de cod cu care trebuie să lucrez sunt:
Array-ul în care aș dori să se afișeze lista de opțiuni
array(
'label'=> 'Colecții',
'desc' => 'Selectați colecția pe care doriți să o afișați',
'id' => $prefix.'collection',
'type' => 'select',
'options' => product_cats()
),
codul care generează lista de selectare (folosit pentru alte câmpuri meta)
// select
case 'select':
echo '<select name="'.$field['id'].'" id="'.$field['id'].'">';
foreach ($field['options'] as $option) {
echo '<option', $meta == $option['value'] ? ' selected="selected"' : '', ' value="'.$option['value'].'">'.$option['label'].'</option>';
}
echo '</select><br /><span class="description">'.$field['desc'].'</span>';
break;
Nu am nicio problemă cu alte câmpuri meta care funcționează sau se afișează, inclusiv listele de selectare.
Mai degrabă nu aș rescrie întreaga meta box cu toate câmpurile sale, așa că încerc să lucrez cu ce am în acest moment.

Probabil rulezi o versiune veche de WordPress (anterioră versiunii 4.5).
Înainte de WordPress 4.5.0, primul parametru al funcției get_terms() era o taxonomie sau o listă de taxonomii, iar începând cu versiunea 4.5.0, taxonomiile trebuie transmise prin argumentul 'taxonomy' în tabloul $args (așa cum faci tu, ar trebui să funcționeze astfel).
Găsești toate detaliile despre aceste modificări pe pagina de referință get_terms().
ACTUALIZARE: Scuze, am verificat codul meu și am folosit get_categories() nu get_terms, și așa este, get_terms() nu funcționează!
Iată un exemplu funcțional pentru a lista toate categoriile de produse (product_cat):
$product_categories = get_categories( array(
'taxonomy' => 'product_cat',
'orderby' => 'name',
'pad_counts' => false,
'hierarchical' => 1,
'hide_empty' => false
) );
Sper că te ajută!

Versiunea WordPress este: Versiunea 4.7.2 (Voi adăuga mai multe detalii la problemele inițiale)

fără succes, dacă vrei să adaugi un meta_box pe ecranul de editare al produsului, folosești acțiunea add_meta_boxes sau altă acțiune pentru a declanșa add_meta_box() ?

folosesc add_meta_boxes
. Nu cred că e o problemă cu meta box-ul ci mai degrabă cu accesarea termenilor product_cat

După cum ți-a spus Dave Romsey în comentariu, ar trebui să funcționeze, funcționează și la mine.

Pentru viața mea, chiar vreau să fac asta să funcționeze corect. Dar, la naiba, nu reușesc să înțeleg cum să integrez.
Anterior, m-am uitat la wp_dropdown_categories()
și am crezut că ar fi o soluție mai bună (și mai ușoară). Am ajuns să lucrez la problema de mai sus pentru că nu am reușit să înțeleg cum să o fac să funcționeze cu sintaxa existentă a cutiei meta.
Pentru moment, am optat pentru soluția temporară găsită mai jos. Nu este ideală și cu siguranță nu cea mai bună metodă, dar îmi permite să avansez în utilizarea valorilor în șabloanele care vor folosi acest câmp.
// Încapsulează toate categoriile într-o funcție
function product_cats() {
$output = array();
$categories = get_terms( array(
'orderby' => 'name',
'pad_counts' => false,
'hierarchical' => 1,
'hide_empty' => true,
) );
foreach( $categories as $category ) {
if ($category->taxonomy == 'product_cat' ) {
$output[$category->slug] = array(
'label' => $category->name,
'value' => $category->slug
);
}
}
//return array('options'=>$output);
return $output;
}
Voi actualiza pe măsură ce avansez.

Probabil că nu va rezolva problema, dar am vrut să împărtășesc: Am întâlnit aceeași problemă astăzi și a fost cauzată de faptul că nu aveam niciun produs în categoriile mele. Dacă și în cazul tău este așa, asigură-te să adaugi 'hide_empty' => false
.
Cu toate acestea. Când apelezi get_terms()
fără niciun argument. Care este rezultatul?

Adăugarea opțiunii 'hide_empty' => false
nu ajută deloc.
În ceea ce privește rularea funcției get_terms()
fără niciun argument, nici măcar specificând taxonomia, obțin o listă masivă a TOȚI termenilor, din toate taxonomiile în care apar (inclusiv product_cat
pe care încerc să-l accesez).
Ceea ce mă face să mă întreb care este problema, deoarece se pare că 'vede' categoriile de produse până la urmă.
Va trebui să fac câteva teste pentru a verifica dacă acestea apar cu adevărat.

Iată un exemplu complet funcțional al unei căsuțe meta care afișează o listă derulantă cu categorii de produse. Căsuța meta va apărea pe tipul de postare "product".
add_action( 'add_meta_boxes', 'wpse256897_add_meta_box' );
add_action( 'save_post', 'wpse256897_save' );
/**
* Adaugă containerul căsuței meta.
*/
function wpse256897_add_meta_box( $post_type ) {
// Limităm căsuța meta la anumite tipuri de postări.
$post_types = array( 'product' );
if ( in_array( $post_type, $post_types ) ) {
add_meta_box(
'product_cat_selection',
__( 'Selectare categorie produs', 'textdomain' ),
'wpse256897_render_meta_box_content',
$post_type,
'advanced',
'high'
);
}
}
/**
* Salvează metadatele când postarea este salvată.
*
* @param int $post_id ID-ul postării care se salvează.
*/
function wpse256897_save( $post_id ) {
/*
* Trebuie să verificăm că această acțiune vine de pe ecranul nostru și cu autorizația corespunzătoare,
* deoarece save_post poate fi declanșat în alte momente.
*/
// Verifică dacă nonce-ul nostru este setat.
if ( ! isset( $_POST['myplugin_inner_custom_box_nonce'] ) ) {
return $post_id;
}
$nonce = $_POST['myplugin_inner_custom_box_nonce'];
// Verifică dacă nonce-ul este valid.
if ( ! wp_verify_nonce( $nonce, 'myplugin_inner_custom_box' ) ) {
return $post_id;
}
/*
* Dacă aceasta este o salvare automată, formularul nostru nu a fost trimis,
* așa că nu vrem să facem nimic.
*/
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Verifică permisiunile utilizatorului.
if ( 'page' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
/* OK, acum este sigur să salvăm datele. */
// Curăță input-ul utilizatorului.
$mydata = sanitize_text_field( $_POST['product_cat_selection'] );
// Actualizează câmpul meta.
update_post_meta( $post_id, '_product_cat_selection', $mydata );
}
/**
* Randare conținut căsuță meta.
*
* @param WP_Post $post Obiectul post.
*/
function wpse256897_render_meta_box_content( $post ) {
// Adaugă un câmp nonce pentru a-l putea verifica mai târziu.
wp_nonce_field( 'myplugin_inner_custom_box', 'myplugin_inner_custom_box_nonce' );
// Folosește get_post_meta pentru a prelua o valoare existentă din baza de date.
$current_product_cat = get_post_meta( $post->ID, '_product_cat_selection', true );
// Afișează formularul, folosind valoarea curentă.
$product_cats = wpse256897_product_cats();
if ( !empty ( $product_cats ) ) {
echo '<select name="product_cat_selection" id="product_cat_selection">';
foreach ( $product_cats as $product_cat_id => $product_cat ) { ?>
<option value="<?php echo esc_attr( $product_cat['value'] ); ?>" <?php if ( isset ( $current_product_cat ) ) selected( $current_product_cat, $product_cat['value'] ); ?>><?php echo esc_html( $product_cat['label'] ); ?></option><?php
}
echo '</select>';
}
}
function wpse256897_product_cats() {
$options = array();
$categories = get_terms( array( 'taxonomy' => 'product_cat' ) );
foreach( $categories as $category ) {
$options[$category->term_id] = array(
'label' => $category->name,
'value' => $category->slug
);
}
return $options;
}
Acesta nu este cel mai elegant exemplu (convențiile de denumire ar putea fi mai bune). A fost adaptat rapid din notele contribuite pe pagina de referință Add Meta Box, dar demonstrează că funcția wpse256897_product_cats()
obține categoriile de produse și că acestea pot fi salvate și afișate într-o listă derulantă pe pagina de produs în cadrul unei căsuțe meta.
Aș mai adăuga că ar putea fi util să verificați funcția wp_dropdown_categories()
. Care, în ciuda numelui, funcționează și cu taxonomii personalizate. Acest lucru v-ar scuti de crearea propriului markup pentru lista derulantă de categorii.
Actualizare:
Se pare că structura array-ului returnat de funcția product_cats()
nu se potrivește cu implementarea căsuței meta. Observați că în exemplul meu de mai sus, am folosit această linie pentru a parcurge categoriile la generarea opțiunilor pentru elementul select:
foreach ( $product_cats as $product_cat_id => $product_cat ) { ?>
Acest lucru se întâmplă deoarece $product_cats
este un array asociativ de ID-uri de categorii, fiecare conținând un alt array cu label
și slug
pentru fiecare ID de categorie.
Se pare că ați putea folosi această versiune alternativă a funcției product_cats()
care formatează valoarea returnată $options într-un mod compatibil cu codul căsuței meta:
function product_cats_alternate() {
$options = array();
$categories = get_terms( array( 'taxonomy' => 'product_cat' ) );
foreach( $categories as $category ) {
$options[] = array(
'label' => $category->name,
'value' => $category->slug
);
}
return $options;
}

Mulțumesc, Dave. Acest lucru m-a ajutat să înțeleg mai bine care este problema mea reală (am actualizat postul original). Aș prefera să nu fiu nevoit să actualizez întreaga mea cutie meta (deși dacă trebuie, o voi face), dar încerc să lucrez cu ce am la momentul actual. Mulțumesc că m-ai ajutat să înțeleg.
notă: Am încercat wp_dropdown_categories, dar am avut și mai multe dificultăți în a-l face să populeze o listă de selectare.
