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
Related
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've been struggling for a while to get this to work. I need to show this payment link in my woocommerce emails, but only on certain (custom) order statuses. How is it done? Thanks :)
printf(
wp_kses(
/* translators: %1s item is the name of the site, %2s is a html link */
__( '%2$s', 'woocommerce' ),
array(
'a' => array(
'href' => array(),
),
)
),
esc_html( get_bloginfo( 'name', 'display' ) ),
'' . esc_html__( 'Click here to pay for this order', 'woocommerce' ) . ''
);
You will use the WC_Order method get_status() in something like:
if( in_array( $order->get_status(), array( 'custom-one', 'custom-two') ) ) {
printf( wp_kses(
/* translators: %1s item is the name of the site, %2s is a html link */
__( '%2$s', 'woocommerce' ), array(
'a' => array(
'href' => array(),
),
) ),
esc_html( get_bloginfo( 'name', 'display' )
), '<a href="' . esc_url( $order->get_checkout_payment_url() ) . '">' .
esc_html__( 'Click here to pay for this order', 'woocommerce' ) . '</a>' );
}
It should works (where you will replace custom-one and custom-two by your custom statuses slugs)
I am trying to get the second value from the array and label it $icon however I am still learning PHP. No matter what I try nothing has helped. This is for a WooCommerce website running a custom theme. The below code has been placed in the functions.php file.
$catalog_orderby = apply_filters('woocommerce_catalog_orderby', array(
'menu_order' => __( 'Default', '', 'woocommerce' ),
'date' => __( 'Whats New', '', 'woocommerce' ),
'popularity' => __( 'Popularity', '', 'woocommerce' ),
'rating' => __( 'Average Rating', '', 'woocommerce' ),
'price' => __( 'Price: Low to High', '', 'woocommerce' ),
'price-desc' => __( 'Price: High to Low', '', 'woocommerce' )
));
foreach( $catalog_orderby as $id => $name ) {
echo '<li><i class="fa">' . $icon . '</i>' . esc_attr( $name ) . '</li>';
};
Any help with this would be greatly appreciated!
The __() function seems to be for fetching a string translation, so you'd need to pass the icon string as a separate variable. You can do that using a multidimensional array.
$catalog_orderby = apply_filters('woocommerce_catalog_orderby', array(
'menu_order' => array(__( 'Default', 'woocommerce' ), ''),
'date' => array(__( 'Whats New', 'woocommerce' ), ''),
'popularity' => array(__( 'Popularity', 'woocommerce' ), ''),
'rating' => array(__( 'Average Rating', 'woocommerce' ), ''),
'price' => array(__( 'Price: Low to High', 'woocommerce' ), ''),
'price-desc' => array(__( 'Price: High to Low', 'woocommerce' ), '')
));
foreach( $catalog_orderby as $id => $item ) {
echo '<li><i class="fa">' . $item[1] . '</i>' . esc_attr( $item[0] ) . '</li>';
};
Why are you using the _() function, it appears to be a translation function?
If you change the __('Default', '', 'woocommerce') to array('Default', '', 'woocommerce') you can access it in the loop by doing $name[1]
I am trying to come up with a solution to limit the stated that a product category can be shipped to. Here is what I have come up with so far.
function get_prod_cat () {
global $woocommerce;
$specialfeecat = 34; // category id for the special fee
$items = $woocommerce->cart->get_cart();
foreach ($items as $item ) {
$product = $item['data'];
$terms = get_the_terms( $product->id, 'product_cat' );
if ( $terms && ! is_wp_error( $terms ) ) :
foreach ( $terms as $term ) {
$catid = $term->term_id;
if($specialfeecat == $catid ) {
$GLOBALS['cat_id'] = $catid;
}
return $cat_id;
}
endif;
}
}
if ($cat_id == 34) {
add_filter( 'woocommerce_states', 'wc_sell_only_states' );
}
function wc_sell_only_states() {
$states['US'] = array(
'AK' => __( 'Arkansas', 'woocommerce' ),
'DC' => __( 'Washington DC', 'woocommerce' ),
'IL' => __( 'Illinois', 'woocommerce' ),
'KY' => __( 'Kentucky', 'woocommerce' ),
'MN' => __( 'Minnesota', 'woocommerce' ),
'NM' => __( 'New Mexico', 'woocommerce' ),
);
return $states;
}
I am trying to get the variable $cat_id from the first function out of it so that I can use it for the condition to limit states. Thanks in advance.
Call add_filter( 'woocommerce_states', 'wc_sell_only_states' ); as you have done. Inside function 'wc_sell_only_states($states)' apply your logic, which you were doing inside 'get_prod_cat'. If category matched then change states
$states['US'] = array(
'AK' => __( 'Arkansas', 'woocommerce' ),
'DC' => __( 'Washington DC', 'woocommerce' ),
'IL' => __( 'Illinois', 'woocommerce' ),
'KY' => __( 'Kentucky', 'woocommerce' ),
'MN' => __( 'Minnesota', 'woocommerce' ),
'NM' => __( 'New Mexico', 'woocommerce' ),
);
Else return states as it was.