This should do the job. It’ll check for posts that have been tagged with the title of the current page. There’s no need to use if (have_posts()):
on a page template: if the template is called it will be because there is a post 🙂
<div class="page-loop">
<?php
while (have_posts()) : the_post();
$page_title = strtolower(get_the_title());
the_title('<h1>','</h1>');
?>
<p><?php the_content(); ?><p>
<?php endwhile;?>
</div>
<!-- Get the most recent post that has been tagged with the page title -->
<div class="related-posts">
<?php
$args = array(
'tag' => $page_title,
'posts_per_page' => 1,
);
$query = new WP_Query($args);
if ($query->have_posts()) :
while ($query->have_posts()) : $query->the_post();
the_title('<h1>','</h1>');
?>
<p><?php the_content(); ?><p>
<?php endwhile; else: ?>
<p>Sorry, no posts with this tag!</p>
<?php endif; wp_reset_query(); ?>
</div>
If you’d rather use custom meta to add the ‘tag’ to the page (instead of just using the title) you could add a custom meta box to the page like so. Add the following code to your functions.php (nb: this will add the meta box to all pages)
/** register the meta box */
function my_theme_add_meta_boxes() {
global $post;
add_meta_box(
'my-theme-meta',
'Choose a tag',
'my_theme_print_page_meta',
'page',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'my_theme_add_meta_boxes');
/** Add extra meta to the page */
function my_theme_print_page_meta() {
global $post;
$page_tags = get_post_meta($post->ID, '_page-tags', true);
?>
<label for="page-tags">Add a 'tag'</label>
<input type="text" class="page-tags" name="page-tags" value="<?php echo esc_attr($page_tags); ?>" />
<?php
}
/** Save post meta */
function my_theme_save_custom_meta() {
global $post;
// Stops WP from clearing post meta when autosaving
if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
return $post->ID;
}
if (isset($_POST['page-tags'])) {
$clean = sanitize_text_field($_POST['page-tags']);
update_post_meta($post->ID, '_page-tags', $clean);
}
}
add_action('save_post', 'my_theme_save_custom_meta');
Then your page.php code could look like this:
<div class="page-loop">
<?php
while (have_posts()) : the_post();
$page_tags = get_post_meta($post->ID, '_page-tags', true);
the_title('<h1>','</h1>');
?>
<p><?php the_content(); ?><p>
<?php endwhile;?>
</div>
<?php if ($page_tags): ?>
<!-- Get the most recent post that has been tagged with the page title -->
<div class="related-posts">
<?php
$args = array(
'tag' => $page_tags,
'posts_per_page' => 1,
);
$query = new WP_Query($args);
if ($query->have_posts()) :
while ($query->have_posts()) : $query->the_post();
the_title('<h1>','</h1>');
?>
<p><?php the_content(); ?><p>
<?php endwhile; else: ?>
<p>Sorry, no posts with this tag!</p>
<?php endif; wp_reset_query(); ?>
</div>
<?php endif; // There are 'page tags' ?>