1

The Problem

I have a complex loop designed for showcasing my portfolio.

Here is the criteria:

  • Portfolio is powered by a custom post type called PORTFOLIO
  • Each post will be assigned a class of either 'landscape' or 'portrait' so that I can serve two different featured image sizes, and it's handled by dev logic, to add visual interest to the layout on each visit
  • Needs to paginate
  • I have included a graphic to illustrate what I am trying to achieve
  • I have variables (count, classes, customClass), that won't work inside includes unless they are added as global variables, which I know is poor practice

enter image description here

Details & What I Have Tried

The code below is working, but I know it is not optimal. I am seeking input on how to improve this to be more digestible.

As noted above, I am also leveraging global variables which I would like to resolve, as I understand that is a no-no.

This is my existing working loop.

//----------------------- WORK PAGE LOOP
<div class="portfolio grid__container">
  <?php 
    // IMG ORIENTATION VARIABLE
    $classes = array(
      'landscape',
      'portrait',
    );
    $count = 0;
    $paged = (get_query_var('paged') > 1) ? get_query_var('paged') : 1;
    // ARGUMENTS
    $args  = array(
      'post_type'          => 'portfolio',
      'orderby'            => 'rand',
      'posts_per_page'     => 99,
      'paged'              => $paged,
      'paged'              => 1,
    );
    // LOOP QUERY
    $portfolio_loop = new WP_Query($args);
    ?>  

  <div class="grid__row">
    <?php 
      // POWER THE LOOP
      while ($portfolio_loop->have_posts()): 
      $portfolio_loop->the_post();  
      $count++; 
      $customClass = $classes[$portfolio_loop->current_post%2];
    ?>

    <!-- ROW 1 -->
    <?php if (in_array($count, array( 1,2,3 )) && $paged == 1) :   ?>
      <div class="grid__cell grid__cell__small--12 grid__cell__medium--4">
        <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
      </div>
      
    <!-- ROW 2 -->
    <?php elseif ($count <= 5 && $paged ==1 ) : ?>
      <div class="grid__cell grid__cell__small--12 grid__cell__medium--6" id="count-<?php echo $count; ?>">
        <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
      </div>

    <!-- ROW 3 -->
    <?php elseif ($count <= 7 && $paged ==1 ) : ?>
      <div class="grid__cell grid__cell__small--12 grid__cell__medium--6">
        <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
      </div>

    <!-- ROW 4 -->
    <?php elseif($count > 7 && $count < 12 && $paged == 1) : ?>
      <div class="grid__cell grid__cell__small--12 grid__cell__medium--4">
        <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
      </div>

    <!-- ROW 5 -->
    <?php elseif($count > 11 && $count < 16 && $paged == 1) : ?>
      <div class="grid__cell grid__cell__small--12 grid__cell__medium--6" id="count-<?php echo $count; ?>">
        <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
      </div>

    <!-- ROW 6 -->
    <?php elseif ($count > 15 && $paged == 1) : ?>
      <div class="grid__cell grid__cell__small--12 grid__cell__medium--4" id="count-<?php echo $count; ?>">
        <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
      </div>

  <?php endif; ?>
  <?php endwhile; ?>

  </div>

<?php if ($portfolio_loop->max_num_pages > 1) { // check if the max number of pages is greater than 1  ?>
  <nav class="prev-next-posts">
    <div class="prev-posts-link">
      <?php echo get_next_posts_link( 'Older Articles', $portfolio_loop->max_num_pages ); // display older posts link ?>
    </div>
    <div class="next-posts-link">
      <?php echo get_previous_posts_link( 'Newer Articles' ); // display newer posts link ?>
    </div>
  </nav>
<?php } ?>

<?php wp_reset_postdata(); ?>
  
</div>

This is my include file:

<?php 
  // GLOBAL VARIABLES
  global $count;
  global $classes;
  global $customClass;
?> 

