Shortcode with multiple meta_key attributes - wordpress

I added two custom fields: day (event_day) & month (event_month) (both of type radio) for CPT Events. Now i want to be able to get posts by meta_key day and month.
The shortcode works except the part with $meta_query.
Here is how shorŠµcode should look like :
[tribe_custom_events_list_mm_wed cat="Rodrigo" num="6" day="Monday" month="October"]
Bellow is the code responsible for the shortcode, added in functions.php
function tribe_custom_events_shortcode($atts, $content = null)
{
global $post;
extract(shortcode_atts(array(
'cat' => '',
'num' => '',
'order' => 'ASC',
'orderby' => 'post_date',
'taxonomy' => 'tribe_events_cat',
'field' => 'name',
'day' => '',
'month' => '',
), $atts));
$tax_query = array(
'taxonomy' => $taxonomy,
'field' => $field,
'terms' => $cat,
);
$day = $day;
$month = $month;
$meta_query = array(
array(
'key' => 'event_day',
'value' => '$day',
'compare' => '='
),
array(
'key' => 'event_month',
'value' => '$month',
'compare' => '='
),
);
$args = array(
'post_type' => 'tribe_events',
'posts_per_page' => $num,
'order' => $order,
'orderby' => $orderby,
'tax_query' => array($tax_query),
'meta_query' => array($meta_query),
);
$output = '';
$posts = get_posts($args);
foreach ($posts as $post) {
setup_postdata($post);
$output .= '<div class="tribe-mini-calendar-event event-0 first last">';
$output .= '<h4 class="tribe-events-title">' . get_the_title() . '</h4>';
$output .= '</div>';
}
echo '<pre>' , var_dump($meta_query) , '</pre>';
wp_reset_postdata();
return '<div>' . $output . '</br>' . '</div>';
}
add_shortcode('tribe_custom_events_list_mm_wed', 'tribe_custom_events_shortcode');

This should work for you. There were a few errors in your code... Noted in the comments below.
$tax_query = array(
'taxonomy' => $taxonomy,
'field' => $field,
'terms' => $cat,
);
/* This is unnecessary since $day already = $day
$day = $day;
$month = $month;
*/
$meta_query = array(
array(
'key' => 'event_day',
'value' => $day, // Don't put quotes around variables
'compare' => '='
),
array(
'key' => 'event_month',
'value' => $month,
'compare' => '='
),
);
$args = array(
'post_type' => 'tribe_events',
'posts_per_page' => $num,
'order' => $order,
'orderby' => $orderby,
'tax_query' => $tax_query, // This is already an array defined above
'meta_query' => $meta_query,
);

Related

WP Bakery woocommerce show product subcategory (FREE)

I wanted to share this work with you since I did not find any solution on the internet, so I had to build mine.
The problem was that the client wanted to show the subcategories within the main category using a shortcode. Only the name of the subcategories, without thumbnail or number of products.
So create a file called "products-subcategory.php" in plugins/bezel-addons/vc/shortcodes/.
And I incorporated it in plugins/bezel-addons/vc/shortcodes.php
In my case my template is the Bezzel https://themeforest.net/item/bezel-creative-multipurpose-wordpress-theme/20014332
But I think you can implement it in anyone using Visual Composer or WP Bakery.
products-subcategory.php.
<?php
/* Product subcategory */
vc_map(
array(
'name' => 'Product subcategory',
'base' => 'bezel_products_subcategory',
'icon' => 'ti-align-left',
'description' => 'Product subcategories',
'category' => __( 'Bezel', 'bezel-addons'),
'params' => array(
array(
'type' => 'dropdown',
'param_name' => 'orderby',
'heading' => 'Order BY',
'value' => array(
'Name' => 'name',
'ID' => 'term_id'
),
),
array(
'type' => 'dropdown',
'param_name' => 'order',
'heading' => 'Order',
'value' => array(
'Upward' => 'ASC',
'Falling' => 'DESC'
),
),
array(
'type' => 'dropdown',
'param_name' => 'empty',
'heading' => 'Show empty subcategories',
'value' => array(
'Yes' => 0,
'No' => 1
),
)
)
)
);
add_shortcode( 'bezel_products_subcategory', 'bezel_products_subcategory' );
function bezel_products_subcategory( $atts ) {
global $wp_query;
extract( shortcode_atts( array(
'taxonomy' => 'product_cat',
'orderby' => 'name',
'order' => 'ASC',
'empty' => 0,
'hierarchical' => 1
), $atts ) );
$cat = get_queried_object();
$category_id = ($cat->parent) ? $cat->parent : $cat->term_id;
$args2 = array('taxonomy' => $taxonomy,'parent' => $category_id,'hierarchical' => $hierarchical, 'orderby' => $orderby, 'order' => $order,'hide_empty' => $empty);
$categories = get_categories( $args2 );
$categories_cnt = count(get_categories( $args2 ));
$selcat[$cat->term_id] = 'current-cat';
if ($categories_cnt != 0){
$sub_cats = get_categories( $args2 );
if($sub_cats) {
$output = '<div class="vc_wp_categories wpb_content_element">';
$output .= '<div class="widget widget_categories">';
$output .= '<ul>';
foreach($sub_cats as $sub_category) {
$output .= '<li class="cat-item cat-item-'.$sub_category->term_id.' '.$selcat[$sub_category->term_id].'">'.$sub_category->cat_name.'</li>';
}
$output .= '</ul>';
$output .= '</div>';
$output .= '</div>';
}
}
return $output;
}
?>

