I am developing a theme and I need to get the actual page ID, when I do:

global $post;
$thePostID = $post->ID;

I get the wrong ID. I tried get_the_ID() and I get the same ID that in the code above, but both are wrong. I also tried to do wp_reset_query() before getting the ID but I still get the same wrong ID. I am running the code above in a template and it is NOT inside of a loop. I also want to clarify that I am trying to get a page ID, not a post ID, although the function seems to be the same. What I am doing wrong and how could I fix it?


I have been testing the different suggestions and here I will try to clarify some. The template page that doesn't show the right page ID displays the posts of a custom field that I created using ACF. The ID that I am getting when executing the_ID() or its variants is the first ID of the first post of the custom field. I retrieved the ID on the header of the template before executing any query and the result is the same, also when I reset the query the ID doesn't change.

Any suggestions?


  • 3
    The ID you get depends a lot on context. Can you give some more information on where you're using this? Is it in the loop or via a particular action or template? Jun 11, 2019 at 1:52
  • It depends on the usage. Like you are using this code in a loop or not.
    – Hector
    Jun 11, 2019 at 3:25
  • Is this your home page or post page?
    – Bhupen
    Jun 11, 2019 at 6:59
  • @MikeNGarrett I edited the post and answer your questions.
    – Gonzalo
    Jun 11, 2019 at 13:15
  • @Hector I edited the post and answer your question.
    – Gonzalo
    Jun 11, 2019 at 13:15

4 Answers 4


As mentioned in the comments, you are trying to get the ID in the taxonomy archive (template-taxonomy.php) which is not a post object and has no record in the database. It just tries to show some posts and you may get the first post ID when you use get_te_ID() function in that archive page.

Using some themes or plugins, you are able to create a page and use that as an archive page. In that case, the get_the_ID() function is able to return the actual page ID (Out of the loop) because it is a real post object and it has a place in the database.


As I mentioned in the comments, context matters when getting a post ID.

Try using get_queried_object() to determine what WordPress thinks you're trying to get based on the url. This will return the full object for you to better understand what's being queried.

From the get_queried_object() Codex:

  • if you're on a single post, it will return the post object
  • if you're on a page, it will return the page object
  • if you're on an archive page, it will return the post type object
  • if you're on a category archive, it will return the category object
  • if you're on an author archive, it will return the author object
  • etc.

This will give you a bit more information to determine if you have the page ID available to you or if you'll have to do a query for the page to get the ID.

If this is the object you're looking for, you can use get_queried_object_id() to retrieve the ID.

  • 2
    If they only need the ID they can use get_queried_object_id(). Jun 11, 2019 at 15:39
  • I think the full object would help more in this situation to determine what's being queried. Jun 11, 2019 at 15:53
  • Presumably they know that based on the template. Any template that’s loading a page could only ever be querying a post. Jun 11, 2019 at 16:09
  • Modified my answer to clarify. Thanks for the feedback. Jun 11, 2019 at 16:19
  • Thanks all for the comment, I just added more data regarding the context.
    – Gonzalo
    Jun 12, 2019 at 0:14

--- UPDATED ---

Ok now that I understand more about what you're doing (querying for a CPT and displaying it on a Page using a template file), here is how I handle a similar function:

