Get the *actual* page ID in WordPress archives

Published September 24, 2019
.* :☆゚

When you’re workiing with WordPress templates, it’s not uncommon to want to use an actual page to reference in an archive template file. You may use the page to store custom fields, content, or a featured image for example.

WordPress unfortunately doesn’t have a very simple out-of-the box solution for handling front-matter on archive pages, so archive templates require slightly different handling compared to regular posts/pages.

Humanmade were ahead of the curve and made a plugin to set a page for post types. My solution is a little more rudimentary but it is nonetheless extendable and easy to configure to your needs.

All this function does is check if there are any relevant pages to use in an archive template by utilising WordPress’ get_page_by_path() function. You can also use get_page_by_title() if that’s easier for you to manage rather than slugs.

Simply paste the function into functions.php to use.

<?php

function get_page_ID() {
  //if on the blog page
	if ( is_home() && ! in_the_loop() ) {
    $ID = get_option('page_for_posts');
	} elseif ( is_post_type_archive()) {
		//reference a custom archive page based it's slug
		//eg. for a 'houses' custom post type, you would create a page called `houses` and store any archive front matter on this page
		$query = get_queried_object();
		$slug = $query->name;
		$pageobj = get_page_by_path($slug);
		$ID = $pageobj->ID;
	} else {
		$ID = get_the_ID();
	}
	return $ID;
}

//in an archive template, if you want to retrieve a featured image for example
get_post_thumbnail(get_page_ID());

Note that the has_archive:true/false flag is irrelevant if you are using this for custom post types.

If you are using default archive functionality you can make a new page with the same CPT name as of 5.2.3 and use this function in tandem, which is exactly what I want!