Show Featured Posts on the Homepage Using Meta Keys

Quick Summary
- Use a meta_query in WP_Query with relation AND to fetch posts whose featured and homepage custom fields both equal 1.
- Put the code in front-page.php or home.php, and set both fields to 1 via Custom Fields or ACF True / False fields.
- Every matching post shows because posts_per_page is -1, so set a number such as 3 to limit the block.
If you mark posts as featured with custom fields, a meta_query in WP_Query can pull out just those posts. This example shows WordPress posts where the custom field featured is 1 and the custom field homepage is 1, which is handy for a featured block on your homepage.
Put the code in the template that renders your homepage, for example front-page.php or home.php.
<?php
$paged = get_query_var( "paged" )?get_query_var( "paged" ) : 1;
$posts_per_page = -1;
$_p = new WP_Query(array(
'posts_per_page' => $posts_per_page,
'paged' => $paged,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'featured',
'value' => '1',
'compare' => '=',
),
array(
'key' => 'homepage',
'value' => '1',
'compare' => '=',
),
)
));
while( $_p->have_posts() ):
$_p->the_post();
?>
//FEATURED POSTS TITLES
<h3><?php the_title( ); ?></h3>
<?php
endwhile;
wp_reset_query();
?>How it works
- Each inner array in
meta_querychecks one custom field:keyis the field name,valuethe value to match, andcomparethe comparison. 'relation' => 'AND'means a post must pass both checks. Use'OR'to show posts that pass either one. Atax_queryjoins category and tag conditions the same way.posts_per_pageis-1, so all matching posts are shown. Set a number such as3to limit the block.- The loop only prints the titles. Add
the_permalink(),the_post_thumbnail()orthe_excerpt()as your design needs.
Setting the fields
Add both custom fields, with the value 1, to each post you want to feature. You can do that in the editor’s Custom Fields panel, or with ACF True / False fields named featured and homepage, which save 1 when checked.
Remove the //FEATURED POSTS TITLES line before you use the snippet: it sits outside the PHP tags and prints as text. After a custom loop like this, wp_reset_postdata() is enough to restore the global post.
Related articles
- a WP_Query loop with image, date and link: fills out the titles-only loop above
- hiding posts from the main blog query: pre_get_posts, to keep chosen posts out of the regular list

