Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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.

share|improve this question
    
This appears to be a PHP question, that is not specific to WordPress. –  Chip Bennett Dec 11 '12 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 Dec 11 '12 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 Dec 11 '12 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. –  Chip Bennett Dec 11 '12 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 Dec 11 '12 at 19:45

4 Answers 4

up vote 3 down vote accepted

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();
?>
share|improve this answer
    
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 Dec 11 '12 at 19:42
    
@timshutes See my update. –  toscho Dec 11 '12 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 Dec 11 '12 at 19:57

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 } ?>
share|improve this answer
1  
+1. This is ultimately where I was trying to drive the OP. :) –  Chip Bennett Dec 11 '12 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 Dec 11 '12 at 21:05

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.

share|improve this answer
    
I fixed this. working on the var scope issue –  timshutes Dec 11 '12 at 19:49

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

share|improve this answer
    
can you explain a little more how you would use this? –  timshutes Dec 11 '12 at 19:16
    
This solution sounds a little dangerous to me.. possibly getting in the way of plugins, etc. anything simpler? –  timshutes Dec 11 '12 at 19:46

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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