I have a relationship field that outputs posts from a custom post type. However, if I unpublish one of those posts, it still shows in the outputted code.

I'm aware it's possible to set the fields to only allow the user to select from published posts only (in the admin), but I'm not sure how to add a check in the ACF output code to see if the posts are published or not.

The most likely situation where this will occur is when the client has been using the site for a while and using the relationship fields, but then deletes or unpublishes one of the posts and forgets to manually remove them from the relationship field.

Is there a way to check this on the fly?

Code below:

$holidays = get_sub_field('holidays');
if( $holidays ): ?>

<?php foreach( $holidays as $holiday): ?>
    <?php setup_postdata($holiday); ?>

    <a href="<?php echo get_permalink( $holiday->ID ); ?>">
        <?php echo get_the_title( $holiday->ID ); ?>

<?php endforeach; ?>
<?php wp_reset_postdata(); ?>

closed as off-topic by shanebp, Jacob Peattie, fuxia Jan 4 at 22:39

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.


You could also just use ACF's filters for this. Put the following code in your functions.php.

// hide drafts
function relationship_options_filter($options, $field, $the_post) {
$options[‘post_status’] = array(‘publish’);
return $options;
add_filter(‘acf/fields/post_object/query/name=<YOUR FIELD NAME>’, ‘relationship_options_filter’, 10, 3);

more info directly from their site: https://www.advancedcustomfields.com/resources/acf-fields-post_object-query/


Use get_post_status to check the status of a post.

if( get_post_status( $holiday->ID ) == 'publish' ){
    echo 'This is a published post';

Also note that your use of setup_postdata is incorrect here. It is required to pass the global $post var to the function, otherwise any template function that relies on the global $post will output incorrect data. That said, you aren't using any of those functions, as you are using versions that allow passing of an explicit post ID, so you can just remove setup_postdata as well as wp_reset_postdata.

  • Thanks @milo. That works nicely within the foreach loop. However, this whole block of code also sits within a flexible content loop (which I'm performing a count on), so if possible I would like to get the number of published holidays before entering the holiday loop so I can perform conditional logic on the wrapping element, depending on how many published holidays there are. eg "if 2 holidays - output this html, elseif 3 holidays - output different html etc etc. I fear this is a separate question though. – Xav Dec 7 '18 at 18:44
  • Assign the value of your flexible content field to a variable like $my_field = get_field( 'my_flexible_content_data' );, then you can var_dump( $my_field ) to see the contents and structure. It will be an array of arrays containing all of your fields, including post objects for the relationship field. You can then iterate through those arrays and count whatever you need to. – Milo Dec 8 '18 at 2:14

Not the answer you're looking for? Browse other questions tagged or ask your own question.