I had time to look at your issue and the options-reading.php page which is the template used to render the reading settings page in backend.
There are unfortunately no filters to filter or add custom posts as sticky posts in a selectable dropdown. There are two hidden filters though which we can use, they are
-
wp_dropdown_pages
inside thewp_dropdown_pages() function
which is used by the dropdown which display the list of pages which can be set as static front page -
get_pages
inside theget_pages()
function which is the function responsible to return the pages which is used bywp_dropdown_pages()
IMHO, I think get_pages
here is a better option. This way we will let wp_dropdown_pages()
to take care of all the markup. We need to take care here though when we use the get_pages
filter
- We will need to make sure we only target the admin area and in particular the reading settings page otherwise we will alter any function/page that uses the
get_pages()
function
You need to decide whether you would need pages to show with the custom post type posts or just need the custom post types
You can try the following:
add_filter( 'get_pages', function ( $pages, $args )
{
// First make sure this is an admin page, if not, bail
if ( !is_admin() )
return $pages;
// Make sure that we are on the reading settings page, if not, bail
global $pagenow;
if ( 'options-reading.php' !== $pagenow )
return $pages;
// Remove the filter to avoid infinite loop
remove_filter( current_filter(), __FUNCTION__ );
$args = [
'post_type' => 'my_frontpage',
'posts_per_page' => -1
];
// Get the post type posts with get_posts to allow non hierarchical post types
$new_pages = get_posts( $args );
/**
* You need to decide if you want to add custom post type posts to the pages
* already in the dropdown, or just want the custom post type posts in
* the dropdown. I will handle both, just remove what is not needed
*/
// If we only need custom post types
$pages = $new_pages;
// If we need to add custom post type posts to the pages
// $pages = array_merge( $new_pages, $pages );
return $pages;
}, 10, 2 );
You should now see your custom post type posts in the dropdown. Take note, this code will affect the dropdown for the blog page as well.
To avoid that, you can use a static counter to count the amount of times the filter has run and then bail just before the filter is applied to the blogpage dropdown. The filter will run a total of 3 times as get_pages()
runs 3 times:
-
first to check if we actually have pages to set as a static front page.
-
second run will be inside
wp_dropdown_pages()
which is used by the static front page dropdown -
the last run will be inside
wp_dropdown_pages()
which is used by the blogpage dropdown
So, based on this, we can try
add_filter( 'get_pages', function ( $pages, $args )
{
// First make sure this is an admin page, if not, bail
if ( !is_admin() )
return $pages;
// Make sure that we are on the reading settings page, if not, bail
global $pagenow;
if ( 'options-reading.php' !== $pagenow )
return $pages;
// Remove the filter to avoid infinite loop
remove_filter( current_filter(), __FUNCTION__ );
// Setup our static counter
static $counter = 0;
// Bail on the third run all runs after this. The third run will be 2
if ( 2 <= $counter )
return $pages;
// Update our counter
$counter++;
$args = [
'post_type' => 'my_frontpage',
'posts_per_page' => -1
];
// Get the post type posts with get_posts to allow non hierarchical post types
$new_pages = get_posts( $args );
/**
* You need to decide if you want to add custom post type posts to the pages
* already in the dropdown, or just want the custom post type posts in
* the dropdown. I will handle both, just remove what is not needed
*/
// If we only need custom post types
$pages = $new_pages;
// If we need to add custom post type posts to the pages
// $pages = array_merge( $new_pages, $pages );
return $pages;
}, 10, 2 );
If you visit the front end and visit the front page, you’ll find that it will redirect to the single post page. That is because, by default, the main query on a static front page is set to query the page
post type. This causes a 404 being returned and redirect_canonical()
then redirects to the single post page. This is easy to solve, all we must do is to adjust the main query on the static front page.
add_action( 'pre_get_posts', function ( $q )
{
if ( !is_admin() // Only target the front end
&& $q->is_main_query() // Only target the main query
&& 'page' === get_option( 'show_on_front' ) // Only target the static front page
) {
$q->set( 'post_type', 'my_frontpage' );
}
});
You will now have your static front page displaying correctly.
All you are left to do is to set a template. You can simply create a front-page.php
, WordPress will automatically use it