WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
up vote 1 down vote accepted

how about get_post?

$post       = get_post( $p );
$group_type = get_post_meta( $post->ID, 'group_type', true );
share|improve this answer

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

share|improve this answer

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.

share|improve this answer
And perhaps also add 'posts_per_page' => 1 as argument to WP_Query, since OP only wants one post. – webaware Jan 26 '13 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 Jan 26 '13 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 Jan 26 '13 at 22:53
Afaik this depends on what page you're on, so it could be ... faulty. – kaiser Jan 26 '13 at 23:31
Would specifying 'page_id' => 1 overcome that? – webaware Jan 27 '13 at 0:26

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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