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
return;
// do something with the post ID
}
}