On one of my sites I have a Page that describes hiking in a particular area, below which I query for all custom posts of the CPT "hike" that have a custom field that holds a (future) date for the hike (it's a guided hike that has a scheduled date and a form for folks to signup for the hike).

The Template file for the Hiking Page starts out as previously mentioned with

if (have_posts()) : while (have_posts()) : the_post();

followed by some HTML, within which is


in order to display the generic verbiage on the page about hiking in that area.

Below that I use get_posts(); to fetch all of the CPT posts for upcoming hikes, so older (past) hikes are not displayed

    global $post;
    $args = array (
    'post_type' => 'hike',
    'meta_key' => 'hike_date_start',
    'orderby' => 'meta_value_num',
    'order' => 'ASC',
    'posts_per_page' => -1);

    $myposts = get_posts($args); 
    foreach ( $myposts as $post ) : setup_postdata( $post );

    $exp_date = strtotime(get_post_meta($post->ID,'hike_date_start',true));
    $today = time();
    if ($today <= $exp_date) {

    $hikedate = get_post_meta($post->ID,'hike_date_start',true);
    $hikedate2 = get_post_meta($post->ID,'hike_date_end',true);
    $hikedateend = strtotime(get_post_meta($post->ID,'hike_date_end',true));
    $hikerating = get_post_meta($post->ID,'hike_rating',true);
    $hikeleader = get_post_meta($post->ID,'hike_leader',true);
    $hikecontactph = get_post_meta($post->ID,'hike_contact_phone',true);
    $hikecontactem = get_post_meta($post->ID,'hike_contact_email',true);
    $hikedirections = get_post_meta($post->ID,'hike_directions',true);

Below that is some more HTML to display the data in the format I want, like so:

    <div class="hikeentry">
      <div class="time">
      <div class="month"><?php echo date('M', $exp_date); ?></div>
      <div class="wkday"><?php echo date('l', $exp_date); ?></div>
      <div class="day"><?php echo date('d', $exp_date); ?></div>
      <div class="year"><?php echo date('Y', $exp_date); ?></div>
   <div class="hikedata">
     <h4><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h4>
     <div class="hikemeta">
     <div class="left">
     <span>Rating:</span> <?php echo $hikerating; ?><br />
     <span>Leader:</span> <?php echo $hikeleader; ?><br />
     <span>Contact:</span> <a href="mailto:<?php echo antispambot($hikecontactem); ?>"><?php echo antispambot($hikecontactem); ?></a> &nbsp;&nbsp; <?php echo $hikecontactph; ?> 
    <div class="left bordered rounded bkgd"><a href="<?php the_permalink() ?>">Click here to read full<br />description and Sign Up</a>
    <?php the_excerpt(); ?>
    </div><!-- end .hikeentry -->

ALSO when you're done with the foreach loop, it's important to reset the postdata, like so

    } endforeach; wp_reset_postdata();

Because I use get_posts($args); and not wp_query(); then you don't need to reset the query, just the postdata.

I'm not specifically using the_ID(); but you can, wherever you need it WITHIN the foreach loop just call the_ID(); as it's part of each individual CPTs data retrieved with setup_postdata();

I hope this helps, ask more questions in the comments and I'm happy to explain more about how/why I use this......I prefer to use the WP built-in methods for retrieving and using data instead of ACFs but I love ACF for making it easy for my users to enter custom data. :-)

--- prior answer, updated above -- It's difficult to know exactly how to advise you without knowing more about your specific use, but if I understand your question correctly, you're creating a Template file for a specific Page, yes?

In that case in your Pages>Add New where you've added your page and specified your new template to use, you still need at the top of your Template file:

if (have_posts()) : while (have_posts()) : the_post();

then where you need the ID you use the_ID();

I use this to assign the page's ID (which for all intents and purposes in current versions of WP is the same as a 'post' - pretty much everything is a 'post' nowadays) to a specific element on the page.

If you can post more details about what you're trying to accomplish it will help us to give you better suggestions.

  • thanks for the comment, I just added more data regarding the context.
    – Gonzalo
    Jun 12, 2019 at 0:13
  • @gonzalo Your additional context helps a little bit....I use ACF extensively, so I might still be able to help, but is the data you're trying to get something like specific posts related to that Page? If so you'll probably need to first access ALL postdata associated with that Page (the metadata) and setup a new query to use foreach and setup_postdata( $post ).... I can supply a more specific example if I can better understand what the data is that you're trying to get at.....I do this on one of my sites to pull all posts in a CPT with a future date to a specific page.
    – Trisha
    Jun 12, 2019 at 1:55
  • this particular page that doesn't return the right page ID is retrieving all the post = to custom field type. I do that by using get_posts with the pos_type = to custom field. Do you think that that is related to the issue? Is there another way that I should be querying the posts, if so, why can't I just use get_posts()? Thanks very much!
    – Gonzalo
    Jun 12, 2019 at 3:08
  • Yes, it will help if you post your entire query, possibly you are missing an element, but I will post another answer below very shortly with a specific example of what I am doing, which sounds very similar......perhaps by looking at my example and notes it will help you.
    – Trisha
    Jun 12, 2019 at 17:43
  • @Gonzalo Actually it was suggested to me to edit my original answer instead of adding a new one so that is what I did - please review it again to see if it helps you.
    – Trisha
    Jun 12, 2019 at 18:01

You get the ID after another post appear or after another loop.

if you want to get the original main query (current page ID)

use this function wp_reset_query, before you get the ID

  • Or wp_reset_postdata... Throwing such advice without context is rather harmful... Jun 11, 2019 at 4:46
  • why? I have say, if just he want to get the main query, isnt? he can use wp_reset_query. its different if he using wp_rest_postdata , this function need more specific context and list of loop
    – Manyang
    Jun 11, 2019 at 4:59
  • because you should be very careful when using both of these functions. If you have a problem with ID, then most probably there is something wrong with the way you process loops. Putting wp_reset_query will just mask this problem, but the problem itself will still exist... There should be no need to use wp_reset_query almost at all... Jun 11, 2019 at 5:01
  • @KrzysiekDróżdż I tried to you wp_reset_query() but it didn't work. I just edited the post and added more information.
    – Gonzalo
    Jun 11, 2019 at 13:16

Your Answer

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

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