Categories
WordPress WordPress Templates

WordPress Theme Exercise Solution: Metonymic Front Page Sectioning

We ended the previous article having generated the main content for the home page of the site.

However, if we inspect the code with browser developer tools, we’ll see that there’s just a ton of articles inside the .site-content MAIN element.

Our next step, therefore, should be to introduce some sectioning HTML to our loop of loops.


By the end of the previous discussion, our loop structure looked like this:

foreach ( $sections as $section ) {

  $my_loop = new WP_Query( $section );

  if ( $my_loop->have_posts() ) :

        while ( $my_loop->have_posts() ) :
                $my_loop->the_post();

                get_template_part( 'template-parts/content', get_post_type() );

        endwhile;

  else :
        get_template_part( 'template-parts/content', 'none' );

  endif;
  wp_reset_postdata();

} // end foreach
?>

Modify it to look like the following. I’ve added comments where things change: you don’t need to add those comments.

foreach ( $sections as $section ) {
  $my_loop = new WP_Query( $section );
 // close PHP so you can add HTML, then reopen PHP
?>

  <!-- Add Sectioning HTML -->
  <section class="section-<?php echo $section['category_name']; ?>">
  <h2 class="section-title"><?php the_category(' '); ?></h2>

  <?php
  if ( $my_loop->have_posts() ) :

  /* Start the Loop */
  while ( $my_loop->have_posts() ) :
    $my_loop->the_post();

    get_template_part( 'template-parts/content');

  endwhile;

  else :
   get_template_part( 'template-parts', 'none' );

  endif;

  // CLOSE THE HTML SECTION tag that was opened at START of the LOOP.
  // I AM USING ECHO HERE to stay in PHP, but we could 
  // open and close each language if we wanted to.
   echo "</section>";

   wp_reset_postdata();
} // end foreach

Test your page. If you inspect the code, you will now see each loop of articles wrapped in a SECTION tag:

In addition, we have tried to dynamically create classes that reflect the category of the content pulled with each loop. We did that by pulling the category name (using $section[‘category_name’]) each time through the loop and using the PHP echo command to append it to the section- class in our code.

So far, so good. But, there’s a problem.

If you go to the H2 with a class of section-title in template file, you will see that we are using the_category() in hopes of making a title at the top of the section that links to the respective category archive (before the output of the articles in that category).

The problem? It’s giving us the wrong category each time.

For example, our first loop pulls headline material, but the_category() outputs a link to the CULTURE category. The OPINIONS loop is outputting the HEADLINES category. Etc.

The reason for this is that on its own, the_category() works only within the WHILE part of the loop.

Here, we’re outside it. This is because we don’t want to repeatedly output the category name with every pass through the WHILE loop (it would put the category name in front of every article if we did that).

We want, remember, to output the category name as a section heading (with a link to the relevant category archive), then output the articles in that section.

Fortunately, we can retrieve the correct category name by using the database ID of the desired category and then build the link to the category archives with it.

But how to get the database ID for each category? For that, we can use the category name, which we already have in our arrays. From there, we can get the category link too.

Add the following to your code right after the $my_loop = new WP_Query( $section ); line:

$category_name = $section['category_name'];
$category_id = get_cat_id( $category_name );
$category_link = get_category_link( $category_id );

References:
https://codex.wordpress.org/Function_Reference/get_cat_ID, https://codex.wordpress.org/Function_Reference/get_category_link

We can thus replace our earlier h2.section-title with the following:

<h2 class="section-title">
 <a href="<?php echo esc_url( $category_link ); ?>">
       <?php echo $category_name; ?>
    </a>
</h2>

Test the front page of the site. The h2s should now display the correct section name and link to the correct category archive.

If it’s not working, check that your foreach loop looks like this:

foreach ( $sections as $section ) {
  $my_loop = new WP_Query( $section );

  $category_name = $section['category_name'];
  $category_id = get_cat_id( $category_name );
  $category_link = get_category_link( $category_id );

// close PHP so you can add HTML
?>

  <!-- Add Sectioning HTML -->
  <section class="section-<?php echo $section['category_name']; ?>">
    <h2 class="section-title">
      <a href="<?php echo esc_url( $category_link ); ?>">
        <?php echo $category_name; ?>
     </a>
    </h2>

  <?php
  if ( $my_loop->have_posts() ) :

  /* Start the Loop */
  while ( $my_loop->have_posts() ) :
    $my_loop->the_post();

    get_template_part( 'template-parts/content');

  endwhile;

  else :
   get_template_part( 'template-parts/content', 'none' );

  endif;

  // CLOSE THE SECTION that was opened at START of each LOOP.
  echo "</section>";

  wp_reset_postdata();

} // end foreach

Let’s now move on, adding a couple more tweaks to content.php in order to output gravatars and author links in the Opinion section.