web-dev-qa-db-fra.com

get_terms n'affichera pas product_cat ni aucune autre taxonomies personnalisées, le cas échéant

Vous vous demandez si vous pourriez avoir des idées sur ce problème. Je suis googlé pendant des jours mais je ne peux pas le comprendre.

Voici où je suis:

J'ai une boîte à méta pour les produits de type poste Woocommerce. Dans la boîte à méta, il y a un 'type' = > 'select' que je veux renseigner avec une liste de tous les 'taxonomy' = > 'product_cat' disponibles.

Je peux obtenir la boîte de sélection à remplir et utiliser les catégories de publication standard, 'taxonomy' = > 'category', à l'aide du code suivant:

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
    );
}
// return array('options'=>$options);
return $options;
}

Tout tombe en morceaux cependant lorsque j'essaie d'utiliser ‘taxonomy' = > ‘product_cat’ ou toute autre taxonomie personnalisée que j'ai.

Je pensais que le problème était que j'essayais d'accéder à la taxonomie personnalisée avant son enregistrement. J'ai donc permuté certaines déclarations/appels dans mon fichier function.php (ceux qui appellent le CPT, les méta-boîtes et woocommece) pour potentiellement changer. l'ordre dans lequel les choses se passent mais pas de chance.

MAIS, sur la base de la question et de la réponse ci-dessous, je peux maintenant confirmer que la fonction peut "voir" et afficher tous les termes, à travers les taxonomies. Si j'exclus le 'taxonomy => des arguments, il renvoie des termes provenant de types de publication et de taxonomies personnalisés.

Idéalement, la fonction de base se lirait comme suit:

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
    );
}
// return array('options'=>$options);
return $options;
}

Je me demandais si vous aviez des pensées générales? Je sais que c’est difficile sans voir le code dans son intégralité, mais j’ai pensé que cela valait la peine d’être demandé.

Wordpress Version 4.7.2

Woocommerce version 2.6.14

METTRE À JOUR:

Lentement, j'essaie de cerner mon problème.

Il semble que 'product_cat' soit accessible après tout (bon), mais il crache un tableau qui ne s’affiche pas correctement.

C'est déroutant pour moi comme si j'utilisais simplement get_terms() sans aucun paramètre, ou si vous spécifiez 'taxonomy' => 'category', le code ci-dessus fonctionne parfaitement.

Les autres éléments de code sur lesquels j'ai besoin de travailler sont:

Le tableau dans lequel j'aimerais que la liste d'options soit transférée -

    array(  
        'label'=> 'Collections',
        'desc'  => 'Select the collection you would like to display',
        'id'    => $prefix.'collection',
        'type'    => 'select',  
        'options' => product_cats()
),

le code qui génère la liste de sélection (utilisé pour les autres champs de méta)

// 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;

Je n'ai aucun problème avec d'autres champs méta qui fonctionnent ou s'affichent, y compris des listes de sélection.

Je préfère ne pas réécrire la méta-boîte entière avec tous ses champs, alors j'essaie de travailler avec ce que j'ai en ce moment.

2
Kevin Van Lierop

Pour ma vie, je veux vraiment que cela fonctionne de la manière correcte . Pour ma vie, je ne peux pas comprendre l'intégration.

Auparavant, j'avais examiné wp_dropdown_categories() et pensais que c'était une solution meilleure (et plus facile). J'ai atterri en travaillant sur le problème ci-dessus parce que je ne pouvais pas comprendre comment le faire fonctionner avec la syntaxe existante de la méta-boîte.

Pour l'instant, j'ai décidé de la solution temporaire trouvée ci-dessous. Ce n'est pas idéal et certainement pas la meilleure façon, mais cela me permet d'avancer en appelant les valeurs des modèles qui utiliseront ce champ.

// Wrap all categories in a function
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;
}

Je mettrai à jour plus que je progresse.

1
Kevin Van Lierop

Cela ne va probablement pas résoudre le problème, mais je voulais le dire: j'ai rencontré le même problème aujourd'hui et cela était dû au fait que je n'avais aucun produit dans mes catégories. Si c'est également le cas pour vous, assurez-vous d'ajouter 'hide_empty' => false.

Cela dit. Lorsque vous exécutez get_terms() sans aucun argument. Quelle est la sortie?

0
Marinus Klasen

Vous utilisez peut-être une ancienne version de WordPress (antérieure à la 4.5).

