Hi I'm trying to create a list of posts that have a common custom field value that are the same as the custom field value for the post they are displayed on. I've found a few examples where the value is specific but I'm after an example where the value is common. So it might be something like Find the value for the common field for this post and then display a list of posts (with links to the post) that have custom fields that have the same value as this post. But don't include this post (the post they are displayed on) in the list. Thanks.
1 Answer
Retrieving and Listing posts based on current posts metadata
Assuming that the custom field is saved as postmeta:
global $post; // current post displayed
/* grab the value of the custom field for the current post */
$custom_field_value = get_post_meta( $post->ID, 'custom-field-name', true );
/* fetch all posts with the same value for the custom field */
$args = array(
'post_per_page' => -1,
'meta_key' => 'custom-field-name',
'meta_value' => $custom_field_value,
'post__not_in' => array( $post->ID )
);
$related_posts = new WP_Query( $args );
/* loop through related posts */
while ( $related_posts->have_posts() ) : $related_posts->the_post();
echo '<li>' . get_the_title() . '</li>';
/* or do something else */
endwhile;
wp_reset_postdata();
Extending the above by a second metadataset and linking to posts
As per your latest comment below, you want to limit the amount of posts shown by another custom field value, or metadataset respectively. Further you want the post list to link to the posts.
As for the linking, see the
get_permalink()
function.I haven't quite understood, whether the
'other-meta-key'
is supposed to be set to'yes'
on the current post or on the retrieved posts. In the first case, you can use the conditional from your comment and wrap everything in it (apart form the first line,global $post;
), because everything else would be redundant.If
'yes'
is supposed to be a meta value of the retrieved posts, your self-suggested approach to tackle the second meta value by adding a conditional into the loop would work as well indeed, but is not the most efficient solution. That way, you'd retrieve more posts than you need and iterate over more than you want to display. It is more efficient to incorporate this condition into the query as well and grab only the posts you want from the database. Whether you'd actually notice a difference in performance depends on the amount of posts we're dealing with.
Anyhow, here we go:
global $post; // current post displayed
/* grab the value of the custom field for the current post */
$custom_field_value = get_post_meta( $post->ID, 'custom-field-name', true );
/* fetch all posts with the same value for the custom field
* and 'yes' for the second field */
$args = array(
'post_per_page' => -1,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'custom-field-name',
'value' => $custom_field_value
),
array(
'key' => 'other-meta-key',
'value' => 'yes'
)
),
'post__not_in' => array( $post->ID )
);
$related_posts = new WP_Query( $args );
echo '<ul>';
/* loop through related posts,
* note that within the loop, the $post object is not the same as above */
while ( $related_posts->have_posts() ) : $related_posts->the_post();
echo '<li><a href="' . get_permalink( $post->ID ) . '">' .
get_the_title() .
'</a></li>';
endwhile;
echo '</ul>';
wp_reset_postdata();
-
1+1. Just be sure to
wp_reset_postdata()
when you close the custom loop. :) Nov 27, 2012 at 17:47 -
-
Thanks Johannes, This works but it includes all posts that have the common/same value for the "meta_key" instead of the common/same value for the "meta_value". It also includes the title of the post on the page it is displayed which I would like exclude. Nov 27, 2012 at 22:25
-
As for the excluding of the current post, simply add
'post__not_in' => array( $post->ID )
to the above query parameters (also edited into the above). As far as the value is concerned: If you feed a value to the 'meta_value' parameter, which I already did above, it will only return the posts with that value for the key. If you get all posts that have the custom field, you did not implement'meta_value' => $custom_field_value
correctly. For testing's sake you can feed it a static value, i.e.'meta_value' => 21
, replacing21
with whatever is a valid value. Nov 27, 2012 at 22:54 -
Hi Johannes Yes you were right I had a typo it works now Can I make another request I only want it show if another custom field has the value of "yes" Plus I need the 'title' to be a live link to the post so I'm guessing the if statement will need to go after where it says /* loop through related posts */ and will look something like
<?php if ( get_post_meta($post->ID, 'other_meta_key', true) == 'Yes') { list all posts with links to the post} ?>
Nov 28, 2012 at 16:36