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);       

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?

3 Answers 3


how about get_post?

$post       = get_post( $p );
$group_type = get_post_meta( $post->ID, 'group_type', true );

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. :)


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
        // 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 );
        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.

  • 1
    And perhaps also add 'posts_per_page' => 1 as argument to WP_Query, since OP only wants one post.
    – webaware
    Commented Jan 26, 2013 at 13:33
  • @webaware Good idea. But this will influence the per page limit only. I added an action for the post_limits filter.
    – kaiser
    Commented Jan 26, 2013 at 15:16
  • Won't 'posts_per_page' => 1 do the same thing in effect, by returning only a single 'page' of 1 row from MySQL?
    – webaware
    Commented Jan 26, 2013 at 22:53
  • Afaik this depends on what page you're on, so it could be ... faulty.
    – kaiser
    Commented Jan 26, 2013 at 23:31
  • Would specifying 'page_id' => 1 overcome that?
    – webaware
    Commented Jan 27, 2013 at 0:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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