I am making a simple sidebar functionality to display embed video in the sidebar. I've created a meta field where admin should paste the embed video. It works as it should on posts, but on pages, get_the_ID() is always returning the same ID, 145, ID of one of the posts.

Here is the code I am using:

    $id = get_the_ID();
    $video_value = get_post_meta($id, '_post_video', true);
    if (! empty($video_value)) {
        echo $video_value;
        echo get_the_ID();
    } else {
        echo 'no video to show';
        echo get_the_ID();

I am a bit confused, so if anyone could shad some light on this... Thanks!

  • @G.M. but this is outside of the loop, and there is no custom loop on either posts or pages Commented Nov 17, 2013 at 13:47

3 Answers 3


There is some other query which replaces the main post ID. Might be another widget, some strange plugin code or something else If you have no control over the context, collect the post ID earlier:

add_action( 'template_redirect', 'collect_post_id' );

function collect_post_id()
    static $id = 0;

    if ( 'template_redirect' === current_filter() && is_singular() )
        $id = get_the_ID();

    return $id;

Instead of get_the_ID() use collect_post_id() now in your code.

$video_value = get_post_meta( collect_post_id(), '_post_video', true );
  • why not to reset the query? Commented Nov 17, 2013 at 13:56
  • @MarkKaplun Which one? If you don’t know the context, you might break something.
    – fuxia
    Commented Nov 17, 2013 at 13:57
  • ok, will just add it as an answer Commented Nov 17, 2013 at 14:00
  • thatnks, this worked, but I am curious why i had the problem in the first place, as I am just starting with this theme, so there is no other code or plugin that could affect it, and what is the difference between posts and pages in this case, as on posts it worked as it should? Commented Nov 17, 2013 at 14:07
  • What exactly changes the main query depends on the actual code. I don’t know that, so I have no idea. :) Maybe a shortcode?
    – fuxia
    Commented Nov 17, 2013 at 14:09

get_the_ID is intented to be used within The Loop.

From Codex:

This tag must be within The Loop.


$id = get_queried_object_ID();

See here for docs.

  • 2
    The docs are lying. That function requires just a global post object, which is available when is_singular() is TRUE, eg. on pages or single posts.
    – fuxia
    Commented Nov 17, 2013 at 13:56
  • I'm not completely sure about that... get_the_ID() calls get_post()->ID, which (for an empty/null $post) argument, then calls WP_Post::get_instance().
    – kaiser
    Commented Nov 17, 2013 at 14:00
  • I know. In the comment OP says there's no custom loop on pages, so I guessed something, probably another widget, is breaking global $post, but - normally - the queried object should be not fucked up, unless the widget is using query_posts in that case that widget should be disabled :) @toscho
    – gmazzap
    Commented Nov 17, 2013 at 14:00

somewhere in your site's code there is a costume query loop that doesn't reset the main loop parameters after it is finished. The right thing to do is to hunt it down and call wp_reset_query() when it finishes, the alternative is to call it in the beginning of your code

$id = get_the_ID();
$video_value = get_post_meta($id, '_post_video', true);
  • You can insert widget areas between items in a custom loop. Calling wp_reset_query() without knowing that would trigger some really ugly side effects.
    – fuxia
    Commented Nov 17, 2013 at 14:11
  • yes, but that is a very edge case, most similar problems that I witnessed were solved by using wp_reset_query. Commented Nov 17, 2013 at 15:03

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.