skip to Main Content

I’m using polylang plugin to having multi-languages website.

Using WooCommerce with polylang demands duplicating each product for each language, so assuming I have Hebrew and English, that means 2 duplications for each products.

It works fine with WooCommerce plugin, but when I’m displaying "related products" at the end of the product page, it’s mixing products in English and Hebrew together.

I expect to filter the related product by website current language (if(get_locale() == 'en_US') – to check website current locale state, else will represent Hebrew).

Polylang functions

Here is what I have tried, but I got stuck on the part of filtering the product by language:

add_filter( 'woocommerce_product_related_posts', 'custom_related_products' );
function custom_related_products($product){
    global $woocommerce;
    // Meta query
    $meta_query = array();
    $meta_query[] = $woocommerce->query->visibility_meta_query();
    $meta_query[] = $woocommerce->query->stock_status_meta_query();
    $meta_query   = array_filter( $meta_query );
    // Get the posts
    $related_posts = get_posts( array(
            'orderby'        => 'rand',
            'posts_per_page' => '4',
            'post_type'      => 'product',
            'fields'         => 'ids',
            'meta_query'     => $meta_query
        ) );

        if ( $related_posts->have_posts() ) {
          while ( $related_posts->have_posts() ) : $related_posts->the_post();
            if(pll_get_post_language(get_the_ID())){
               //Not sure its the right approach for this..
            }
          endwhile;
        }
    $related_posts = array_diff( $related_posts, array( $product->id ), $product->get_upsells() );
    return $related_posts;
}

How can I filter Woocommerce related product section by language?

Edit

So after a little bit of research and help in the comments I found out that 'lang' => 'en' argument does exist, but even when I use it, there is no change on related products language display.
Any ideas?

4

Answers


  1. You can try this code:

    $related_posts = get_posts( array(
        'orderby'        => 'rand',
        'posts_per_page' => '4',
        'post_type'      => 'product',
        'meta_query'     => $meta_query,
        'lang'           => 'en'
    ) );
    
    if ($related_posts) {
        foreach ($related_posts as $post) {
            setup_postdata($post);
            // something like <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
        }
    }
    
    wp_reset_postdata();
    

    This code correctly returns code in selected language on my site

    Login or Signup to reply.
  2. add_filter( 'woocommerce_product_related_posts', 'custom_related_products' );
    function custom_related_products($product){
        global $woocommerce;
        // Meta query
        $meta_query = array();
        $meta_query[] = $woocommerce->query->visibility_meta_query();
        $meta_query[] = $woocommerce->query->stock_status_meta_query();
        $meta_query   = array_filter( $meta_query );
        // Get the posts
        $related_posts = get_posts( array(
                'orderby'        => 'rand',
                'posts_per_page' => '4',
                'post_type'      => 'product',
                'fields'         => 'ids',
                'meta_query'     => $meta_query,
                'suppress_filters' => false
            ) );
    
            if ( $related_posts->have_posts() ) {
              while ( $related_posts->have_posts() ) : $related_posts->the_post();
                if(pll_get_post_language(get_the_ID())){
                   //Not sure its the right approach for this..
                }
              endwhile;
            }
        $related_posts = array_diff( $related_posts, array( $product->id ), $product->get_upsells() );
        return $related_posts;
    }
    

    suppress_filters There is a way to make get_posts cache the results however, the suppress_filters option is true by default, but if you set it to false, the caching mechanisms inside WordPress will do their work, and results will be saved for later.

    Login or Signup to reply.
  3. While working on a custom WordPress REST Api end point to fetch post by selected language or device language, this worked. See if it can help you out.

    function mycustomplugin_posts($params) {
        // get the url params
    
        $page = $params->get_param('page') ? $params->get_param('page') : 0;
        $per_page = $params->get_param('per_page') ? $params->get_param('per_page') : 10;
        $offset = $params->get_param('offset') ? $params->get_param('offset') : 0;
        $order = $params->get_param('order') ? $params->get_param('order') : 'desc';
        $order_by = $params->get_param('order_by') ? $params->get_param('order_by') : 'date';
        $lang = array_search($params->get_param('lang'),polylang_json_api_languages(), true) ? $params->get_param('lang') : pll_default_language();
        
        $args = [
            'post_type' => 'post',
            'page' => $page,
            'numberposts' => $per_page,
            'offset' => $offset,
            'order' => $order,
            'orderby' => $order_by,
            'tax_query' => [
                [
                    'taxonomy'  => 'language',
                    'field'     => 'slug',
                    'terms'     => $lang
                ]
            ]
        ];
    
        $posts = get_posts($args);
        $data = [];
        $i = 0;
    
        foreach($posts as $post) {
            
            // Extract the post data
    
            $data[$i]['id'] = $post->ID;
            $data[$i]['title'] = $post->post_title;
            $data[$i]['content'] = $post->post_content;
            $data[$i]['excerpt'] = e42_the_short_content($post->post_content, 300);
            $data[$i]['slug'] = $post->post_name;
            $data[$i]['date'] = $post->post_date;
            $data[$i]['link'] = get_permalink($post->ID);
            $data[$i]['author'] = get_the_author_meta('display_name', $post->post_author);
            $data[$i]['categories'] = array();
            $data[$i]['featured_image']['thumbnail'] = get_the_post_thumbnail_url($post->ID, 'thumbnail');
            $data[$i]['featured_image']['medium'] = get_the_post_thumbnail_url($post->ID, 'medium');
            $data[$i]['featured_image']['large'] = get_the_post_thumbnail_url($post->ID, 'large');
            
            foreach(get_the_category($post->ID) as $category){
                array_push($data[$i]['categories'],$category->term_id);
            }
            $i++;
        }
        
        // Create the response object
    
        $response = new WP_REST_Response( $data );
    
        // Add a custom status code
    
        $response->set_status( 200 );
        return $response;
    }
    
    Login or Signup to reply.
  4. /plugins/woocommerce/templates/single-product/related.php
    Move this to child theme
    yourtheme/woocommerce/single-product/related.php

    And add the following line to the foreach loop

    if (pll_current_language()!=pll_get_post_language($post_object->ID)) {
        continue;
    }
    

    Basically if current language does not match product language we skip over it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search