show posts with And relation in categories at WordPress

I want to show posts which have categories (a,b and c) with And Relation in query.
I wrote the below code but it shows all the posts that have each of categories. How to show those posts that have all 3 categories with And relation?
<?php
$args2 = array(
'post_type' => 'post' ,
'orderby' => 'date' ,
'order' => 'DESC' ,
'posts_per_page' => 6,
'relation' => 'And',
'category_name'=>'a','b','c',
'paged' => get_query_var('paged'),
'post_parent' => $parent
);
$q = new WP_Query($args2);
if ( $q->have_posts() ) {
while ( $q->have_posts() ) {
$q->the_post();
echo the_title();
}
}
?>
I added a tax query, now it checks if a post has categorie a, b or parent of b and the location set.
$args2 = array(
'post_type' => 'post',
'orderby' => 'date',
'order' => 'DESC',
'posts_per_page' => -1,
'tax_query' => array(
// If 'a' is set.
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array( 'a' ),
'operator' => 'IN'
),
// AND if 'b' OR 'parent_b' is set.
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array( 'b', 'parent_b' ),
'operator' => 'IN'
),
// AND if location is set.
array(
'taxonomy' => 'location',
'operator' => 'EXISTS'
),
)
);
$q = new WP_Query( $args2 );
if( $q->have_posts() ) {
while ( $q->have_posts() ) {
$q->the_post();
echo the_title();
}
}

Allow multiple value in shortcode for custom meta field value in wordpress shortcode

I have a shortcode which is working fine if iI put the single value for "rank" in shortcode.
[coaches_list category="dummy" number="3" rank="2"]
But I want to pass multiple values in "rank" as [coaches_list category="dummy" number="3" rank="2", "6"].
'rank' is a numeric type custom field associated with post.
I have searched alot on internet from last 2 days but found no result. Please let me know where I am having mistake.
Here is the piece of shortcode I bulit:
$args = array(
'number' => '-1',
'orderby' => 'id',
'order' => 'desc',
'category' => '',
'meta_key' => '',
'rank' => '',
), $atts )
);
global $post;
$html = "";
$my_query = new WP_Query( array('post_type' => 'post',
'posts_per_page' => $number, 'orderby' => $orderby, 'order' => $order, 'category' =>$category, 'meta_key' => 'rank', 'meta_value' => $rank ));
if( $my_query->have_posts() ) : while( $my_query->have_posts() ) : $my_query->the_post();
I'd go for [coaches_list category="dummy" number="3" rank="2,6"]
And then you could make an array $ranks = explode(',',$rank);.
function my_shortcode($atts){
extract(shortcode_atts( $args = array(
'number' => '-1',
'orderby' => 'id',
'order' => 'desc',
'category' => '',
'meta_key' => '',
'rank' => '',
),$atts));
$ranks = explode(',',$rank);
$html = '<ul>';
$my_posts = get_posts(array(
'post_type' => 'post',
'posts_per_page' => $number,
'orderby' => $orderby,
'order' => $order,
'category' =>$category,
'meta_query' => array(
'key'=>'rank',
'value'=>$ranks,
'compare'=>'IN'
)
));
foreach($my_posts as $rankpost){
$html .= '<li>'.$rankpost->ID.': '.get_the_title($rankpost->ID).' - Rank: '.get_post_meta($rankpost->ID,'rank',true).'</li>';
}
$html .= '</ul>';
return $html;
}
Or maybe you could create a query that gives out all post with rank=2 AND/OR rank=6.

