web-dev-qa-db-fra.com

Comment utiliser return dans ma fonction personnalisée au lieu de echo

Je crée une fonction dans functions.php avec un hook personnalisé, et d'après ce que j'ai lu quelque part, il est recommandé de renvoyer au lieu d'utiliser echo dans une fonction WordPress ? Corrige moi si je me trompe.

Quoi qu'il en soit, donc avec écho, ma fonction fonctionne, mais casse tout le reste. Avec return, la fonction n’émet plus rien, mais rien n’est cassé. J'ai essayé d'utiliser cette question comme référence pour réparer le mien.

Voici ce que j'ai

function display_collections_menu(){
/* Get WooCommerce's product categories which is custom taxonomy */
  $prod_cat_args = array(
      'taxonomy'     => 'product_cat', //woocommerce
      'orderby'      => 'name',
      'empty'        => 0
    );

    $woo_categories = get_categories( $prod_cat_args );

    $woo_menu = '';

    $woo_menu.= '<ul class="menu-collections">';

    /* For each first level category, get the image, name, and link */
    foreach ( $woo_categories as $woo_cat ) {

        if( $woo_cat->category_parent == 0 ) {
          $woo_cat_id = $woo_cat->term_id; //category ID
          $woo_img_id = get_woocommerce_term_meta( $woo_cat_id, 'thumbnail_id', true ); //category image ID
          $woo_parent_image = wp_get_attachment_url( $woo_img_id ); //category image url
          $woo_cat_slug = $woo_cat->slug; //category slug for classes
          $woo_cat_name = $woo_cat->name; //category name for link

          /* return the image/link/name */
          $orw_woo_menu.= '<li class="menu-product menu-item menu-item-object-' . $woo_cat_slug . ' ">
          <a href="' . get_term_link( $woo_cat_slug, 'product_cat' ) . '" class="menu-product-link">
          <img src="' . $woo_parent_image . '" alt=" ' . $woo_cat_name . ' " class="menu-product-thumb" />
          <p class="menu-product-name">' . $woo_cat_name . '</p></a></li>';
        } 

    }//end of $woo_categories foreach

    $woo_menu.= '</ul>';

    return $woo_menu;   
}
add_action('woo_collections_menu', 'display_collections_menu');

Cela fonctionnera si, au lieu d'utiliser return et une variable, je répète les valeurs, mais cela casse les choses. Est-ce que j'utilise mal le retour?


Mise à jour avec une tentative de solution de Privateer - ne fonctionne toujours pas:

function display_collections_menu( $input = '' ){
/* Get WooCommerce's product categories which is custom taxonomy */
  $prod_cat_args = array(
      'taxonomy'     => 'product_cat', //woocommerce
      'orderby'      => 'name',
      'empty'        => 0
    );

    $woo_categories = get_categories( $prod_cat_args );

    $woo_menu = '';

    $woo_menu.= '<ul class="menu-collections">';

    /* For each first level category, get the image, name, and link */
    foreach ( $woo_categories as $woo_cat ) {

        if( $woo_cat->category_parent == 0 ) {
          $woo_cat_id = $woo_cat->term_id; //category ID
          $woo_img_id = get_woocommerce_term_meta( $woo_cat_id, 'thumbnail_id', true ); //category image ID
          $woo_parent_image = wp_get_attachment_url( $woo_img_id ); //category image url
          $woo_cat_slug = $woo_cat->slug; //category slug for classes
          $woo_cat_name = $woo_cat->name; //category name for link

          /* return the image/link/name */
          $orw_woo_menu.= '<li class="menu-product menu-item menu-item-object-' . $woo_cat_slug . ' ">
          <a href="' . get_term_link( $woo_cat_slug, 'product_cat' ) . '" class="menu-product-link">
          <img src="' . $woo_parent_image . '" alt=" ' . $woo_cat_name . ' " class="menu-product-thumb" />
          <p class="menu-product-name">' . $woo_cat_name . '</p></a></li>';
        } 

    }//end of $woo_categories foreach

    $woo_menu.= '</ul>';

    return $woo_menu;   
}
add_filter('collections_menu', 'display_collections_menu', 10, 1);
$html_block = apply_filters('collections_menu', $input_html);

Et puis ceci dans un template:

<?php echo $html_block; ?>

Est-ce que je me trompe toujours?

1
RachieVee

Si vous utilisez do_action( 'woo_collections_menu' ); dans le modèle, votre fonction doit renvoyer sa valeur. Sinon, vous returning les données dans un trou noir, rien ne sort ce que vous retournez.

