0

My Wordpress site uses categories to group product information into subcategories. As an example, for an automobile the parent category is Brand and the subcategories include Honda, Toyota, Ford, etc. Sometimes more than one subcategory can be assigned to a post. Also, sometimes a parent+child category is never assigned to a post. I'm using a custom page template.

My code works but I'm concerned it is inefficient and slowing down my site.

Here are the basics:

functions.php

global $reviews_cat_id_brand;
$reviews_cat_id_brand = 158; // using # in case string changes

if( !function_exists('reviews_has_subcat_link') ){
  function reviews_has_subcat_link($cat_id){
    $taxonomy_name = 'review-category';
    // store category data in array
    $cat_array = get_term_by('id', $cat_id, $taxonomy_name);
    $terms = get_the_terms(get_the_ID(), $taxonomy_name);

    foreach ($terms as $term) {
      if($term->parent === $cat_array->term_id) {
        return true;
      }
    }
  }
}

if( !function_exists('reviews_print_subcat_link') ){
  function reviews_print_subcat_link($cat_id){
    $taxonomy_name = 'review-category';
    // store category data in array
    $cat_array = get_term_by('id', $cat_id, $taxonomy_name);
    $terms = get_the_terms(get_the_ID(), $taxonomy_name);
    $subcat_array = [];

    foreach ($terms as $term) {
      if($term->parent === $cat_array->term_id) {
        $subcat_array[] = '<a href="'.get_term_link($term).'">'.$term->name.'</a>';
      }
    }
    echo implode(', ', $subcat_array);
  }
}

review-page.php

<?php if( reviews_has_subcat_link($reviews_cat_id_brand) ): ?>
  <tr><td>Brand:</td>
  <td><?php reviews_print_subcat_link($reviews_cat_id_brand); ?></td></tr>
<?php endif; ?>

That's about it. Each review page has about 6 of these subcategory checks and the site has a few hundred pages. Is there a better way to do this?

In the Wordpress editor I have the parent category checked when a subcategory is present. Ideally I'd like to detect if a parent is checked and then display the selected children without looping through everything every single time.

Thanks in advance for any guidance.

0

After looking at get_the_terms() again I think I found a better solution:

functions.php

global $reviews_cat_id_brand;
$reviews_cat_id_brand = 158; // using # in case string changes

if( !function_exists('reviews_print_subcat_link') ){
      function reviews_print_subcat_link($cat_id){
        $items = get_the_terms(get_the_ID(), 'review-category');
        $subcat_array = [];

        foreach ($items as $item) {
            if($item->parent === $cat_id) {
                $subcat_array[] = '<a href="'.get_term_link($item).'">'.$item->name.'</a>';
            }
        }
        return $subcat_array;
      }
    }

review-page.php

$reviews_subcat_links_brand = reviews_print_subcat_link($reviews_cat_id_brand);

if ($reviews_subcat_links_brand) {
  echo '<tr><td>Brand:</td>';
  echo '<td>'.implode(', ', $reviews_subcat_links_brand).'</td></tr>';
}

There still might be a better solution but this cuts down the looping quite a bit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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