Sorry but not work.
I have create a post child with a multicheckboxes field called 'size' (wpcf-size).
Post child of products woocommerce.
I want display all product with a selected size for example 12,40.
I have create this function
add_action( 'woocommerce_product_query', 'so_27971630_product_query' );
function so_27971630_product_query( $q ){
$meta_query = $q->get( 'meta_query' );
$meta_query[] = array(
array(
array(
'relation' => 'OR',
array(
'key' => 'wpcf-size',
'value' => $_GET['size'],
'compare' => 'IN'
)
)
)
);
$q->set( 'meta_query', $meta_query );
}
This is form:
echo '<form role="search" method="get" id="searchform" class="searchform" action="' . esc_url( home_url( '/' ) ) . '">
echo'<select name="size" class="dropdown">
<option value="all">All</option>';
global $wpdb;
$values2 = $wpdb->get_col("SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key ='wpcf-size'" );
foreach( $values2 as $valore2) {
$opzioni2[]=(unserialize($valore2));
}
array_walk_recursive($opzioni2, function ($value, $key) use (&$list2) {
$list2[] = $value;
});
foreach( array_unique ($list2) as $valore2) {
echo '<option value="'.$valore2.'">'.$valore2.'</option><br>';
}
echo'</select></form>';
Related
I am trying to filter my posts from a custom post type called 'courses'. I've created a custom taxonomy called 'course_types' which has 2 terms; 'Bundled Courses' and 'Single Courses'. I have a form with checkboxes, with which I would like to filter the custom posts, and have used a variety of combinations of tax_query operators ("AND, OR, NOT IN, etc"), but I am unabke to acheieve the expected results. Any help on this would be greatly appreciated. Thanks guys.
The Query
<?php
$args =
array(
'post_type' => 'courses',
'tax_query' => array(
array(
'taxonomy' => 'course_types',
'field' => 'term_id',
'terms' => $_GET['course_types'],
),
'relation' => 'AND',
),
)
?>
Form with checkboxes
<form method="GET">
<?php $terms = get_terms( array(
'taxonomy' => 'course_types',
'hide_empty' => false,
)
);
foreach($terms as $term) {
echo '<label><input type="checkbox" name="course_types[]" value="' . $term->name
.'">' . $term->name . '</label>';
} ?>
<input type="submit" value="Filter">
</form>
<?php
The Results
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
get_template_part( 'template-parts/content', 'courses' );
}
} else {
// no posts found
}
/* Restore original Post Data */
wp_reset_postdata();
?>
Turns out that the issue was that form was returning a name ('Single Courses' and 'Bundled Courses'), bu the query was expecting a term_id.
Corrected code
<form method="GET">
<?php $terms = get_terms( array(
'taxonomy' => 'course_types',
'hide_empty' => false,
) );
foreach($terms as $term) {
echo '<label><input type="checkbox" name="course_types[]" value="'
. $term->term_id .'">' . $term->name . '</label>';
} ?>
<input type="submit" value="Filter">
</form>
The query must contain a conditional if not filtered. I used a ternary.
<?php
$terms = get_terms( 'course_types' );
$term_ids = wp_list_pluck( $terms, 'term_id' );
$args =
array(
'post_type' => 'courses',
'tax_query' => array(
array(
'taxonomy' => 'course_types',
'field' => 'term_id',
'terms' => $_GET ? $_GET['course_types'] : $term_ids,
),
'relation' => 'AND',
),
);
?>
I have such code with attribute extraction to use it in shortcode.
<?php
function wpusers_shortcode( $atts ) {
extract(shortcode_atts( array(
'Department' => '',
), $atts
)
);
$args = array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'Department',
'value' => $Department,
),
)
);
// The Query
$user_query = new WP_user_Query( $args );
// User Loop
if ( ! empty( $user_query->get_results() ) ) {
foreach ( $user_query->get_results() as $user ) {
echo '<p>' . $user->display_name . '</p>';
}
} else {
echo 'No users found.';
}
}
add_shortcode( 'wpusers', 'wpusers_shortcode' );
?>
The shortcode is [wpusers Department="IEDK"].
Users are assigned to custom field Department
enter image description here
But at front end I have a message - No Users Found.
When I add attr (IEDK) in the code I can see them
extract(shortcode_atts( array(
'Department' => 'IEDK',
or
'key' => 'Department',
'value' => 'IEDK',
Whhere can be a problem?
Thanks in advance.
Remove extract and then try to debug with uncomment lines
function wpusers_shortcode( $atts ) {
$ar = shortcode_atts(
array('Department' => ''),
$atts
);
// print_r($ar); die;
$args = array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'Department',
'value' => $ar['Department'],
),
)
);
// print_r($args); die;
$user_query = new WP_user_Query( $args );
if ( ! empty( $user_query->get_results() ) ) {
foreach ( $user_query->get_results() as $user ) {
echo '<p>' . $user->display_name . '</p>';
}
} else {
echo 'No users found.';
}
}
add_shortcode( 'wpusers', 'wpusers_shortcode' );
Solved.
The problem was in Uppercase of key [wpusers Department="IEDK"].
I changed to small "d" everywhere and now it works..........
How to display total number of product in category with subcategory in WooCommerce?
I'm try using this code, but it work perfectly only in categories without subcategory.
add_action( 'woocommerce_before_shop_loop', 'add_product_count_view', 10);
function add_product_count_view() {
global $wp_query;
$category_id = $wp_query->get_queried_object()->term_id;
$term = get_term( $category_id, 'product_cat' );
echo $term->name . '(' . $term->count . ')';
}
Paste this code in function.php:
add_action( 'count_product_title', 'add_product_count_view', 10);
function add_product_count_view() {
global $wp_query;
$category_id = $wp_query->get_queried_object()->term_id;
//echo sprintf( _n( '%d товар', '%d товаров', $term->count ), $term->count );
$query = new WP_Query( array(
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $category_id,
'include_children' => true,
),
),
'nopaging' => true,
'fields' => 'ids',
) );
if( function_exists("is_shop") && $category_id != 0) {
echo '(' .esc_html( $query->post_count ) . ')';
}
}
Paste in your template
<?php do_action('count_product_title');?>
Could anyone assist in helping me get the below code to function correctly. I have taken bits of code from various other posts to create it.
I need to create a custom field (Datasheet) and be able to post a link to a PDF file. It should then appear just before the meta data on each product page.
Current code is as follows:
add_action( 'woocommerce_product_options_general_product_data',
'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
global $woocommerce, $post;
echo '<div class="options_group">';
woocommerce_wp_text_input( array( // Text Field type
'id' => '_datasheet_url',
'label' => __( 'Datasheet', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Datasheet URL here.', 'woocommerce' )
) );
echo '</div>';
}
add_action( 'woocommerce_process_product_meta',
'woo_save_custom_general_fields' );
function woo_save_custom_general_fields( $post_id ){
$datasheet_field= $_POST['_datasheet_url'];
if( !empty( $datasheet_field ) )
update_post_meta( $post_id, '_datasheet_url', esc_attr( $datasheet_field
) );
}
add_action('woocommerce_product_meta_start',
'woo_display_custom_general_fields_values', 5);
function woo_display_custom_general_fields_values() {
global $product;
$url = get_post_meta( $post->ID, 'Datasheet', true );
echo '<img src="http://www.freemansolutions.co.uk/wp-content/uploads/pdf-
icon.png"> Datasheet';
}
The main error is $url = get_post_meta( $post->ID, 'Datasheet', true ); as $post is not defined, then $post->ID throw an error and you can get the URL custom field value.
Try the following instead:
add_action( 'woocommerce_product_options_general_product_data', 'add_datasheet_url_custom_field' );
function add_datasheet_url_custom_field() {
echo '<div class="options_group">';
woocommerce_wp_text_input( array(
'id' => '_datasheet_url',
'label' => __('Datasheet URL', 'woocommerce'),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __('Set the "Datasheet" URL here.', 'woocommerce'),
) );
echo '</div>';
}
add_action( 'woocommerce_process_product_meta', 'save_datasheet_url_custom_field', 12, 1 );
function save_datasheet_url_custom_field( $post_id ){
if( isset( $_POST['_datasheet_url'] ) )
update_post_meta( $post_id, '_datasheet_url', sanitize_text_field( $_POST['_datasheet_url'] ) );
}
add_action('woocommerce_product_meta_start', 'use_datasheet_url_custom_field', 5 );
function use_datasheet_url_custom_field() {
$pdf_url = get_post_meta( get_the_id(), '_datasheet_url', true );
if( ! empty( $pdf_url ) ){
$icon_pdf = home_url( '/wp-content/uploads/pdf-icon.png' );
echo '<img src="'.$icon_pdf.'" /> ' . __('Datasheet', 'woocommerce') . '';
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
In our shop, we have a number of standard WP pages. On these pages we show ~40 products using the standard Woocommerce shortcodes.
For example:
[product_category category="boots" per_page="20" columns="4" orderby="price" order="desc"]
The products appears, but there are two things missing:
No sorting dropdown appears above the product lists, so the products cannot be sorted by our visitors.
We don't see any pagination buttons, so it's impossible to see more than the first 20 products on each page.
Any ideas how we can fix those two things?
Regarding your first issue, I have not found any good solutions beside hacking the shortcode within WC. Not entirely advisable as it will be overwritten each upgrade/patch of WC. If it's absolutely necessary, you could maintain the code by rewriting the hack each time you upgrade.
Alright, first download a copy of includes\class-wc-shortcodes.php in your woocommerce folder. Make a backup of the original before editing it, I usually rename the file with a -o or change the file type to .bak.
Assuming you'd want the original sort by dropdown that comes with WC on the Shop Page.
Step 1
Remove orderby and order arguments on the shortcode:
[product_category category="boots" per_page="20" columns="4"]
Step 2
Edit the Product Category shortcode on class-wc-shortcodes.php as such:
/**
* List products in a category shortcode
*
* #access public
* #param array $atts
* #return string
*/
public static function product_category( $atts ) {
global $woocommerce_loop, $wpdb;
if ( empty( $atts ) ) return '';
extract( shortcode_atts( array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'title',
'order' => 'asc',
'category' => '',
'operator' => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
), $atts ) );
if ( ! $category ) return '';
// Default ordering args
// $ordering_args = WC()->query->get_catalog_ordering_args( $orderby, $order ); // COMMENT THIS OUT
$orderby = 'title';
$order = 'asc';
if ( isset( $_GET['orderby'] ) ) {
$getorderby = $_GET['orderby'];
}
if ($getorderby == 'popularity') {
$orderby = 'meta_value_num';
$order = 'desc';
$meta_key = 'total_sales';
} elseif ($getorderby == 'rating') {
$fields .= ", AVG( $wpdb->commentmeta.meta_value ) as average_rating ";
$where .= " AND ( $wpdb->commentmeta.meta_key = 'rating' OR $wpdb->commentmeta.meta_key IS null ) ";
$join .= "
LEFT OUTER JOIN $wpdb->comments ON($wpdb->posts.ID = $wpdb->comments.comment_post_ID)
LEFT JOIN $wpdb->commentmeta ON($wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id)
";
$orderby = "average_rating DESC, $wpdb->posts.post_date DESC";
$groupby = "$wpdb->posts.ID";
} elseif ($getorderby == 'date') {
$orderby = 'date';
$order = 'desc';
} elseif ($getorderby == 'price') {
$orderby = 'meta_value_num';
$order = 'asc';
$meta_key = '_price';
} elseif ($getorderby == 'price-desc') {
$orderby = 'meta_value_num';
$order = 'desc';
$meta_key = '_price';
}
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'orderby' => $orderby, // $ordering_args['orderby'],
'order' => $order, // $ordering_args['order'],
'meta_key' => $meta_key,
'fields' => $fields,
'where' => $where,
'join' => $join,
'groupby' => $groupby,
'posts_per_page' => $per_page,
'meta_query' => array(
array(
'key' => '_visibility',
'value' => array('catalog', 'visible'),
'compare' => 'IN'
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'terms' => array( esc_attr( $category ) ),
'field' => 'slug',
'operator' => $operator
)
)
);
if ( isset( $ordering_args['meta_key'] ) ) {
$args['meta_key'] = $ordering_args['meta_key'];
}
ob_start();
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
$woocommerce_loop['columns'] = $columns;
if ( $products->have_posts() ) : ?>
<div style="width:100%;">
<div style="float:right">
<form class="woocommerce-ordering" method="get">
<select name="orderby" class="orderby">
<?php
$catalog_orderby = apply_filters( 'woocommerce_catalog_orderby', array(
'menu_order' => __( 'Default sorting', 'woocommerce' ),
'popularity' => __( 'Sort by popularity', 'woocommerce' ),
'rating' => __( 'Sort by average rating', 'woocommerce' ),
'date' => __( 'Sort by newness', 'woocommerce' ),
'price' => __( 'Sort by price: low to high', 'woocommerce' ),
'price-desc' => __( 'Sort by price: high to low', 'woocommerce' )
) );
if ( get_option( 'woocommerce_enable_review_rating' ) === 'no' )
unset( $catalog_orderby['rating'] );
foreach ( $catalog_orderby as $id => $name )
echo '<option value="' . esc_attr( $id ) . '" ' . selected( $getorderby, $id, false ) . '>' . esc_attr( $name ) . '</option>';
?>
</select>
<?php
// Keep query string vars intact
foreach ( $_GET as $key => $val ) {
if ( 'orderby' === $key || 'submit' === $key )
continue;
if ( is_array( $val ) ) {
foreach( $val as $innerVal ) {
echo '<input type="hidden" name="' . esc_attr( $key ) . '[]" value="' . esc_attr( $innerVal ) . '" />';
}
} else {
echo '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $val ) . '" />';
}
}
?>
</form>
</div>
</div>
<div style="clear:both;"></div>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
woocommerce_reset_loop();
wp_reset_postdata();
return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
}
Upload the file back into the includes folder and you're done! Your shortcode product pages will now have a working sort by dropdown same as the one that appears on the WC Shop Page.
Edit the sort options to your liking! Hope it helps!
Well for your second problem: Your shortcode is limiting to see only 20 products. Change the it to per_page="40" and you should see 40 products or simply remove the line and the number of products is not limited.
For your first problem I don't have an answer. I'm looking it for my self as well :).
If you add the paginate="true" attribute to your [products] shortcode, then the shortcode, then the Sort by dropdown menu will appear on the page.
Change this
[product_category category="boots" per_page="20" columns="4"]
to this
[product_category category="boots" paginate="true" limit="20" columns="4"]