0

I have used $count before, but never run into this problem. I cannot get it to work. I have limited php background, so please be patient with me! Here is the $count setup code:

<?php $count = 0; ?>
<?php if ( have_posts() ) : // Start the Loop ?>
    <?php $count++; ?>      
    <?php while ( have_posts() ) : the_post(); ?>
        <?php get_template_part( 'content', get_post_format() ); ?>
    <?php endwhile; ?>  
<?php endif; ?>

Within content.php - here is what I am trying to do:

<?php if ($count == 1) { ?>
    <section class="stories-title">
        <img src="<?php bloginfo('stylesheet_directory'); ?>/assets/stories-title.jpg" />
    </section>
<?php ;} ?>

Can anyone explain to me what's happening? To the best of my knowledge, I'm running into an undefined variable issue, but I'm not sure how to fix this without breaking the $count... do the conditional statements and content have to be in the same file for $count to work?

UPDATE: The issue (as described below) was with variable scope - the $count variable does not carry over when using template_part. Here is the fixed code:

functions.php

// remember number (so we can count posts)

/**
 * Remember a number.
 *
 * @param  int|FALSE $add A number to add, or FALSE to reset the counter to 0 (zero).
 * @return int
 */

function wpse_count( $add = 0 )
{
    static $counter = 0;

    if ( FALSE === $add )
        $counter = 0;
    else
        $counter += (int) $add;

    return $counter;
}

index.php

<?php wpse_count( FALSE ); ?>

<?php if ( have_posts() ) : // Start the Loop ?>

    <?php while ( have_posts() ) : the_post(); ?>
      <?php wpse_count( 1 ); ?>
        <?php get_template_part( 'content', get_post_format() ); ?>

    <?php endwhile; ?>

<?php endif; ?>

content.php

    <?php if (count_posts() == 1) { ?>
        <section class="stories-title">
            <img src="<?php bloginfo('stylesheet_directory'); ?>/assets/stories-title.jpg" />
        </section>
    <?php ;} ?>

Additional Solution

For a MUCH simpler solution to this problem, see a different answer below. Just needed to use wp_query

<?php if ( $wp_query->current_post == 0 ) { ?>

No $counter needed.

8
  • This appears to be a PHP question, that is not specific to WordPress. Commented Dec 11, 2012 at 19:32
  • well - the problem is occurring specifically because of the get_template_part in the twentyeleven theme. I realize others may have issues w/ undefined variables in settings outside of WP - this problem for me is very specific to wordpress functions & the template_part
    – timshutes
    Commented Dec 11, 2012 at 19:34
  • I also don't see how the new title clarifies my question at all -- my problem is that the counter breaks when I call in a new template_part because the variables don't carry over. Maybe that's exactly what the new title is saying.. but seems more general than my question
    – timshutes
    Commented Dec 11, 2012 at 19:36
  • The problem is not specific to get_template_part(). That function is really just a fancy wrapper for the PHP include() function. The problem, which again is not specific to WordPress, is that variable scope does not pass through the PHP include() call. Commented Dec 11, 2012 at 19:39
  • I guess technically can't all questions can be reduced to php / html / mysql? This seemed to be a problem I only ran into when I switched to the twentyeleven loop style. The main issue boils down to: I want to display an image ONLY before the 1st post. I understand what you're saying - the problem is in PHP - but the solution I think might be specific to WP. I defer to those who are more knowledgeable than me here.
    – timshutes
    Commented Dec 11, 2012 at 19:45

4 Answers 4

3

The variable $count is accessible in the scope of the current function only. So whatever happens inside get_template_part() cannot know that variable.

You could use a global variable, which is accessible everywhere as $GLOBALS['count']. But then you risk collisions with plugins and maybe other code.

I recommend a helper function for the functions.php:

/**
 * Remember a number.
 *
 * @param  int|FALSE $add A number to add, or FALSE to reset the counter to 0 (zero).
 * @return int
 */
function wpse_count( $add = 0 )
{
    static $counter = 0;

    if ( FALSE === $add )
        $counter = 0;
    else
        $counter += (int) $add;

    return $counter;
}

You can use that function to remember any number you want. In your example that should look like this:

<?php 
// Reset the counter
wpse_count( FALSE );

if ( have_posts() ) : // Start the Loop

    while ( have_posts() ) : 
        the_post();
        wpse_count( 1 );
        get_template_part( 'content', get_post_format() );
    endwhile;

endif; 
?>

And in the template part file you print the value without adding anything:

echo wpse_count();

Example in TwentyEleven’s content-status.php

<?php 
the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) ); 
echo 'Number: ' . wpse_count();
?>
3
  • I'm sorry - I'm really revealing my limited php knowledge here - once I have this function setup, how do I implement in the template_part?
    – timshutes
    Commented Dec 11, 2012 at 19:42
  • @timshutes See my update.
    – fuxia
    Commented Dec 11, 2012 at 19:47
  • this solved it - post count is working correctly. I just needed to fix my if statement. I'll mark as the answer & update my question with the correct code. Thanks!
    – timshutes
    Commented Dec 11, 2012 at 19:57
3

you could use the variable $wp_query->current_post to determine the position before the first post; no $counter needed.

content.php

<?php if ( $wp_query->current_post == 0 ) { ?>
        <section class="stories-title">
            <img src="<?php bloginfo('stylesheet_directory'); ?>/assets/stories-title.jpg" />
        </section>
    <?php } ?>
2
  • 1
    +1. This is ultimately where I was trying to drive the OP. :) Commented Dec 11, 2012 at 21:02
  • I already marked an answer, but this is the solution I was looking for initially. Chip was correct - I was pigeoned into my particular solution and should have asked a broader question.
    – timshutes
    Commented Dec 11, 2012 at 21:05
1

You are incrementing your $count variable outside of the part of the Loop that is running through the posts. You code needs to increment the counter inside the while.

$count = 0;
if ( have_posts() ) : // Start the Loop 
//     $count++;    
    while ( have_posts() ) : the_post();
      $count++; 
      echo $count."\n";
        get_template_part( 'content', get_post_format() );
    endwhile;
endif; ?>

Then use one of the options in the other answers to solve the variable scope problem.

1
  • I fixed this. working on the var scope issue
    – timshutes
    Commented Dec 11, 2012 at 19:49
0

How about using the $GLOBALS['count'] to make it surely available everywhere.

2
  • can you explain a little more how you would use this?
    – timshutes
    Commented Dec 11, 2012 at 19:16
  • This solution sounds a little dangerous to me.. possibly getting in the way of plugins, etc. anything simpler?
    – timshutes
    Commented Dec 11, 2012 at 19:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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