How do you specify single print blocks when looping through a ‘for’ loop?

I have a carousel created from images in a page template. For each page, the template will try to loop through a for and print out the images as needed.

The problem I’m facing is I need a few sections:

Read More

1) If more than 1 item returned, print this or
2) Just once print this item.

My code:

<?php
    //Check for slider
    $slideCheck = get_post_meta($post->ID, 'slide1', $single = true);
    // if there's a slide
    if($slideCheck){ ?>
        <section id="myCarousel" class="carousel slide" data-ride="carousel">
            <ol class="carousel-indicators">
                <li data-target="#myCarousel" data-slide-to="0" class=""></li>
                <li data-target="#myCarousel" data-slide-to="1" class="active"></li>
                <li data-target="#myCarousel" data-slide-to="2"></li>
            </ol>
            <div class="carousel-inner">
                <?php
                    $max_slides = 10;
                    for ($i=1; $i<=$max_slides; $i++){
                        $key = 'slide' . $i;
                        $slide = get_post_meta($post->ID, $key, $single = true);
                        $slide_text = get_post_meta($post->ID, $key . '_label', $single = true);
                        if($slide){
                            $class = ($key == 'slide1') ? 'active' : '';
                    ?>
                        <div class="item <?php echo $class; ?>">
                            <img src="<?php echo $slide; ?>" class="slider-images" />
                            <div class="carousel-caption">
                                <h2><?php if($slide_text) { echo $slide_text; } ?></h2>
                            </div>
                        </div>
                        <?php } // end if
                    } // end for
                ?>
            </div>
            <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
                <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
                <span class="sr-only">Previous</span>
            </a>
            <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
                <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
                <span class="sr-only">Next</span>
            </a>
        </section>
    <?php } // end if
?>

The parts as follows:

1) It grabs the post meta to see if there are slides attached to the post
2) If true, it starts the slide block
3) I need the <section> portion to print once if #2 is true
4) However, I need the next <ol> section to only print if there are more than 1 slides
5) The <div class="carousel-inner"> prints once if #2 is true
6) Then the for loop to print the items
7) Following that is a </div> that closes the carousel-inner from #5
8) The following <a> code I need to print like the <ol> above, only if there are more than 1 slides.

I got it all working, however I know there has to be a cleaner way to do this. Here is my attempt:

if($slideCheck){ ?>
    <section id="myCarousel" class="carousel slide" data-ride="carousel">
            <?php
                $max_slides = 10;
                for ($i=1; $i<=$max_slides; $i++){
                    $key = 'slide' . $i;
                    $slide = get_post_meta($post->ID, $key, $single = true);
                    $slide_text = get_post_meta($post->ID, $key . '_label', $single = true);
                    if($slide){
                        $class = ($key == 'slide1') ? 'active' : '';
                        if($i>1){
            ?>
                            <ol class="carousel-indicators">
                                <li data-target="#myCarousel" data-slide-to="0" class=""></li>
                                <li data-target="#myCarousel" data-slide-to="1" class="active"></li>
                                <li data-target="#myCarousel" data-slide-to="2"></li>
                            </ol>
                        <?php } //endif $1>1
                            if($i=1){
                        ?>
                            <div class="carousel-inner">
                        <?php } //endif $i=1
                        ?>
                        <div class="item <?php echo $class; ?>">
                            <img src="<?php echo $slide; ?>" class="slider-images" />
                            <div class="carousel-caption">
                                <h2><?php if($slide_text) { echo $slide_text; } ?></h2>
                            </div>
                        </div>
                        <?php } //endif $1>1
                            if($i=1){
                        ?>
                            </div>
                        <?php } //endif $i=1
                            if($i=2){
                        ?>
                            <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
                                <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
                                <span class="sr-only">Previous</span>
                            </a>
                            <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
                                <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
                                <span class="sr-only">Next</span>
                            </a>
                        <?php } // endif
                    } // end if
                } // end for
            ?>
    </section>
<?php } // end if
?>

As you can see, it seems very convoluted with a bunch of if($i>1) etc. There has to be a cleaner method and a better way to write this.

Related posts

1 comment

  1. This code is cleaner, and more adaptable.

    <?php
        // Set up an empty array to hold all of the slides
        $slideCheck = array();
        // We can only have 10 slides.  Change this number to allow for more or less.
        $max_slides = 10;
        // Loop through and get all the slides.
        for( $i = 0; $i <= $max_slides; $i++ ) {
            // Set up the key
            $key = 'slide' . $i;
            // Get the slide url
            $url = get_post_meta($post->ID, $key, $single = true);
            // Get the slide text
            $text = get_post_meta($post->ID, $key . '_label', $single = true);
            // Check to make sure we at least have one of the values
            if( ! empty( $url ) || ! empty( $text ) ) {
                // If we do, add them to our array
                $slideCheck[] = array(
                    'url'  => $url,
                    'text' => $text
                );
            }
        }
        // If we have one or more slides
        if( ! empty( $slideCheck ) ) { ?>
            <section id="myCarousel" class="carousel slide" data-ride="carousel">
    
                <?php if( sizeof( $slideCheck )  > 1 ) { // Here we are checking if we have more than one slide. ?>
                <ol class="carousel-indicators">
                    <?php for( $i = 0; $i < sizeof( $slideCheck ); $i++ ) { // Make this section dynamic, as we don't know how many slides we'll actually have ?>
                    <li data-target="#myCarousel" data-slide-to="<?php echo $i; ?>" class="<?php echo $i == 1 ? 'active' : ''; ?>"></li>
                    <?php } ?>
                </ol>
                <?php } ?>
    
                <div class="carousel-inner">
                    <?php
                        foreach( $slideCheck as $key => $slide ) {
                            // Some check to see if we are on the second slide, per your old code??? Not sure what it does.
                            $class = ($key == 1 ) ? 'active' : '';
                            ?>
                            <div class="item <?php echo $class; ?>">
                                <?php if( ! empty( $slide['url'] ) ) { ?>
                                <img src="<?php echo $slide['url']; ?>" class="slider-images" />
                                <?php } if( ! empty( $slide['text'] ) ) { ?>
                                <div class="carousel-caption">
                                    <h2><?php echo $slide['text']; ?></h2>
                                </div>
                                <?php } ?>
                            </div>
                        <?php } // end foreach ?>
                </div>
                <?php if( sizeof( $slideCheck ) > 1 ) { // Again, if we have more than one slide... ?>
                <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
                    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
                    <span class="sr-only">Previous</span>
                </a>
                <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
                    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
                    <span class="sr-only">Next</span>
                </a>
                <?php } ?>
            </section>
        <?php } // end if ?>
    

    Creating an array of ALL of your slides FIRST allows a few things:

    First, it allows you to know do a check on the sizeof() the array. If it’s greater than 1, you have more than 1 slide.

    Second, I’m not sure how the end user is populating these “slides”, but it seems if they have 10 fields (based on your max number), they could enter info into the first slide fields, skip the second fields, enter information into the third fields, and so forth. Again, not sure how you have it set up, but this array method will thwart that mistake by only putting “slides” that have any values in their inputs, into the array.

    I took the liberty to make your OL dynamic as well… as I figured it would grow or shrink based on the number of slides. Not sure if that’s your intent, but it seemed that way to me. The only thing I didn’t understand is why you are setting the second slide to be the “active” one.

Comments are closed.