How to add multiple custom fields to a wp_query in a shortcode?

In a shortcode I can limit wp_query results by custom field values.

Example:

Read More
[my-shortcode meta_key=my-custom-field meta_value=100,200 meta_compare='IN']

And obviously it’s possible to use multiple custom fields in a wp_query like WP_Query#Custom_Field_Parameters

But how can I use multiple custom fields in my shortcode? At the moment I do pass all the shortcode parameters with $atts.

Related posts

1 comment

  1. On of a few different solutions might be to use a JSON encoded format for the meta values. Note that this isn’t exactly user-friendly, but certainly would accomplish what you want.

    You would of course need to generate the json encoded values first and ensure they are in the proper format. One way of doing that is just using PHP’s built in functions:

    // Set up your array of values, then json_encode them with PHP
    $values = array(
        array('key' => 'my_key',
            'value' => 'my_value',
            'operator'  => 'IN'
        ),
        array('key' => 'other_key',
            'value' => 'other_value',
        )
    );
    
    echo json_encode($values);
    // outputs: [{"key":"my_key","value":"my_value","operator":"IN"},{"key":"other_key","value":"other_value"}]
    

    Example usage in the shortcode:

    [my-shortcode meta='[{"key":"my_key","value":"my_value","operator":"IN"},{"key":"other_key","value":"other_value"}]']
    

    Which then you would parse out in your shortcode function, something like so:

    function my_shortcode($atts ) {
        $meta = $atts['meta'];
        // decode it "quietly" so no errors thrown
        $meta = @json_decode( $meta );
        // check if $meta set in case it wasn't set or json encoded proper
        if ( $meta && is_array( $meta ) ) {
            foreach($meta AS $m) {
                $key = $m->key;
                $value = $m->value;
                $op = ( ! empty($m->operator) ) ? $m->operator : '';
    
                // put key, value, op into your meta query here....
            }
        }
    }
    

    Alternate Method
    Another method would be to cause your shortcode to accept an arbitrary number of them, with matching numerical indexes, like so:

    [my-shortcode meta-key1="my_key" meta-value1="my_value" meta-op1="IN
        meta-key2="other_key" meta-value2="other_value"]
    

    Then, in your shortcode function, “watch” for these values and glue them up yourself:

    function my_shortcode( $atts ) {
        foreach( $atts AS $name => $value ) {
            if ( stripos($name, 'meta-key') === 0 ) {
                $id = str_ireplace('meta-key', '', $name);
                $key = $value;
                $value = (isset($atts['meta-value' . $id])) ? $atts['meta-value' . $id] : '';
                $op = (isset($atts['meta-op' . $id])) ? $atts['meta-op' . $id] : '';
    
                // use $key, $value, and $op as needed in your meta query
    
            }
        }
    }
    

Comments are closed.