I would like to set up an archive page for tags where posts are displayed separated depending on post format, first post-format-aside then an archive with all posts except the posts already displayed, from-post format-aside.

So first I want 4 posts with the post-format-aside format and then I want an archive but without posts from post-format-aside. As I have tried to do it is with WP-queries but it doesn't feel like a good structure.... This is the code I have set up so far:

<div class="row">
<?php $posts = new WP_Query( array(
'posts_per_page' => 4,
'post_type' => 'post',
'tax_query' => array(
    array(                
        'taxonomy' => 'post_format',
        'field' => 'slug',
        'terms' => array( 
            'post-format-aside'
        ),
    )
)
) );

if ( $posts->have_posts() ) : while ( $posts->have_posts() ) : $posts->the_post(); ?>
            <div class="col-sm-3 col-xs-6">
                <?php   get_template_part( 'content', get_post_format() ); ?>
                </div>

    <?php endwhile; ?>

    <?php endif; wp_reset_query(); ?>
 </div>

<?php
 $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$posts = ( array(
   'post_type' => 'post',
'posts_per_page' => -1,
'paged' => $paged,
'tax_query' => array(
    array(                
        'taxonomy' => 'post_format',
        'field' => 'slug',
        'terms' => array( 
            'post-format-link'
        ),
    )
)
) );
$query = new WP_query($posts);
if ( $query->have_posts() ) : ?>
   <?php rewind_posts(); ?>
  <?php  while ( $query->have_posts() ) : $query->the_post();
        if($i%4==0) {
            <div class="row">
        <?php } ?>

            <div class="col-sm-3 col-xs-6">
                <?php   get_template_part( 'content', get_post_format() ); ?>
                </div>

                <?php $i++;
                    if($i%4==0) { // if counter is multiple of 3, put an closing div ?>
                    </div>
                <?php } ?>

    <?php endwhile; wp_reset_query(); ?>
                <?php
                    if($i%4!=0) { // put closing div here if loop is not exactly a multiple of 3 ?>
                    </div>
                <?php } ?>
    <div class="blog">
        <div class="row">
            <div class="col-md-12">
                <?php posts_nav_link(); ?>
            </div>
        </div>
    </div>
up vote 1 down vote accepted

You're right. It isn't a good structure.

  1. You are running three queries on the page-- the two you are creating plus the main query that is being completely ignored (plus ancillary queries).
  2. You are also clobbering the main query halfway through the page load when you overwrite $wp_query, which can cause unexpected and unpredictable results and difficulty with pagination.
  3. You are overwriting other Core variables, like $posts
  4. You have PHP tag SPAM
  5. Your code formatting in general is lacking, though I've seen much worse.

What you want to do is alter the main query to exclude that post format:

function exclude_asides_wpse_194888($qry) {
  if (is_tag()) {
    $taxq = array(
        array(                
            'taxonomy' => 'post_format',
            'field' => 'slug',
            'terms' => array( 
                'post-format-aside'
              ),
            'operator' => '!='
        )
    )
    $qry->set('tax_query',$taxq);
  }
}
add_action('pre_get_posts','exclude_asides_wpse_194888');

Then run your "asides" query:

$asides = new WP_Query( 
  array(
    'posts_per_page' => 4,
    'post_type' => 'post',
    'tax_query' => array(
        array(                
            'taxonomy' => 'post_format',
            'field' => 'slug',
            'terms' => array( 
                'post-format-aside'
              ),
        )
    )
  ) 
);

if ( $asides->have_posts() ) {
  while ( $asides->have_posts() ) {
    $asides->the_post(); ?>
    <div class="col-sm-3 col-xs-6">
        <?php get_template_part( 'content', get_post_format() ); ?>
    </div><?php 
  }
}

Then let the main query as normal:

if ( have_posts() ) {
  while ( have_posts() ) {
    $query->the_post();
      if($i%4==0) { ?>
        <div class="row"><?php 
      } ?>

      <div class="col-sm-3 col-xs-6"><?php   
        get_template_part( 'content', get_post_format() ); ?>
      </div><?php 
      $i++;
      if($i%4==0) { // if counter is multiple of 3, put an closing div ?>
        </div><?php 
      } 
  }
  if($i%4!=0) { // put closing div here if loop is not exactly a multiple of 3 ?>
    </div><?php 
  } ?>
  <div class="blog">
    <div class="row">
      <div class="col-md-12"><?php 
        posts_nav_link(); ?>
      </div>
    </div>
  </div>
}
  • Thanks for your reply! One problem with the function is that that is enables post-format-aside for all queries it seems, even the first loop with four "aside" posts. But without the function includes all post types.. @sa_ha_dum – HannesH Jul 19 '15 at 16:40
  • Yes, you probably need to adjust the conditional -- the is(is_tag()) part-- to fit your needs. I was not sure of your particular requirements. – s_ha_dum Jul 19 '15 at 16:56
  • Yes I understand what you mean but is there a way to target only the main query and not target all posts on the page? – HannesH Jul 19 '15 at 18:31

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.