Avant WordPress 4.5.0, le premier paramètre de get_terms () était une taxonomie ou une liste de taxonomies et, depuis la version 4.5.0, les taxonomies devraient être transmises via l'argument 'taxonomy' dans le tableau $ args (ce que vous faites doit travailler comme ça).

Vous trouverez tous les détails sur ces modifications dans la page de référence get_terms () .

UPDATE: Désolé, je vérifie mon code et j'utilise get_categories (), pas get_terms, et ce droit get_terms () ne fonctionne pas!

voici un exemple de travail pour lister tous mes product_cat

$product_categories = get_categories( array(
    'taxonomy'     => 'product_cat',
    'orderby'      => 'name',
    'pad_counts'   => false,
    'hierarchical' => 1,
    'hide_empty'   => false
) );

J'espère que ça aide !

0
Benoti

Voici un exemple parfaitement fonctionnel d’une méta-boîte qui affiche une boîte de sélection de catégorie de produit. La méta-boîte apparaîtra sur le type de publication du produit.

add_action( 'add_meta_boxes', 'wpse256897_add_meta_box' );
add_action( 'save_post',     'wpse256897_save' );
/**
 * Adds the meta box container.
 */
function wpse256897_add_meta_box( $post_type ) {
    // Limit meta box to certain post types.
    $post_types = array( 'product' );

    if ( in_array( $post_type, $post_types ) ) {
        add_meta_box(
            'product_cat_selection',
             __( 'Product Category Selection', 'textdomain' ),
             'wpse256897_render_meta_box_content',
             $post_type,
             'advanced',
             'high'
        );
    }
}

/**
 * Save the meta when the post is saved.
 *
 * @param int $post_id The ID of the post being saved.
 */
function wpse256897_save( $post_id ) {
    /*
     * We need to verify this came from the our screen and with proper authorization,
     * because save_post can be triggered at other times.
     */

    // Check if our nonce is set.
    if ( ! isset( $_POST['myplugin_inner_custom_box_nonce'] ) ) {
            return $post_id;
    }

    $nonce = $_POST['myplugin_inner_custom_box_nonce'];

    // Verify that the nonce is valid.
    if ( ! wp_verify_nonce( $nonce, 'myplugin_inner_custom_box' ) ) {
            return $post_id;
    }

    /*
     * If this is an autosave, our form has not been submitted,
     * so we don't want to do anything.
     */
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
            return $post_id;
    }

    // Check the user's permissions.
    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, it's safe for us to save the data now. */

    // Sanitize the user input.
    $mydata = sanitize_text_field( $_POST['product_cat_selection'] );

    // Update the meta field.
    update_post_meta( $post_id, '_product_cat_selection', $mydata );
}

/**
 * Render Meta Box content.
 *
 * @param WP_Post $post The post object.
 */
function wpse256897_render_meta_box_content( $post ) {
    // Add an nonce field so we can check for it later.
    wp_nonce_field( 'myplugin_inner_custom_box', 'myplugin_inner_custom_box_nonce' );

    // Use get_post_meta to retrieve an existing value from the database.
    $current_product_cat = get_post_meta( $post->ID, '_product_cat_selection', true );

    // Display the form, using the current value.
    $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;
}

Ce n’est pas l’exemple le plus élégant (les conventions de nommage pourraient être meilleures). Il a été rapidement adapté à partir des notes apportées sur la page de référence Ajouter une boîte méta , mais il montre que wpse256897_product_cats() récupère les catégories de produits et qu'elles peuvent être enregistrées et affichées dans une zone de sélection de la page du produit. une meta box.

J'aimerais également ajouter qu'il pourrait être intéressant de vérifier la fonction wp_dropdown_categories() . Qui, malgré son nom, fonctionne aussi avec les taxonomies personnalisées. Cela vous éviterait de créer votre propre balise déroulante de catégorie.

Update: On dirait que la structure du tableau renvoyé par la fonction product_cats() ne fait pas de bruit avec votre implémentation de meta box. Notez que dans mon exemple ci-dessus, j'ai utilisé cette ligne pour parcourir les catégories lors de la génération des options pour l'élément select:

foreach ( $product_cats as $product_cat_id => $product_cat ) { ?>

Ceci est dû au fait que $product_cats est un tableau associatif d'identifiants de catégorie qui contiennent chacun un autre tableau contenant les label et slug pour chaque identifiant de catégorie.

Il semble que vous puissiez éventuellement utiliser cette version alternative de product_cats() qui formate la valeur de retour $ options de manière compatible avec votre code metabox:

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;
}
0
Dave Romsey