Skip Navigation

[Resolved] Create a View of related posts on a taxonomy archive

This thread is resolved. Here is a description of the problem and solution.

Problem: I would like to display a list of related posts on a taxonomy term archive. Related posts should be posts with terms that are siblings of the current archive term.

Solution:
- Create a View of these posts filtered by the same taxonomy, where the taxonomy term slug is set by one shortcode attribute.
- Use a custom shortcode to get the parent term slug based on the current archive term slug.

function get_term_parent_func($atts) {
  $a = shortcode_atts( array(
      'taxonomy' => '',
      'return' => 'id'
  ), $atts );
  $taxonomy = $a['taxonomy'];
  $parent_id = 0;
  if( is_tax( $taxonomy ) ) {
    $taxObj = get_queried_object();
    $tax = isset($taxObj->taxonomy) ? $taxObj->taxonomy : 0;
    $term = isset($taxObj->term_id) ? $taxObj->term_id : 0;
    $parent_slugs = get_term_parents_list( $term, $tax, array('format'=>'slug', 'link'=>FALSE, 'inclusive'=>FALSE, 'separator'=>','));
    $parent_slugs = explode(',', $parent_slugs);
    $depth = sizeof($parent_slugs) - 1;
    $parent_slug = ($depth === 0) ? $taxObj->slug : $parent_slugs[$depth-1];
    if( $a['return'] == 'id' ) {
      $parent = get_term_by( 'slug', $parent_slug, $tax );
      $parent_id = isset($parent->term_id) ? $parent->term_id : $taxObj->term_id;
      return $parent_id;
    }
 
    if( $a['return'] == 'slug' ) {
      return $parent_slug;
    }
  }
  return $parent_id;
}
add_shortcode("get_term_parent", "get_term_parent_func");

- Pass that value into your View of posts as a shortcode attribute:

[wpv-view name="products-in-parent-term" wpvproductcat="[get_term_parent taxonomy='product_cat' return='slug']"]

- Register the get_term_parent shortcode in Toolset > Settings > Third party shortcode arguments
- Apply a custom filter using PHP that will filter out all the posts in the current term archive, to prevent duplicates.

add_filter( 'wpv_filter_query', 'not_this_term_filter',99,3 );
function not_this_term_filter( $query_args, $views_settings, $view_id) {
  $view_ids = array( 1234 );
  $tax = 'product-categories';
  $taxObj = get_queried_object();
  $tax = isset($taxObj->taxonomy) ? $taxObj->taxonomy : 0;
  $term_id = isset($taxObj->term_id) ? $taxObj->term_id : 0;
  if (in_array($view_id, $view_ids)){
    $query_args['tax_query'][] = array(
      'taxonomy' => $tax,
      'field' => 'id',
      'terms' => $term_id,
      'operator' => 'NOT IN'
    );
  }
  return $query_args;
}

Relevant Documentation:
https://toolset.com/documentation/user-guides/passing-arguments-to-views/
https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query

This support ticket is created 6 years, 3 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Our next available supporter will start replying to tickets in about 0.96 hours from now. Thank you for your understanding.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 8 replies, has 2 voices.

Last updated by Tcoffee 6 years, 3 months ago.

Assisted by: Christian Cox.

Author
Posts
#953138
952287-1_min.jpg