Wordpress get only posts with matching title not content

Currently with this code below, I get posts whose title or description contains search keyword. How do I change it, so I only get posts whose title contains search keyword.
$search_keyword = esc_attr( $_REQUEST['query'] );
$ordering_args = $woocommerce->query->get_catalog_ordering_args( 'title', 'asc' );
$suggestions = array();
$args = array(
's' => apply_filters( 'yith_wcas_ajax_search_products_search_query', $search_keyword ),
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'orderby' => $ordering_args['orderby'],
'order' => $ordering_args['order'],
'posts_per_page' => apply_filters( 'yith_wcas_ajax_search_products_posts_per_page', get_option( 'yith_wcas_posts_per_page' ) ),
'meta_query' => array(
array(
'key' => '_visibility',
'value' => array( 'search', 'visible' ),
'compare' => 'IN'
)
)
);
if ( isset( $_REQUEST['product_cat'] ) ) {
$args['tax_query'] = array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $_REQUEST['product_cat']
) );
}
$products = get_posts( $args );
I was trying to add one more query but only make it worse.

How to simplify my WP_Query(s)?

Can anybody help me to simplify the WP_Query(s) below please? They have the very same structure, but one to target the future, and one for past events.
<?php
$future = date('Ymd', strtotime("+1 year"));
$now = date('Ymd', strtotime("now"));
$past = date('Ymd', strtotime("-1 year"));
?>
<?php
$args_future = array(
'post_type' => 'event',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'event_date',
'value' => array($now, $future),
'type' => 'numeric',
'compare' => 'BETWEEN'
)
)
);
$query_future = new WP_Query($args_future);
?>
<?php
echo '<h2>Future events</h2><ul class="future-events">';
while($query_future->have_posts()) {
$query_future->the_post();
echo '<li>'.get_the_title().'</li>';
} echo '</ul>'; wp_reset_postdata();
?>
<?php
$args_past = array(
'post_type' => 'event',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'event_date',
'value' => array($past, $now),
'type' => 'numeric',
'compare' => 'BETWEEN'
)
)
);
$query_past = new WP_Query($args_past);
?>
<?php
echo '<h2>Past events</h2><ul class="past-events">';
while($query_past->have_posts()) {
$query_past->the_post();
echo '<li>'.get_the_title().'</li>';
} echo '</ul>'; wp_reset_postdata();
?>
Your code isn't too bad. Splitting it into several loops is pretty much unavoidable in this case if you want to maintain readability. All I did here was organize your code into a multidimensional array. This is untested, but should get you started:
<?php
$future = date('Ymd', strtotime("+1 year"));
$now = date('Ymd', strtotime("now"));
$past = date('Ymd', strtotime("-1 year"));
$args = array(
'future'=>array(
'ul_class'=>'future-events',
'label'=>'Future Events',
'query_args'=>array(
'post_type' => 'event',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'event_date',
'value' => array($now, $future),
'type' => 'numeric',
'compare' => 'BETWEEN'
)
)
)
),
'past'=>array(
'ul_class'=>'past-events',
'label'=>'Past Events',
'query_args'=>array(
'post_type' => 'event',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'event_date',
'value' => array($past, $now),
'type' => 'numeric',
'compare' => 'BETWEEN'
)
)
)
)
);
foreach($args as $arg){
$q = new WP_Query($arg['query_args']);
printf('<h2>%s</h2><ul class="%s">', $arg['label'], $arg['ul_class']);
while($q->have_posts()) : $q->the_post();
echo '<li>'.get_the_title().'</li>';
endwhile;
echo '</ul>';
}
wp_reset_postdata();
?>

Resources