<article id="post-<?php the_ID(); ?>" <?php post_class( $customClass . $count . ' m-b-20--sm m-b-75--lg'); ?>>
  <!-- COMING SOON -->
  <?php if(has_term('coming-soon', 'portfolio_status')) { ?>
    <?php get_template_part('template-parts/portfolio/portfolio', 'soon-badge'); ?>
  <?php } else { ?>
  <?php } ?>
  <!-- COMING SOON --> TEST: <?php echo $customClass; ?>
  <figure class="lazyload portfolio__image m-b-30--md m-b-20--sm"> 
    <?php if(!has_term('coming-soon', 'portfolio_status')) { ?>
    <a href="<?php echo get_permalink(); ?>">  
    <?php } 
      if ($customClass == "landscape") {
        echo the_post_thumbnail('portfolio-landscape');
      }
      elseif ($customClass == "portrait") {
        echo the_post_thumbnail('portfolio-portrait');
      }
    ?>  
    <?php if(!has_term('coming-soon', 'portfolio_status')) { ?>
    </a>
    <?php } ?>    
  </figure>
  <span class="block meta"><?php echo strip_tags(get_the_term_list( $post->ID, 'portfolio_categories', ' ',', ')); ?></span>
  <h2 class="h4 portfolio__title">
    <span class="h4">
      <?php if(!has_term('coming-soon', 'portfolio_status')) { ?>
      <a href="<?php echo get_permalink(); ?>">  
        <?php } ?>     
          <?php the_title(); ?>
        <?php if(!has_term('coming-soon', 'portfolio_status')) { ?>
      </a>
      <?php } ?>
    </span>
  </h2>
  <div class="portfolio__excerpt m-t-10"><?php the_excerpt(); ?></div>
  <?php get_template_part('template-parts/portfolio/portfolio', 'tags'); ?>
</article>

Updated V2 Code

  • Simplified conditional statements, not sure why I made them so complicated before.
  • Removed double instances of $paged and updated pagination to use the built in WordPress paginate_links snippet as noted by @Rajiii4u
<div class="portfolio grid__container">

  <?php 
    // VARIABLE FOR IMG ORIENTATION 
    $classes = array(
      'landscape',
      'portrait',
    );
    // COUNT THE POSTS
    $count = 0;
    // PAGINATE
    $paged = (get_query_var('paged') > 1) ? get_query_var('paged') : 1;
    // ARGUMENTS
    $args  = array(
      'post_type'          => 'portfolio',
      'orderby'            => 'rand',
      'posts_per_page'     => 18,
      'paged'              => $paged,
    );
    // CUSTOM LOOP QUERY
    $portfolio_loop = new WP_Query($args);
    ?>  

  <div class="grid__row">
    <?php 
      // POWER THE LOOP
      while ($portfolio_loop->have_posts()): 
      $portfolio_loop->the_post();  
      $count++; 
      $customClass = $classes[$portfolio_loop->current_post%2];
    ?>

    <!-- ROW 1 // 1 TO 3 -->
  <?php if (in_array($count, array( 1,2,3 ))) : ?>
    <div class="grid__cell grid__cell__small--12 grid__cell__medium--4" id="counter-<?php echo $count; ?>">
      <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
    </div>

  <!-- ROW 2 // LESS THAN OR EQUAL TO 5 -->
  <?php elseif ($count <= 5 ) : ?>
    <div class="grid__cell grid__cell__small--12 grid__cell__medium--6" id="counter-<?php echo $count; ?>">
      <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
    </div>

  <!-- ROW 3 // LESS THAN OR EUQAL TO 7 -->
  <?php elseif ($count <= 7 ) : ?>
    <div class="grid__cell grid__cell__small--12 grid__cell__medium--6" id="counter-<?php echo $count; ?>">
      <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
    </div>

  <!-- ROW 4 // LESS THAN OR EQUAL TO 12 -->
  <?php elseif($count <= 10 ) : ?>
    <div class="grid__cell grid__cell__small--12 grid__cell__medium--4" id="counter-<?php echo $count; ?>">
      <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
    </div>

  <!-- ROW 5 -->
  <?php elseif($count <= 12 ) : ?>
    <div class="grid__cell grid__cell__small--12 grid__cell__medium--6" id="counter-<?php echo $count; ?>">
      <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
    </div>

  <!-- ROW 6 -->
  <?php else : ?>
    <div class="grid__cell grid__cell__small--12 grid__cell__medium--4" id="counter-<?php echo $count; ?>">
      <?php get_template_part('template-parts/portfolio/portfolio', 'article'); ?>
    </div>

  <?php endif; ?> <!-- END CONDITIONAL STATEMENTS-->
  <?php endwhile; ?>
  </div> <!-- GRID_ROW -->

