Search code examples
phpwordpresswoocommercehook-woocommerceshortcode

How to append a custom meta field as a shortcode argument value in WooCommerce


I have created a custom checkbox field _is_group and i would like to be able to use this in the [products...] shortcode.

The currently used workaround is that I create the query with wc_get_products() first and then pass the returned IDs to the standard shortcode, with implode() function:

$group = wc_get_products([
    'post_type'     => 'product',
    'meta_key'      => '_is_group',
    'meta_value'    => 'yes',
    'meta_compare'  => 'IN',
    'return'        => 'ids'
]);

echo do_shortcode('[products ids="' . implode(',', $group) . '"]');

Sure it works, but it looks ugly, making unnecessarily two db queries instead of one. I think there is a better way to deal with it, something like that:

[products columns="3" is_group="yes"]

So I decided to ask how to append a custom meta field as a shortcode argument value in Woocommerce . Maybe the solution is to use woocommerce_shortcode_products_query or something else?

Note: I've seen other similar questions and solutions like using custom shortcode inside another shortcode, but that doesn't solve the problem. I care about optimization


Solution

  • You need two parts:

    1. Support your own attribute for the [products] shortcode.

    // Add your own attribute
    function filter_shortcode_atts_products( $out, $pairs, $atts, $shortcode ) {
        // Isset and equal to yes
        if ( isset ( $atts['is_group'] ) && $atts['is_group'] == 'yes' ) {
            $out['is_group'] = true;
        } else {
            $out['is_group'] = false;
        }
        
        return $out;
    }
    add_filter( 'shortcode_atts_products', 'filter_shortcode_atts_products', 10, 4 );
    
    1. Modify the query to use your $query_args
    // Modify the query args 
    function filter_woocommerce_shortcode_products_query( $query_args, $atts, $type ) {
        // Target
        if ( $type == 'products' && $atts['is_group'] ) {
            // Meta query       
            $query_args['meta_query'] = array(
                array(
                    'key'     => '_is_group',
                    'value'   => 'yes',
                    'compare' => 'IN',
                )
            );
        }
    
        return $query_args;
    }
    add_filter( 'woocommerce_shortcode_products_query', 'filter_woocommerce_shortcode_products_query', 10, 3 );
    

    SHORTCODE USAGE

    In an existing page:

    [products columns="3" is_group="yes"]

    Or in PHP:

    echo do_shortcode('[products columns="3" is_group="yes"]');