I want to show similar products on a child term archive & sub child term archive pages ( similar products = products come under same parent taxonomy (eg: in the product page, first it should list the products of the current child term and list products of remaining child terms of the same parent below that. see screenshot1)

#953202

We will reuse the same custom shortcode from the other ticket. For reference:

function get_term_parent_func($atts) {
  $a = shortcode_atts( array(
      'taxonomy' => '',
      'return' => 'id'
  ), $atts );
  $taxonomy = $a['taxonomy'];
  $parent_id = 0;
  if( is_tax( $taxonomy ) ) {
    $taxObj = get_queried_object();
    $tax = isset($taxObj->taxonomy) ? $taxObj->taxonomy : 0;
    $term = isset($taxObj->term_id) ? $taxObj->term_id : 0;
    $parent_slug = get_term_parents_list( $term, $tax, array('format'=>'slug', 'link'=>FALSE, 'inclusive'=>FALSE, 'separator'=>''));
    if( $a['return'] == 'id' ) {
      $parent = get_term_by( 'slug', $parent_slug, $tax );
      $parent_id = isset($parent->term_id) ? $parent->term_id : $taxObj->term_id;
      return $parent_id;
    }

    if( $a['return'] == 'slug' ) {
      return $parent_slug;
    }
  }
  return $parent_id;
}
add_shortcode("get_term_parent", "get_term_parent_func");

- Create a View of Products, filtered by Product Category, where the Product Cat slug is set by one shortcode attribute wpvproductcat.
- In the Loop Output editor, create your design to be applied to each Product in the list
- Insert this View in your WordPress Archive for the Product Category taxonomy, and use the custom shortcode to pass in the slug of the parent term:

[wpv-view name="products-in-parent-term" wpvproductcat="[get_term_parent taxonomy='product_cat' return='slug']"]

- Add one more piece of custom code to your functions.php file which will filter out products in the current archive:

add_filter( 'wpv_filter_query', 'not_this_term_filter',99,3 );
function not_this_term_filter( $query_args, $views_settings, $view_id) {
  $view_ids = array( 1234 );
  $tax = 'product_cat';
  $taxObj = get_queried_object();
  $tax = isset($taxObj->taxonomy) ? $taxObj->taxonomy : 0;
  $term_id = isset($taxObj->term_id) ? $taxObj->term_id : 0;
  if (in_array($view_id, $view_ids)){
    $query_args['tax_query'][] = array(
      'taxonomy' => $tax,
      'field' => 'id',
      'terms' => $term_id,
      'operator' => 'NOT IN'
    );
  }
  return $query_args;
}

Replace 1234 with the numeric ID of this View.

#953575
sub-child-term-archive.png
child-term archive page.png

Hi,
The solution works perfectly in child term archive page, but not in sub-child term archive page.

When the view is inserted in the sub child archive page, it is showing no items found.

I have inserted the shortcode

[get_term_parent taxonomy='product-categories' return='slug'] 

directly to both archive pages and i have attached screen shots for both the pages.

the shortcode is outputting both ancestors when added in the sub-child archive page, I think that's why it is not showing any products.

Anyway, please take a look and help me out with this.

#953740

The slug of the WooCommerce Product Category taxonomy is actually "product_cat", but it looks like your code uses "product-categories". Try modifying that slug to be "product_cat" and let me know the results.

#953792

Hi,
I'm not using woocommerce for this project and it is a custom taxonomy "product-categories" which i'm using.

Sorry for not making it clear at the first place.

#953870

Is the same View used in both the child and subchild archive? If so, then the filter we added will strip out the results on the subchild archive. To fix this, duplicate the View and replace the original View with the duplicate View in the subchild archive. Leave the original View in the child archive. The 'not_this_term_filter' will no longer be applied to the subchild archive, and should resolve that problem.

Be sure to modify the filter code to use the correct taxonomy slug, since I misunderstood your requirements:

add_filter( 'wpv_filter_query', 'not_this_term_filter',99,3 );
function not_this_term_filter( $query_args, $views_settings, $view_id) {
  $view_ids = array( 1234 );
  $tax = 'product-categories';
...
#954390

Hi Christian,

I have tried that solution but getting the same result and I think you haven't got my point.

The view shortcode is inserted in archive page with a shortcode attribute

 wpvproductcategories = [get_term_parent taxonomy='product-categories' return='slug'].

when I add this shortcode (

[get_term_parent taxonomy='product-categories' return='slug']

) on the child archive page I'm getting parent taxonomy slug of the current child archive page .

When I add the same in sub-child archive page I'm getting the slug of the immediate parent and parent of the immediate parent
(ex: in Mono Single Function Page I'm getting the following value: printers-a4laserjet-printer. ie, the slug of its immediate parent( laserjet-printer ) and parent of the immediate parent (printers-a4).

[wpv-view name="similar-products-in-sub-child-term-view" wpvproductcategories="[get_term_parent taxonomy='product-categories' return='slug']"] 

will work properly only if the shortcode

[get_term_parent taxonomy='product-categories' return='slug']

outputs only the slug of its immediate parent taxonomy.

so, please help me to achieve the desired result.

#954514

Okay I see, there was a logic bug in the code. Here's an update:

function get_term_parent_func($atts) {
  $a = shortcode_atts( array(
      'taxonomy' => '',
      'return' => 'id'
  ), $atts );
  $taxonomy = $a['taxonomy'];
  $parent_id = 0;
  if( is_tax( $taxonomy ) ) {
    $taxObj = get_queried_object();
    $tax = isset($taxObj->taxonomy) ? $taxObj->taxonomy : 0;
    $term = isset($taxObj->term_id) ? $taxObj->term_id : 0;
    $parent_slugs = get_term_parents_list( $term, $tax, array('format'=>'slug', 'link'=>FALSE, 'inclusive'=>FALSE, 'separator'=>','));
    $parent_slugs = explode(',', $parent_slugs);
    $depth = sizeof($parent_slugs) - 1;
    $parent_slug = ($depth === 0) ? $taxObj->slug : $parent_slugs[$depth-1];
    if( $a['return'] == 'id' ) {
      $parent = get_term_by( 'slug', $parent_slug, $tax );
      $parent_id = isset($parent->term_id) ? $parent->term_id : $taxObj->term_id;
      return $parent_id;
    }

    if( $a['return'] == 'slug' ) {
      return $parent_slug;
    }
  }
  return $parent_id;
}
add_shortcode("get_term_parent", "get_term_parent_func");
#955548

Hi Christian,
Thanks for the valuable help throughout the ticket. It has been very easy to understand and implement the coding part.