Related
Based on Enhanced WooCommerce Custom Fields for Variations answer code for adding a custom field to a product variation which works.
I have added additional custom fields, 6 at all. When I update the product, the data does not save and does not display on the front end either.
What have I done incorrectly when adding the additional custom fields?
My code:
// Add a custom field to variation settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
function variation_settings_fields( $loop, $variation_data, $variation ) {
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_model[' . $variation->ID . ']',
'label' => __( 'model', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_model', true )
)
);
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_wattage[' . $variation->ID . ']',
'label' => __( 'wattage', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_wattage', true )
)
);
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_lumen[' . $variation->ID . ']',
'label' => __( 'lumen', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_lumen', true )
)
);
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_material[' . $variation->ID . ']',
'label' => __( 'material', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_material', true )
)
);
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_dimension[' . $variation->ID . ']',
'label' => __( 'dimension', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_dimension', true )
)
);
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_year[' . $variation->ID . ']',
'label' => __( 'year', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_year', true )
)
);
}
// Save custom field value from variation settings
add_action( 'woocommerce_admin_process_variation_object', 'save_variation_settings_fields', 10, 2 );
function save_variation_settings_fields( $variation, $loop ) {
if( isset($_POST['_model'][$loop]) ) {
$variation->update_meta_data( '_model', sanitize_text_field($_POST['_model'][$loop]) );
}
if( isset($_POST['_wattage'][$loop]) ) {
$variation->update_meta_data( '_wattage', sanitize_text_field($_POST['_wattage'][$loop]) );
}
if( isset($_POST['_lumen'][$loop]) ) {
$variation->update_meta_data( '_lumen', sanitize_text_field($_POST['_lumen'][$loop]) );
}
if( isset($_POST['_material'][$loop]) ) {
$variation->update_meta_data( '_material', sanitize_text_field($_POST['_material'][$loop]) );
}
if( isset($_POST['_dimension'][$loop]) ) {
$variation->update_meta_data( '_dimension', sanitize_text_field($_POST['_dimension'][$loop]) );
}
if( isset($_POST['_year'][$loop]) ) {
$variation->update_meta_data( '_year', sanitize_text_field($_POST['_year'][$loop]) );
}
}
// Add variation custom field to single variable product form
add_filter( 'woocommerce_available_variation', 'add_variation_custom_field_to_variable_form', 10, 3 );
function add_variation_custom_field_to_variable_form( $variation_data, $product, $variation ) {
$variation_data['model'] = $variation->get_meta('_model');
$variation_data['wattage'] = $variation->get_meta('_wattage');
$variation_data['lumen'] = $variation->get_meta('_lumen');
$variation_data['material'] = $variation->get_meta('_material');
$variation_data['dimension'] = $variation->get_meta('_dimension');
$variation_data['year'] = $variation->get_meta('_year');
return $variation_data;
}
add_action( 'woocommerce_product_additional_information', 'add_html_container_to_display_selected_variation_custom_field' );
function add_html_container_to_display_selected_variation_custom_field( $product ){
echo '<div class="custom_variation-text-field"></div>';
}
// Display selected variation custom field value to product the tab
add_action( 'woocommerce_after_variations_form', 'display_selected_variation_custom_field_js' );
function display_selected_variation_custom_field_js(){
?>
<script type="text/javascript">
(function($){
$('form.cart').on('show_variation', function(event, data) {
$('.custom_variation-text-field').text(data.text_field);
}).on('hide_variation', function(event) {
$('.custom_variation-text-field').text('');
});
})(jQuery);
</script>
<?php
}
To make it save the data, I have made some changes in the 1st function (2nd one stay unchanged):
// Add a custom field to variation settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
function variation_settings_fields( $loop, $variation_data, $variation ) {
woocommerce_wp_text_input( array(
'id' => '_model[' . $loop . ']',
'label' => __( 'model', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'This is the description text...', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_model', true )
) );
woocommerce_wp_text_input(
array(
'id' => '_wattage[' . $loop . ']',
'label' => __( 'wattage', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'This is the description text...', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_wattage', true )
) );
woocommerce_wp_text_input( array(
'id' => '_lumen[' . $loop . ']',
'label' => __( 'lumen', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'This is the description text...', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_lumen', true )
) );
woocommerce_wp_text_input( array(
'id' => '_material[' . $loop . ']',
'label' => __( 'material', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'This is the description text...', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_material', true )
) );
woocommerce_wp_text_input( array(
'id' => '_dimension[' . $loop . ']',
'label' => __( 'dimension', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'This is the description text...', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_dimension', true )
) );
woocommerce_wp_text_input( array(
'id' => '_year[' . $loop . ']',
'label' => __( 'year', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_year', true )
) );
}
// Save custom field value from variation settings
add_action( 'woocommerce_admin_process_variation_object', 'save_variation_settings_fields', 10, 2 );
function save_variation_settings_fields( $variation, $loop ) {
if( isset($_POST['_model'][$loop]) ) {
$variation->update_meta_data( '_model', sanitize_text_field($_POST['_model'][$loop]) );
}
if( isset($_POST['_wattage'][$loop]) ) {
$variation->update_meta_data( '_wattage', sanitize_text_field($_POST['_wattage'][$loop]) );
}
if( isset($_POST['_lumen'][$loop]) ) {
$variation->update_meta_data( '_lumen', sanitize_text_field($_POST['_lumen'][$loop]) );
}
if( isset($_POST['_material'][$loop]) ) {
$variation->update_meta_data( '_material', sanitize_text_field($_POST['_material'][$loop]) );
}
if( isset($_POST['_dimension'][$loop]) ) {
$variation->update_meta_data( '_dimension', sanitize_text_field($_POST['_dimension'][$loop]) );
}
if( isset($_POST['_year'][$loop]) ) {
$variation->update_meta_data( '_year', sanitize_text_field($_POST['_year'][$loop]) );
}
}
It should better work to custom fields data to database and display the saved values in admin.
Now the frontend display part is wrong (your last 2 functions).
You need first to think about how you want to display that multiple custom fields, how should be the html structure and the labels related to each custom field. So edit your question as I can't guess that for you.
Here is a working example with all your custom fields, to display the data in frontend single product pages, for the selected variation:
// Add variation custom field to single variable product form
add_filter( 'woocommerce_available_variation', 'add_variation_custom_field_to_variable_form', 10, 3 );
function add_variation_custom_field_to_variable_form( $variation_data, $product, $variation ) {
$variation_data['model'] = $variation->get_meta('_model');
$variation_data['wattage'] = $variation->get_meta('_wattage');
$variation_data['lumen'] = $variation->get_meta('_lumen');
$variation_data['material'] = $variation->get_meta('_material');
$variation_data['dimension'] = $variation->get_meta('_dimension');
$variation_data['year'] = $variation->get_meta('_year');
return $variation_data;
}
add_action( 'woocommerce_product_additional_information', 'add_html_container_to_display_selected_variation_custom_field' );
function add_html_container_to_display_selected_variation_custom_field( $product ){
echo '<div class="custom_variation-text-field">aaa</div>';
}
// Display selected variation custom field value to product the tab
add_action( 'woocommerce_after_variations_form', 'display_selected_variation_custom_field_js' );
function display_selected_variation_custom_field_js(){
?>
<script type="text/javascript">
(function($){
var a = '.custom_variation-text-field', b = $(a).html();
$('form.cart').on('show_variation', function(event, data) {
outputHtml = '';
if( data.model ) {
outputHtml += '<span><strong><?php _e("Model"); ?><strong>: '+data.model+'<span><br>';
}
if( data.wattage ) {
outputHtml += '<span><strong><?php _e("Wattage"); ?><strong>: '+data.wattage+'<span><br>';
}
if( data.lumen ) {
outputHtml += '<span><strong><?php _e("Lumen"); ?><strong>: '+data.lumen+'<span><br>';
}
if( data.material ) {
outputHtml += '<span><strong><?php _e("Material"); ?><strong>: '+data.material+'<span><br>';
}
if( data.dimension ) {
outputHtml += '<span><strong><?php _e("Dimension"); ?><strong>: '+data.dimension+'<span><br>';
}
if( data.year ) {
outputHtml += '<span><strong><?php _e("Year"); ?><strong>: '+data.year+'<span>';
}
if( outputHtml ) {
$(a).html(outputHtml);
}
}).on('hide_variation', function(event) {
$(a).html(b);
});
})(jQuery);
</script>
<?php
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
I face a problem regarding woocommerce_wp_select . I am adding new fields to the single product page. First, I add the options by the following codes:
$title_110 = array(
'id' => 'custom_text_field_title_110',
'label' => __( 'Awards', 'rasa_store' ),
'desc_tip' => true,
'description' => __( 'Select an option.', 'ctwc' ),
'options' => array(
'' => __( 'Select Option', 'woocommerce' ),
'0' => __('This product does not win any awards', 'woocommerce' ),
'1' => __('This product win on award.', 'woocommerce' ),
'2' => __('This product win 2 award.', 'woocommerce' ),
'3' => __('This product win 3 award.', 'woocommerce' ),
'4' => __('This product very famous.', 'woocommerce' )
),
);
woocommerce_wp_select( $title_110 );
Than I save it.
$attribute_110 = wc_get_product( $post_id );
$title_top_110 = isset( $_POST['custom_text_field_title_110'] ) ? $_POST['custom_text_field_title_110'] : '';
$attribute_110->update_meta_data( 'custom_text_field_title_110', sanitize_text_field( $title_top_110 ) );
$attribute_110->save();
But in front page of single product page, while I use :
$attribute_11 = wc_get_product ( $post->ID );
$title_top_110 = $attribute_11->get_meta( 'custom_text_field_title_110' );
if( $title_top_110 ) {
printf(
'<div class="row">
<div class="col-md-4">
<img class="img-fluid box-10-2" src="%s/img/award-icon.png">
</div>
<div class="col-md-8 box-10">
<p class="card-text box-10-1">%s</p>
</div>
</div>
',
esc_html( get_bloginfo('template_directory') ),
esc_html( $title_top_110 )
);
}
Instead of printing This product does not win any awards I see 0.
I am looking for finding a way to fix it. I test the following methods, and they do not work:
1. Replaced update_post_meta() by get_post_meta()
2. Replaced esc_html to esc_sql
There are some different ways:
You need an additional custom function for your dropdown options this way:
function custom_field_options_title_110() {
return array(
'' => __( 'Select Option', 'woocommerce' ),
'0' => __('This product does not win any awards', 'woocommerce' ),
'1' => __('This product win on award.', 'woocommerce' ),
'2' => __('This product win 2 award.', 'woocommerce' ),
'3' => __('This product win 3 award.', 'woocommerce' ),
'4' => __('This product very famous.', 'woocommerce' )
);
}
Then you will call that function everywhere is needed:
In backend on your woocommerce_wp_select() code:
woocommerce_wp_select( array(
'id' => 'custom_text_field_title_110',
'label' => __( 'Awards', 'rasa_store' ),
'desc_tip' => true,
'description' => __( 'Select an option.', 'ctwc' ),
'options' => custom_field_options_title_110(), // <== Here we call our options function
) );
And now on frontend for single product page:
$attribute_11 = wc_get_product ( $post->ID );
$title_top_110 = $attribute_11->get_meta( 'custom_text_field_title_110' );
if( ! empty($title_top_110) ) {
printf( '<div class="row"><div class="col-md-4"><img class="img-fluid box-10-2" src="%s"></div>
<div class="col-md-8 box-10"><p class="card-text box-10-1">%s</p></div></div>',
esc_html( get_bloginfo('template_directory') . '/img/award-icon.png' ),
esc_html( custom_field_options_title_110()[$title_top_110] ) // <== HERE we use it
);
}
It should work…
Another alternative is to have the same keys and values in your 'options' array like:
$options_title_110 = array( '' => __( 'Select Option', 'woocommerce' ) );
foreach ( array(
__('This product does not win any awards', 'woocommerce' ),
__('This product win on award.', 'woocommerce' ),
__('This product win 2 award.', 'woocommerce' ),
__('This product win 3 award.', 'woocommerce' ),
__('This product very famous.', 'woocommerce' )
) as $label ) {
$options_title_110[$label] = $label;
}
woocommerce_wp_select( array(
'id' => 'custom_text_field_title_110',
'label' => __( 'Awards', 'rasa_store' ),
'desc_tip' => true,
'description' => __( 'Select an option.', 'ctwc' ),
'options' => $options_title_110,
) );
Then the custom field selected value will be saved on backend and displayed on front end.
You can set the options as you where doing, so this part should work as intended
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_text_field_title_110' );
function woo_add_custom_text_field_title_110(){
$title_110 = array(
'id' => 'custom_text_field_title_110',
'label' => __( 'Awards', 'rasa_store' ),
'desc_tip' => true,
'description' => __( 'Select an option.', 'ctwc' ),
'options' => array(
'' => __( 'Select Option', 'woocommerce' ),
'0' => __('This product does not win any awards', 'woocommerce' ),
'1' => __('This product win on award.', 'woocommerce' ),
'2' => __('This product win 2 award.', 'woocommerce' ),
'3' => __('This product win 3 award.', 'woocommerce' ),
'4' => __('This product very famous.', 'woocommerce' )
),
);
woocommerce_wp_select( $title_110 );
}
To save the fields
// Save Fields
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_text_field_title_110_save' );
function woo_add_custom_text_field_title_110_save( $post_id ){
// Select
$title_top_110 = $_POST['custom_text_field_title_110'];
if( !empty( $title_top_110 ) )
update_post_meta( $post_id, 'custom_text_field_title_110', esc_attr( $title_top_110 ) );
else {
update_post_meta( $post_id, 'custom_text_field_title_110', '' );
}
}
And to output the data on single product page (this code needs to be modified to output it inside the loop)
$title_top_110 = get_post_meta( 'custom_text_field_title_110', $post->ID, true );
if( $title_top_110 ) {
printf(
'<div class="row">
<div class="col-md-4">
<img class="img-fluid box-10-2" src="%1$s/img/award-icon.png">
</div>
<div class="col-md-8 box-10">
<p class="card-text box-10-1">%2$s</p>
</div>
</div>
',
esc_html( get_bloginfo('template_directory') ),
esc_html( $title_top_110 )
);
}
I'm trying to filter the products in the shop page by stock. Below is the code I added in my child theme's functions.php to add 2 new stock statuses. Which is working fine as expected.
function add_custom_stock_type() {
?>
<script type="text/javascript">
jQuery(function(){
jQuery('._stock_status_field').not('.custom-stock-status').remove();
});
</script>
<?php
woocommerce_wp_select( array( 'id' => '_stock_status', 'wrapper_class' => 'custom-stock-status', 'label' => __( 'Stock status', 'woocommerce' ), 'options' => array(
'readytoship' => __( 'Ready to ship', 'woocommerce' ),
'outofstock' => __( 'Out of stock', 'woocommerce' ),
'onbackorder' => __( 'Backorder', 'woocommerce' ),
'customized' => __( 'Customized', 'woocommerce' ),
), 'desc_tip' => true, 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ) ) );
}
add_action('woocommerce_product_options_stock_status', 'add_custom_stock_type');
function save_custom_stock_status( $product_id ) {
update_post_meta( $product_id, '_stock_status', wc_clean( $_POST['_stock_status'] ) );
}
add_action('woocommerce_process_product_meta', 'save_custom_stock_status',99,1);
function woo_add_custom_general_fields_save_two( $post_id ){
// Select
$woocommerce_select = $_POST['_stock_status'];
if( !empty( $woocommerce_select ) )
update_post_meta( $post_id, '_stock_status', esc_attr( $woocommerce_select ) );
else
update_post_meta( $post_id, '_stock_status', '' );
}
function woocommerce_get_custom_availability( $data, $product ) {
switch( $product->stock_status ) {
case 'readytoship':
$data = array( 'availability' => __( 'Ready to ship', 'woocommerce' ), 'class' => 'ready-to-ship' );
break;
case 'outofstock':
$data = array( 'availability' => __( 'Out of stock', 'woocommerce' ), 'class' => 'out-of-stock' );
break;
case 'onbackorder':
$data = array( 'availability' => __( 'Backorder', 'woocommerce' ), 'class' => 'onbackorder' );
break;
case 'customized':
$data = array( 'availability' => __( 'Customized', 'woocommerce' ), 'class' => 'customized' ); //added new one
break;
}
return $data;
}
add_action('woocommerce_get_availability', 'woocommerce_get_custom_availability', 10, 2);
So this is the code I'm using and I'm getting the stock status dropdown perfectly: https://prnt.sc/vrm5a9
I'm trying to "Filter Products Based on Stock Type" which I'm quite unsure how. I planned to place it in the woocommerce sidebar along with other filters like categories, price slider and stuff.
Any help is appreciated.
I use woocommerce and the standard widgets are fine, but I want to add the option to show products only from a certain category. Here is the code for the standard widget:
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* List products. One widget to rule them all.
*
* #author WooThemes
* #category Widgets
* #package WooCommerce/Widgets
* #version 2.3.0
* #extends WC_Widget
*/
class WC_Widget_Products extends WC_Widget {
/**
* Constructor
*/
public function __construct() {
$this->widget_cssclass = 'woocommerce widget_products';
$this->widget_description = __( 'Display a list of your products on your site.', 'woocommerce' );
$this->widget_id = 'woocommerce_products';
$this->widget_name = __( 'WooCommerce Products', 'woocommerce' );
$this->settings = array(
'title' => array(
'type' => 'text',
'std' => __( 'Products', 'woocommerce' ),
'label' => __( 'Title', 'woocommerce' )
),
'number' => array(
'type' => 'number',
'step' => 1,
'min' => 1,
'max' => '',
'std' => 5,
'label' => __( 'Number of products to show', 'woocommerce' )
),
'show' => array(
'type' => 'select',
'std' => '',
'label' => __( 'Show', 'woocommerce' ),
'options' => array(
'' => __( 'All Products', 'woocommerce' ),
'featured' => __( 'Featured Products', 'woocommerce' ),
'onsale' => __( 'On-sale Products', 'woocommerce' ),
)
),
'orderby' => array(
'type' => 'select',
'std' => 'date',
'label' => __( 'Order by', 'woocommerce' ),
'options' => array(
'date' => __( 'Date', 'woocommerce' ),
'price' => __( 'Price', 'woocommerce' ),
'rand' => __( 'Random', 'woocommerce' ),
'sales' => __( 'Sales', 'woocommerce' ),
)
),
'order' => array(
'type' => 'select',
'std' => 'desc',
'label' => _x( 'Order', 'Sorting order', 'woocommerce' ),
'options' => array(
'asc' => __( 'ASC', 'woocommerce' ),
'desc' => __( 'DESC', 'woocommerce' ),
)
),
'in_cat' => array(
'type' => 'text',
'std' => __( 'Category Number', 'woocommerce' ),
'label' => __( 'In Category', 'woocommerce' )
),
'hide_free' => array(
'type' => 'checkbox',
'std' => 0,
'label' => __( 'Hide free products', 'woocommerce' )
),
'show_hidden' => array(
'type' => 'checkbox',
'std' => 0,
'label' => __( 'Show hidden products', 'woocommerce' )
)
);
parent::__construct();
}
/**
* Query the products and return them
* #param array $args
* #param array $instance
* #return WP_Query
*/
public function get_products( $args, $instance ) {
$number = ! empty( $instance['number'] ) ? absint( $instance['number'] ) : $this->settings['number']['std'];
$show = ! empty( $instance['show'] ) ? sanitize_title( $instance['show'] ) : $this->settings['show']['std'];
$orderby = ! empty( $instance['orderby'] ) ? sanitize_title( $instance['orderby'] ) : $this->settings['orderby']['std'];
$order = ! empty( $instance['order'] ) ? sanitize_title( $instance['order'] ) : $this->settings['order']['std'];
$cat = ! empty( $instance['in_cat'] ) ? sanitize_title( $instance['in_cat'] ) : $this->settings['in_cat']['std'];
$query_args = array(
'posts_per_page' => $number,
'post_status' => 'publish',
'post_type' => 'product',
'no_found_rows' => 1,
'order' => $order,
'meta_query' => array(),
'post_type=products&cat='.$cat
);
if ( empty( $instance['show_hidden'] ) ) {
$query_args['meta_query'][] = WC()->query->visibility_meta_query();
$query_args['post_parent'] = 0;
}
if ( ! empty( $instance['hide_free'] ) ) {
$query_args['meta_query'][] = array(
'key' => '_price',
'value' => 0,
'compare' => '>',
'type' => 'DECIMAL',
);
}
$query_args['meta_query'][] = WC()->query->stock_status_meta_query();
$query_args['meta_query'] = array_filter( $query_args['meta_query'] );
switch ( $show ) {
case 'featured' :
$query_args['meta_query'][] = array(
'key' => '_featured',
'value' => 'yes'
);
break;
case 'onsale' :
$product_ids_on_sale = wc_get_product_ids_on_sale();
$product_ids_on_sale[] = 0;
$query_args['post__in'] = $product_ids_on_sale;
break;
}
switch ( $orderby ) {
case 'price' :
$query_args['meta_key'] = '_price';
$query_args['orderby'] = 'meta_value_num';
break;
case 'rand' :
$query_args['orderby'] = 'rand';
break;
case 'sales' :
$query_args['meta_key'] = 'total_sales';
$query_args['orderby'] = 'meta_value_num';
break;
default :
$query_args['orderby'] = 'date';
}
return new WP_Query( apply_filters( 'woocommerce_products_widget_query_args', $query_args ) );
}
/**
* widget function.
*
* #see WP_Widget
*
* #param array $args
* #param array $instance
*/
public function widget( $args, $instance ) {
if ( $this->get_cached_widget( $args ) ) {
return;
}
ob_start();
if ( ( $products = $this->get_products( $args, $instance ) ) && $products->have_posts() ) {
$this->widget_start( $args, $instance );
echo apply_filters( 'woocommerce_before_widget_product_list', '<ul class="product_list_widget">' );
while ( $products->have_posts() ) {
$products->the_post();
wc_get_template( 'content-widget-product.php', array( 'show_rating' => false ) );
}
echo apply_filters( 'woocommerce_after_widget_product_list', '</ul>' );
$this->widget_end( $args );
}
wp_reset_postdata();
echo $this->cache_widget( $args, ob_get_clean() );
}
}
As you can see I've added line 70:
'in_cat' => array(
'type' => 'text',
'std' => __( 'Category Number', 'woocommerce' ),
'label' => __( 'In Category', 'woocommerce' )
and also at Line 101:
$cat = ! empty( $instance['in_cat'] ) ? sanitize_title( $instance['in_cat'] ) : $this->settings['in_cat']['std'];
The option is available in the widget to be able to entera category ID and it saves when I click the save button.
The bit I'm struggling with is actually applying the filter, you will see i've added to Line 110:
'post_type=products&cat='.$cat
and I've also tried:
'category_name' => $cat
But I can't get the filters to work. Could anyone point me in the right direction please?
Cheers
Chris
Product category is custom taxonomy, you need to use 'tax_query' to solve the purpose as follows,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $cat,
),
),
Here, $cat should be string/array of taxonomy terms.
Even you can use, woocommerce shortcode if it suites your requirement,
[product_category category="appliances"]
Here, 'appliances' is slug of product category.
I'm working on a Wordpress site which has a drop-down/select list for ordering products.
I'd really like to style this nicely and have found a pretty good set of styles courtesy of codrops I'd like to use.
However the HTML for this uses UL LI list rather than the standard select.
I need to try and convert the following code:
<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( $orderby, $id, false ) . '>' . esc_attr( $name ) . '</option>';
?>
into something resembling this:
<div class="wrapper-dropdown">
<span>I'm kinda the label!</span>
<ul class="dropdown">
<li>I'm hidden!</li>
<li>Me too!</li>
<li>So do I.</li>
</ul>
</div>
<div class="wrapper-dropdown">
<span>I'm kinda the label!</span>
<ul class="dropdown">
<?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 '<li>' . esc_attr( $name ) . '</li>';
?>
</ul>
</div>
Just switch out the echo <option> code with echo <li> code