WooCommerce 产品:自定义循环中的错误产品永久链接

WooCommerce products: Wrong product permalink in custom loop

我正在使用自定义循环来展示一系列产品。 该循环工作正常,并显示具有正确标题、图像和其他内容的产品。 但是permalink就是当前页的URL.

如果我在 permalink 中添加 $post,一切正常:get_permalink($post)

这是我当前的代码:

<?php $featured_posts = $products_select; if( $products_select ): ?>
<div>
    <ul>
        <?php foreach( $featured_posts as $post ): setup_postdata($post); ?>
            <?php wc_get_template_part( 'content', 'product' ); ?>
        <?php endforeach; ?>
    </ul>
    <?php wp_reset_postdata(); ?>
</div>

我检查了$products_select的内容,发现没有存储link。 这可能是问题所在吗?有什么方法可以纠正 permalink?

变量$products_select是基于relationship field from Advanced Custom Fields的自定义字段的输出。它存储为 post object.

更新

不要使用 get_posts() 函数,而是使用真正的 WP_Query 函数,如下例所示:

<?php
$loop = new WP_Query( array(
    'post_status' => 'publish',
    'post_type' => 'product',
    'posts_per_page' => 10,
) ); 
?>
<div>
    <ul><?php
if ( $loop->have_posts() ) :
while ( $loop->have_posts() ) : $loop->the_post();
    echo '<pre>ID: '.get_the_id().' | Title: '. get_the_title() . ' | Link: ' . get_permalink() . '</pre>';
    wc_get_template_part( 'content', 'product' );
endwhile;
wp_reset_postdata();
endif;?>
    </ul>
</div>

这次可以正常使用了,没有任何问题。


备选方案: 为避免此问题,您可以改用 WooCommerce [products] 简码,如下所示:

<?php 
$featured_posts = $products_select; if( $products_select ): 

// get a comma separated string of product Ids
$post_ids = implode( ',', wp_list_pluck( $featured_posts, 'ID' ) ); 

// Use [products] shortcode with the comma separated string of product Ids
echo do_shortcode("[products ids='$post_ids']" ); ?>
</div>

已测试并有效。

我还找到了一个可以与高级自定义字段一起使用并保持关系字段的自定义顺序的解决方案:

<?php
$args = array(
    'post_type' => 'product',
    'post__in' => $products_select,
    'posts_per_page' => 4,
    'orderby' =>  'post__in' 
    );
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) : ?>
<div>
    <ul>
        <?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
            <?php wc_get_template_part( 'content', 'product' ); ?>
        <?php endwhile; ?>
    </ul>
</div>  
<?php endif;  wp_reset_postdata(); ?>