Display posts by tag on page

I’m trying to create an advanced WordPress page that shows the regular content, plus a second section on the same page that shows the latest posts from X tag. For example, a page is created about “cats”, has pictures, content, etc. Afterwords, I’d like to display the last X posts tagged with “cats”. Is that possible without using plugins, and without creating a custom page template for every page?

Perhaps it’s doable with the custom fields feature and multiple loops. E.g. get X amount of posts from a custom field with the value “cats”. I’ve been struggling with it for a while now, can can’t seem to find a solution that doesn’t involve create a template for every single page.

Read More

Thanks!

Related posts

Leave a Reply

3 comments

  1. 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' ?>
    
  2. Do a WP_Query in the second part of your page:

    <!-- First part of your page!-->
    <div class="firstcontent">
    
        <?php if ( have_posts() ) : while ( have_posts() ) : the_post();?>
            <p><?php the_title(); ?><p>
            <p><?php the_content(); ?><p>
        <?php endwhile; endif;?>
    
    </div>
    
    <!-- And now you call the WP_Query() !-->
    <div class="secondcontent">
    
        <!-- get the main query !-->
        <?php $wp_query = new WP_Query(array(
            'post_type' => 'post'
        ));?>
    
        <!-- and you can use it as above !-->
        <?php if ( have_posts() ) : while ( have_posts() ) : the_post();?>
            <p><?php the_title(); ?><p>
            <p><?php the_content(); ?><p>
        <?php endwhile; endif;?>
    
    </div>
    

    I’m currently working with a theme on WordPress, and i’m actually doing this stuff, so it work !