I've got a page with a blogroll in the left column and a sidbar in the right one. When I try to retrieve the page-id inside of the sidebar like:

echo $post->ID;
echo get_the_ID();

The result is 3726 but the page URI is page_id=3722 ! I'm really confused now. I badly have to catch the real page id to be able to use custom fields (with the right values).


I just noticed that 3726 is the id of the last blog element being displayed. But how to grab the page id?

  • See: wordpress.stackexchange.com/a/99545/21376 I'd mark that duplicate if the system would let me. – s_ha_dum Oct 20 '13 at 21:28
  • Thank you for the link but this post you mention does not explain anything to me nor delivers it a solution - I've checked. So could you please explain why this question should be related? I don't see the relationship. And maybe you've got an idea what my problem is? – Hexodus Oct 21 '13 at 8:39
  • possible duplicate of Identify the page being shown while in The Loop – kaiser Oct 21 '13 at 13:18
  • @s_ha_dum That's one way of getting upvotes ;) – kaiser Oct 21 '13 at 13:18
  • $post->ID and get_the_ID() both give you ID of the current post in the Loop and not necessarily the ID of the page you are on. get_queried_object always gives you information about the page. Your edit confirms my suspicion that the other question is a duplicate, whether you recognize it or not. – s_ha_dum Oct 21 '13 at 14:53

There are two ways to get what you need. One is mentioned in Identify the page being shown while in The Loop:

$post_id = get_queried_object_id();

Unfortunately, this might break. get_queried_object_id() looks in the global variable $wp_query for the ID, and that variable can be overwritten during the page rendering by query_posts(). The same is true for functions like is_page().

But you can fetch the real post ID earlier, during template_redirect, store its value, and get it in your widget class.

First we need a helper function that collects the post ID for later usage:

add_action( 'template_redirect', 'collect_real_post_id' );

function collect_real_post_id()
    static $post_id = 0;

    if ( is_singular() && 'wp_head' === current_filter() )
        $post_id = get_queried_object_id();

    return $post_id;

And now you can use that value wherever you want, for example in your widget() method:

class My_Widget extends WP_Widget

    public function widget( $args, $instance )
        $post_id = collect_real_post_id();

        if ( ! $post_id ) // 0 evaluates to FALSE

        // do something with the post ID
| improve this answer | |
  • Thank you for this solution - no doubt this will certainly work but I don't like to mess around to much in this theme ... that is not mine. Your hint with 'this might break' helped me to take an other mind road to an easier solution. – Hexodus Oct 21 '13 at 19:12

Actually get_queried_object_id() should do this trick but it's not storing the proper page id - like toscho mentioned it might break.

There's an easy ways around this problem and I always prefer the easiest possible solution. So I came around with this one.

  1. I switched the permalink settings to 'pagename'
  2. Now my url's are like that: http://www.mypage.com/examplepage/ and I can use now the uri without the slashes to feed the method get_page_by_path()

The resulting code:

function get_page_real_id_by_uri()
    $uri =  $_SERVER['REQUEST_URI'];
    $uri = str_replace("/", "", $uri);
    return get_page_by_path($uri)->ID;

I'm not sure if it's possible in Wordpress (I'm new to it) to declare two same path names - this might be a weak point of this solution. But so far it works perfectly.

| improve this answer | |
  • This will fail with child pages. – fuxia Oct 23 '13 at 16:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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