简体   繁体   中英

Get (and display) other posts that match ACF relationship field

I have an ACF relationship field called products . This field is present on the custom post type called resources .

In resources , I have three blogs, titled:

  • Blog 1
  • Blog 2
  • Blog 3

Blog 1 has the products field set to "Premium". Blog 2 also has this field set to "Premium".

Blog 3 has the products field set to "Common".

I've made a custom module that will showcase "related products" (blogs that have matching products ). For example, if I'm on Blog 1 , I'm expecting to see the title of Blog 2 in this custom module because of the products field match (they're both set to "Premium").

If I'm on Blog 3 , I expect to see nothing, because no other post exists with the products value.

Currently, in my custom module (called "related products" for reference),I have the following code:

$posts = get_field('products');

if( $posts ):

    foreach( $posts as $post): 
        the_title();
    endforeach;

endif;

Now, I'm on Blog 1 and in the "related products" module, I see: Premium printed once.

It's clearly pulling the data but I think this is only for the current post (it's showing the product data for blog 1 ). I've tested this by changing products on Blog 3 to "Premium" and the results were still the same on-page, just "Premium" printed once on the post.

What I'm trying to achieve:

  • Get other posts that are the same product type.
  • Extract data from these other posts (I want to get those post titles and display them).

get_field('products') will fetch the products field from the current post, so what you're getting is expected output.

If you want to show all other posts that have the same value in their products field you'll need to fetch all posts and compare their products fields;

$thisPostsProductsField = get_field('products');
$allPosts = get_posts([
    'post_type' => 'resources',
    'numberposts' => -1,
    'post__not_in' => [get_the_ID()] # NOTE: Ignore the post we're on
]);
$relatedPosts = [];

foreach ($allPosts as $aPost) {
    $aPostsProductField = get_field('products', $aField->ID); # NOTE: The second argument to get_field() specifies from where to fetch the field, it defaults to the current post ID

    if ($aPostsProductField === $thisPostsProductsField) {
        $relatedPosts[] = $aPost;
    }
}

# $relatedPosts should now contain other posts of type "resources" that have the same "products" field
foreach ($relatedPosts as $post) {
    setup_postdata($post);

    the_title();
    the_content();
    the_post_thumbnail();
}

wp_reset_postdata();

I assume here that you've limited your products relationship field to one post? Otherwise you'll need to loop the field value too, and you also need to decide whether it's enough that a post has one of the original post's products or if it needs to have all of the original post's products.

Edit: You could possibly use a meta_query instead to avoid having to fetch every single post and comparing their fields;

$relatedPosts = get_posts([
    'post_type' => 'resources',
    'meta_query' => [
        [
            'key' => 'products',
            'value' => $thisPostsProductsField->ID,
            'compare' => '='
        ]
    ]
]);

But it depends on how ACF stores the products field.

What you're describing sounds straightforward.
However the line you wrote seems incorrect :

$posts = get_field('products');

Indeed theget_field() function returns a single value, not a collection of posts.

Here below is a snippet that retrieves all posts having the products field set to the same value as the current post:

$value = get_field('products');

$posts = get_posts(array(
    'numberposts'   => -1,
    'post_type'     => 'post',
    'meta_key'      => 'products',
    'meta_value'    => $value
));

Hope this helps ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM