web-dev-qa-db-fra.com

Terme de taxonomie personnalisé dans le permalien du produit WooCommerce

J'ai créé une taxonomie personnalisée pour le type de publication de produit créé par WooCommerce. Je veux utiliser cette taxonomie aux permaliens des produits.

Je suis tombé sur ce qui semblait être parfait pour ce que je voulais faire. Cependant, j'ai peu de chance de le faire fonctionner. En ajoutant le code dans l'article, je finis toujours avec% item% (que j'utilise plutôt que% artiste%) plutôt que le terme dans mon permalien.

<?php
/*
Plugin Name:  Woocommerce Item Taxonomy
Description:  Enables a Taxonomy called "Item" for organizing multiple single products under an unified item.
Version:      1.0.0
License:      MIT License
*/

add_action( 'init', 'ps_taxonomy_item' );
function ps_taxonomy_item()  {
  $labels = array(
    'name'                       => 'Item',
    'singular_name'              => 'Item',
    'menu_name'                  => 'Item',
    'all_items'                  => 'All Items',
    'parent_item'                => 'Parent Item',
    'parent_item_colon'          => 'Parent Item:',
    'new_item_name'              => 'New Item Name',
    'add_new_item'               => 'Add New Item',
    'edit_item'                  => 'Edit Item',
    'update_item'                => 'Update Item',
    'separate_items_with_commas' => 'Separate Item with commas',
    'search_items'               => 'Search Items',
    'add_or_remove_items'        => 'Add or remove Items',
    'choose_from_most_used'      => 'Choose from the most used Items',
  );

  $args = array(
    'labels'                     => $labels,
    'hierarchical'               => true,
    'public'                     => true,
    'show_ui'                    => true,
    'show_admin_column'          => true,
    'show_in_nav_menus'          => true,
    'show_tagcloud'              => true,
  );

  register_taxonomy( 'item', 'product', $args );
  register_taxonomy_for_object_type( 'item', 'product' );
}


/**
 * replace the '%item%' tag with the first 
 * term slug in the item taxonomy
 * 
 * @wp-hook post_link
 * @param string $permalink
 * @param WP_Post $post
 * @return string
 */
add_filter( 'post_link', 'wpse_56769_post_link', 10, 2 );
function wpse_56769_post_link( $permalink, $post ) {
    $default_term = 'no_item';
    $terms = wp_get_post_terms( $post->ID, 'item' );

    if ( ! empty( $terms ) && ! is_wp_error( $terms ) )
        $term = current( $terms )->slug;
    else
        $term = $default_term;

    $permalink = str_replace( '%item%', $term, $permalink );

    return $permalink;
}


/**
 * set WP_Rewrite::use_verbose_page_rules to TRUE if %item%
 * is used as the first rewrite tag in post permalinks
 * 
 * @wp-hook do_parse_request
 * @wp-hook page_rewrite_rules
 * @global $wp_rewrite
 * @param mixed $pass_through (Unused)
 * @return mixed
 */
function wpse_56769_rewrite_verbose_page_rules( $pass_through = NULL ) {

    $permastruct = $GLOBALS[ 'wp_rewrite' ]->permalink_structure;
    $permastruct = trim( $permastruct, '/%' );
    if ( 0 !== strpos( $permastruct, 'item%' ) )
        return $pass_through;

    $GLOBALS[ 'wp_rewrite' ]->use_verbose_page_rules = TRUE;
    return $pass_through;
}
add_filter( 'page_rewrite_rules', 'wpse_56769_rewrite_verbose_page_rules', PHP_INT_MAX );
add_filter( 'do_parse_request',  'wpse_56769_rewrite_verbose_page_rules', PHP_INT_MAX );


/**
 * check for existing item and set query to 404 if necessary
 *
 * @wp-hook parse_query
 * @param array $request_vars
 * @return array
 */
function wpse_56769_request_vars( $request_vars ) {

    if ( ! isset( $request_vars[ 'item' ] ) )
        return $request_vars;

    if ( ! isset( $request_vars[ 'name' ] ) )
        return $request_vars;

    if ( 'no_item' == $request_vars[ 'item' ] )
        unset( $request_vars[ 'item' ] );

    return $request_vars;
}
add_filter( 'request', 'wpse_56769_request_vars' );
2
INT

Comme toujours, à la fin, c'était trop simple: utiliser le mauvais crochet. post_link est pour les articles seulement devrait utiliser post_type_link à la place.

/**
 * replace the '%item%' tag with the first 
 * term slug in the item taxonomy
 * 
 * @wp-hook post_link
 * @param string $permalink
 * @param WP_Post $post
 * @return string
 */
add_filter( 'post_type_link', 'wpse_56769_post_link', 10, 2 );
function wpse_56769_post_link( $permalink, $post ) {

    if( $post->post_type == 'product' ) {
      $default_term = 'no_item';
      $terms = wp_get_post_terms( $post->ID, 'item' );

      if ( ! empty( $terms ) && ! is_wp_error( $terms ) )
          $term = current( $terms )->slug;
      else
          $term = $default_term;

      $permalink = str_replace( '%item%', $term, $permalink );
    }

    return $permalink;
}
2
INT

J'ai utilisé cette réponse très utile pour les fournisseurs de produits WooCommerce, car je voulais le fournisseur dans le lien permanent. Ci-dessous se trouve un extrait condensé modifié à faire exactement dans votre fichier functions.php.

//VENDOR PERMALINK
add_filter( 'post_type_link', 'wpse_56769_post_link', 10, 2 );
function wpse_56769_post_link( $permalink, $post ) {
    if( $post->post_type == 'product' ) {
      $default_term = 'vendor';
      $terms = wp_get_post_terms( $post->ID, 'wcpv_product_vendors' );
      if ( ! empty( $terms ) && ! is_wp_error( $terms ) )
          $term = current( $terms )->slug;
      else
          $term = $default_term;
      $permalink = str_replace( '%wcpv_product_vendors%', $term, $permalink );
    }
    return $permalink;
}
function wpse_56769_rewrite_verbose_page_rules( $pass_through = NULL ) {
    $permastruct = $GLOBALS[ 'wp_rewrite' ]->permalink_structure;
    $permastruct = trim( $permastruct, '/%' );
    if ( 0 !== strpos( $permastruct, 'wcpv_product_vendors%' ) )
        return $pass_through;
    $GLOBALS[ 'wp_rewrite' ]->use_verbose_page_rules = TRUE;
    return $pass_through;
}
add_filter( 'page_rewrite_rules', 'wpse_56769_rewrite_verbose_page_rules', 
PHP_INT_MAX );
add_filter( 'do_parse_request',  'wpse_56769_rewrite_verbose_page_rules', 
PHP_INT_MAX );
function wpse_56769_request_vars( $request_vars ) {
    if ( ! isset( $request_vars[ 'wcpv_product_vendors' ] ) )
        return $request_vars;
    if ( ! isset( $request_vars[ 'name' ] ) )
        return $request_vars;
    if ( 'no_item' == $request_vars[ 'wcpv_product_vendors' ] )
        unset( $request_vars[ 'wcpv_product_vendors' ] );
    return $request_vars;
}
add_filter( 'request', 'wpse_56769_request_vars' );

Ensuite, placez la balise %wcpv_product_vendors% dans les paramètres de permaliens où vous le souhaitez.

Merci à l'OP @INT pour la réponse très utile et le travail des jambes!

0
RCNeil