Si vous utilisez un filtre, vous devriez alors return la valeur. Le but d'un filtre est de prendre une valeur, de filtrer cette valeur à travers une fonction, puis de faire quelque chose avec le résultat. Dans le contexte de votre modèle, utiliser apply_filters serait un peu étrange, car votre menu n'a aucune valeur jusqu'à ce que vous le construisiez. Donc, dans le modèle, cela ressemblerait à:

echo apply_filters( 'collections_menu', '' );

Ce qui est potentiellement déroutant et inutile. Cette chaîne vide pourrait être un menu par défaut ou quelque chose du genre, mais l'insérer dans le modèle n'est probablement pas le choix le plus judicieux.

Cependant, un filtre aurait aurait un sens dans la fonction elle-même, pour permettre à quelqu'un de modifier la sortie.

function display_collections_menu(){
    $default_menu = 'my complete menu markup here';
    return apply_filters( 'collections_menu', $default_menu );
}

Ensuite, dans le modèle, vous pouvez simplement sortir la fonction directement:

echo display_collections_menu();

et quelqu'un peut ajouter son propre filtre pour modifier la sortie s'il le souhaite. Une autre inclusion utile pourrait être un filtre sur les arguments avec lesquels vous extrayez des termes, afin que quelqu'un puisse modifier la sortie du menu sans avoir à reproduire la fonction entière.

Mais pour revenir à votre code d'origine, l'ajout de do_action( 'woo_collections_menu' );, puis l'écho de la sortie du menu directement dans la fonction devraient également fonctionner.

1
Milo

D'après ma compréhension des actions (par opposition aux filtres), une action fait simplement quelque chose et arrête le traitement. Aucune valeur de retour n'est réellement utilisée.

Vous pouvez changer votre code pour qu'il devienne un filtre en acceptant un argument (dites le code HTML à ajouter), puis effectuez un appel comme celui-ci où vous souhaitez récupérer le code:

$html_block = apply_filters('woo_collections_menu', $input_html);

Pour ce faire, vous pouvez changer la définition de votre fonction:

function display_collections_menu( $input = '' ){
 #code here
}
add_filter('woo_collections_menu', 'display_collections_menu', 10, 1);

Cela mettrait alors notre sortie dans la variable $html_block à utiliser comme bon vous semble.

1
Privateer

Je ne comprenais toujours pas comment retourner $ woo_menu; avec mon premier exemple de code, mais je me suis rendu compte que les choses ne se brisent pas si je garde le reste de la structure aussi loin que la variable le permet et que je répète une fois à la toute fin. Cela semble fonctionner pour moi. Que ce soit une bonne pratique ou non, laissez-moi un commentaire, mais pour l’instant, c’est la solution que j’utilise.

Merci.

function display_collections_menu(){
/* Get WooCommerce's product categories which is custom taxonomy */
  $prod_cat_args = array(
      'taxonomy'     => 'product_cat', //woocommerce
      'orderby'      => 'name',
      'empty'        => 0
    );

    $woo_categories = get_categories( $prod_cat_args );

    $woo_menu = '';

    $woo_menu.= '<ul class="menu-collections">';

    /* For each first level category, get the image, name, and link */
    foreach ( $woo_categories as $woo_cat ) {

        if( $woo_cat->category_parent == 0 ) {
          $woo_cat_id = $woo_cat->term_id; //category ID
          $woo_img_id = get_woocommerce_term_meta( $woo_cat_id, 'thumbnail_id', true ); //category image ID
          $woo_parent_image = wp_get_attachment_url( $woo_img_id ); //category image url
          $woo_cat_slug = $woo_cat->slug; //category slug for classes
          $woo_cat_name = $woo_cat->name; //category name for link

          /* return the image/link/name */
          $orw_woo_menu.= '<li class="menu-product menu-item menu-item-object-' . $woo_cat_slug . ' ">
          <a href="' . get_term_link( $woo_cat_slug, 'product_cat' ) . '" class="menu-product-link">
          <img src="' . $woo_parent_image . '" alt=" ' . $woo_cat_name . ' " class="menu-product-thumb" />
          <p class="menu-product-name">' . $woo_cat_name . '</p></a></li>';
        } 

    }//end of $woo_categories foreach

    $woo_menu.= '</ul>';

    echo $woo_menu; //ECHO at the very end instead of return works for me  
}
add_action('woo_collections_menu', 'display_collections_menu');
0
RachieVee