Avoiding using a loop to access a single post

Sometimes I want to access one particular CPT to extract something from it, for example a custom field value:

$group = new WP_Query( array( 
    'post_type' => 'group',
    'p' => $group_id
) );
while ( $group->have_posts() ) : $group->the_post();
    $group_type = get_post_meta($post->ID, "group_type", $single = true);       
endwhile;

However the purpose of a loop is to access more than one element so I dislike using a loop for a single post. Is there a way to do exactly the same thing (accessing this custom field value) without using a loop?

Related posts

Leave a Reply

3 comments

  1. Your WP_Query object holds an array of posts. Just take first entry:

    get_post_meta( $group->posts[0]->ID, "group_type", true );
    

    Note: the third parameter for get_post_meta() expects a keyword: true or false, not $single = true. It works, but it looks rather odd. 🙂

  2. You can use only half of a loop. Well, it’s not even a loop, just the check if we received any post. Simply use the (WP_Query) objects methods. The example wraps it up in a function, so you could even use it as Template Tag:

    function wpse83212_get_group_post( $group_id )
    {
        add_filter( 'post_limits', 'wpse83212_group_post_limit' );
        $group = new WP_Query( array( 
             'post_type' => 'group'
            ,'p'         => $group_id
        ) );
        // Did the query return anything?
        if ( $group->have_posts() )
        {
            // Setup the post data
            $group->the_post();
            // Now we have access to the `$GLOBALS['post']` object
            // as well as to any functions that only work inside the Loop:
            return get_post_meta( get_the_ID(), 'group_type', true );
        }
        else
        {
            return NULL;
        }
    }
    function wpse83212_group_post_limit( $limit )
    {
        remove_filter( current_filter(), __FUNCTION__, 10 );
        return 1;
    }
    

    Then simply use it in any template: $group_meta = wpse83212_get_group_post( 12 );. If the value now is NULL there was no such post. Else you’d get the single value returned.