<?php wp_reset_postdata(); ?>

<?php
  $big = 999999999; // need an unlikely integer

  echo paginate_links( array(
    'base'    => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format'  => '?paged=%#%',
    'current' => max( 1, get_query_var('paged') ),
    'total'   => $portfolio_loop->max_num_pages
  ) );
?>
        
</div>

1 Answer 1

0

Here are some optimization suggestions for the code:

Refactor the code structure: Currently, the code is using multiple if statements to determine which template to display for each portfolio item. This can be refactored to use a single switch statement. This will make the code more readable and easier to maintain.

Remove redundant code: The $paged variable is defined twice in the $args array, so it can be removed from the second definition.

Improve pagination: Currently, the pagination is done by checking if $portfolio_loop->max_num_pages is greater than 1. A better approach would be to use the paginate_links() function provided by WordPress to display the pagination links.

Remove unused variables: The $customClass variable is defined but not used, so it can be removed.

Replace magic numbers with constants: Currently, the code is using magic numbers (e.g., 7, 11, 15, 99) to determine the layout for each portfolio item. These values should be replaced with constants to make the code more readable and easier to maintain.

    <?php 
  // GLOBAL VARIABLES
  global $count;
  global $customClass;
?> 
<article id="post-<?php the_ID(); ?>" <?php post_class("$customClass $count m-b-20--sm m-b-75--lg"); ?>>
  <!-- COMING SOON -->
  <?php if(has_term('coming-soon', 'portfolio_status')) {
    get_template_part('template-parts/portfolio/portfolio', 'soon-badge');
  } ?>
  <!-- COMING SOON --> TEST: <?php echo $customClass; ?>
  <figure class="lazyload portfolio__image m-b-30--md m-b-20--sm"> 
    <?php if(!has_term('coming-soon', 'portfolio_status')) { ?>
      <a href="<?php echo get_permalink(); ?>">  
    <?php } 
      if ($customClass === "landscape") {
        echo the_post_thumbnail('portfolio-landscape');
      }
      elseif ($customClass === "portrait") {
        echo the_post_thumbnail('portfolio-portrait');
      }
    ?>  
    <?php if(!has_term('coming-soon', 'portfolio_status')) { ?>
      </a>
    <?php } ?>    
  </figure>
  <span class="block meta"><?php echo strip_tags(get_the_term_list( $post->ID, 'portfolio_categories', ' ',', ')); ?></span>
  <h2 class="h4 portfolio__title">
    <?php if(!has_term('coming-soon', 'portfolio_status')) { ?>
      <a href="<?php echo get_permalink(); ?>">  
    <?php } ?>     
    <?php the_title(); ?>
    <?php if(!has_term('coming-soon', 'portfolio_status')) { ?>
      </a>
    <?php } ?>
  </h2>
  <div class="portfolio__excerpt m-t-10"><?php the_excerpt(); ?></div>
  <?php get_template_part('template-parts/portfolio/portfolio', 'tags'); ?>
</article>
3
  • Hi @Rajiii4u thank you for your input. Remove unused variables: The $customClass variable is defined but not used, so it can be removed. – I'm confused about your feedback here. That variable is being used in the article element. It is what assigns a class of either landscape or portrait
    – Sabotawsh
    Commented Feb 5, 2023 at 15:56
  • The $paged variable is defined twice in the $args array, so it can be removed from the second definition. – Ah, good catch, removed, thanks!
    – Sabotawsh
    Commented Feb 5, 2023 at 15:59
  • Improve pagination: Currently, the pagination is done by checking if $portfolio_loop->max_num_pages is greater than 1. A better approach would be to use the paginate_links() function provided by WordPress to display the pagination links.– great point, updated code to reflect this.
    – Sabotawsh
    Commented Feb 5, 2023 at 18:12

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.