1

Sometimes there's no way around creating a custom query, but when I do and then loop through it, I often want to use get_template_part() within the custom query loop to pull in a template I already know will fit my needs. Sometimes that template is 99.9% perfect and only needs some conditionals added for it to behave as needed depending on the query.

Assuming is_main_query() = FALSE in this template file, how can I (1) determine which query I am looping within; and (2) access the non-main query's properties and methods?


Example:

page.php

<?php
  $two_posts        = new WP_Query(array(
    'nopaging'      => true,
    'post_per_page' => -1,
    'post_type'     => 'post',
    'post__in'      => array(1, 2),
    'orderby'       => 'post__in'
  ));
?>

<?php if($two_posts->have_posts()) : ?>
  <div class="two-posts">
    <?php while($two_posts->have_posts()) : ?>
      <?php $two_posts->the_post(); ?>
      <?php get_template_part('templates/content', 'existing'); ?>
      <!-- or -->
      <?php include(locate_template('templates/content-existing.php')); ?>
    <?php endwhile; ?>
  </div>
<?php endif; ?>
<?php wp_reset_query(); ?>

templates/content-existing.php

<?php if(is_main_query()) : ?>
  <p class="title"><?php the_title(); ?></p>
<?php elseif(/* query == $two_posts */) : ?>
  <?php if(/* $two_posts->current_post == 0 */) : ?>
    <h1><?php the_title(); ?><h1>
  <?php endif; ?>
  <?php if(/* $two_posts->current_post == 1 */) : ?>
    <h2><?php the_title(); ?></h2>
  <?php endif; ?>
<?php else : ?>
  <p>Nothing to display here.</p>
<?php endif; ?>
1
1

First, don't use is_main_query() function (method is ok). It tells something absolutely different from what you would think it does — was the main query overridden.

As far as I remember, there is no clean solution to this since WP doesn't have a concept of explicitly passing context to a specific template or template part.

Since WP's way hinges primarily on globals, the “fitting” (if dirty) approach might be to pass the information in same fashion — through a global variable(s) of your own.

0

Thanks to Rarst's guidance I put together a quick solution that seems to do the trick even though it seems a bit hacky.


Solution:

page.php

<?php
  $two_posts        = new WP_Query(array(
    'nopaging'      => true,
    'post_per_page' => -1,
    'post_type'     => 'post',
    'post__in'      => array(1, 2),
    'orderby'       => 'post__in'
  ));

  /* Setup default global query boolean */
  $GLOBALS['two_posts_query'] = FALSE;

  /* Keep track of the post count */
  $GLOBALS['two_posts_count'] = $two_posts->post_count;
?>

<?php if($two_posts->have_posts()) : ?>
  <div class="two-posts">
    <?php while($two_posts->have_posts()) : ?>
      <?php $two_posts->the_post(); ?>
      <?php /* Keep track of the current post */ ?>
      <?php $GLOBALS['two_posts_current_post'] = $two_posts->current_post; ?>
      <?php /* Set global variable to TRUE */ ?>
      <?php $GLOBALS['two_posts_query'] = TRUE; ?>
      <?php get_template_part('templates/content', 'existing'); ?>
      <?php $GLOBALS['two_posts_query'] = FALSE; ?>
      <?php /* Reset global variable to FALSE */ ?>
    <?php endwhile; ?>
  </div>
<?php endif; ?>
<?php wp_reset_query(); ?>

templates/content-existing.php

<?php
  global $two_posts_query, $two_posts_post_count, $two_posts_current_post;
?>

<?php if($two_posts_query && $two_posts_post_count >= 2) : ?>
  <?php if($two_posts_current_post == 0) : ?>
    <h1><?php the_title(); ?><h1>
  <?php elseif($two_posts_current_post > 0) : ?>
    <h2><?php the_title(); ?></h2>
  <?php endif; ?>
<?php else : ?>
  <p class="title"><?php the_title(); ?></p>
<?php endif; ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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