Ранее были рассмотрены варианты добавления лэйбла New полуавтоматическим способом (последние созданные товары, либо по времени от текущего), либо назначением метки NEW.
Здесь разберем как сделать данный функционал полем и какие при этом есть нюансы.
Создаем поле NEW в карточке товара
// Создание чекбокса NEW
add_action( 'woocommerce_product_options_general_product_data', 'add_new_general_fields' );
function add_new_general_fields() {
global $woocommerce, $post;
echo '<div class="options_group">';
woocommerce_wp_checkbox(
array(
'id' => '_checkbox_new',
'wrapper_class' => 'show_if_simple',
'label' => __('Новинка', 'woocommerce' ),
'description' => __( 'Метка NEW для товаров', 'woocommerce' )
)
);
echo '</div>';
}
// Сохранение чекбокса NEW (удаление мета при отключении)
add_action( 'woocommerce_process_product_meta', 'add_general_fields_new_save' );
function add_general_fields_new_save( $post_id ){
if (!empty($_POST['_checkbox_new'])) { update_post_meta( $post_id, '_checkbox_new', 'yes' ); }
else { delete_post_meta( $post_id, '_checkbox_new' ); }
}
Дорабатываем систему вывода лэйблов. Это функция которая систематизирует вывод всех лэйблов WC: акция (если есть акционная цена), хит (если включен featured), метки (если назначены товару) и теперь NEW (если включен чекбокс _checkbox_new).
// Вывод лэйблов
function insert_labels_product() {
global $product;
$producttags = wp_get_object_terms($product->get_ID(), 'product_tag');
$label_new = get_post_meta($product->get_ID(), '_checkbox_new', true);
if (!empty($producttags) || $product->is_on_sale() == 1 || $product->is_featured() == 1 || $label_new == 'yes' ) {
echo '<div class="labels">';
if ( $product->is_on_sale() ) { echo '<div class="label-onsale">Акция!</div>'; }
if ( $product->is_featured() ) { echo '<div class="label-onhit">Хит</div>'; }
if ( $label_new == 'yes' ) { echo '<div class="label-onnew">NEW</div>'; }
foreach( $producttags as $tag ){
echo '<div class="label-'.$tag->slug.'">'.$tag->name.'</div>';
}
echo '</div>';
}
}
add_action( 'woocommerce_before_shop_loop_item_title', 'insert_labels_product', 10 );
add_action( 'woocommerce_before_single_product_summary', 'insert_labels_product', 10 );
remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_show_product_loop_sale_flash', 10 );
remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_sale_flash', 10 );
Добавление элементов управления полем в шаблоне Товары
Добавляем колонку NEW
add_filter('manage_product_posts_columns', function($columns) {
return array_merge($columns, ['novelty' => __('Новинка', 'textdomain')]);
});
add_action('manage_product_posts_custom_column', function($column_key, $post_id) {
if ($column_key == 'novelty') {
$novelty = get_post_meta($post_id, '_checkbox_new', true);
if ($novelty) {
echo '<div id="new-' . $post_id . '" class="novelty-btn novelty-yes">Yes</div>';
} else {
echo '<div id="new-' . $post_id . '" class="novelty-btn">No</div>';
}
}
}, 10, 2);
Создаем поле NEW внутри панели быстрого и массового редактирования
// создаем поле NEW внутри панели (в быстром и массовом редактировании)
add_action( 'woocommerce_product_quick_edit_start', 'show_checkbox_new_quick_edit' );
add_action( 'woocommerce_product_bulk_edit_end', 'show_checkbox_new_quick_edit', 99 );
function show_checkbox_new_quick_edit() {
?>
<label>
<span class="title">Новинка</span>
<span class="input-text-wrap">
<input type="checkbox" name="_checkbox_new">
</span>
</label>
<br class="clear" />
<?php
}
Сохраняем поле NEW
// сохраняем поле NEW
add_action( 'woocommerce_product_bulk_and_quick_edit', 'save_checkbox_new_bulk_edit', 99, 2 );
function save_checkbox_new_bulk_edit( $post_id, $post ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return $post_id; }
if ( 'product' !== $post->post_type ) return $post_id;
if ( isset( $_REQUEST['_checkbox_new'] ) ) {
update_post_meta( $post_id, '_checkbox_new', 'yes' );
} else {
delete_post_meta( $post_id, '_checkbox_new' );
}
}
Добавляем необходимые скрипты для подстановки поля в панель быстрого редактирования, а также изменения значения поля при нажатии на иконку.
add_action( 'admin_footer', 'show_checkbox_new_quick_edit_data' );
function show_checkbox_new_quick_edit_data(){
wc_enqueue_js( "
// передаем значение в панель БР если поле NEW включено
jQuery('#the-list').on('click', '.editinline', function() {
var post_id = jQuery(this).closest('tr').attr('id');
post_id = post_id.replace('post-', '');
var custom_field = jQuery('#new-' + post_id).text();
if ( custom_field === 'Yes' ) {
setTimeout(function () { jQuery('#edit-' + post_id + ' input[name=\'_checkbox_new\']').prop('checked', true); }, 200);
}
});
// изменяем состояние поля при нажатии на иконку
jQuery('#the-list').on('click', '.novelty-btn', function() {
var new_id = jQuery(this).attr('id');
new_id = new_id.replace('new-', '');
var new_val = jQuery(this).text();
jQuery.ajax({
url: '/wp-admin/admin-ajax.php',
method: 'post',
data: {
action: 'ajax_novelty',
new_id: new_id,
new_val: new_val,
},
success: function () {
jQuery('#new-' + new_id).text(new_val == 'Yes' ? 'No' : 'Yes');
jQuery('#new-' + new_id).toggleClass('novelty-yes');
}
});
});
" );
// стили оформления колонки
echo '<style type="text/css">
table.wp-list-table .column-novelty {width: 48px;}
thead .column-novelty {font-size: 0;}
.novelty-btn {cursor: pointer; font-size: 0; color: #ccc;}
.novelty-btn.novelty-yes {color: #2271b1;}
thead .column-novelty::before, table.wp-list-table .novelty-btn::before {
content: "\f339";
font-family: Dashicons;
line-height: 1.3;
font-size: initial;
cursor: pointer;
}
</style>';
}
И ещё одна функция ajax обновления поля (при нажатии иконки)
// Обновление поста ajax
function ajax_novelty_save(){
$new_id = $_REQUEST['new_id'];
$new_val = $_REQUEST['new_val'];
if ( $new_val == 'No' ) { update_post_meta( $new_id, '_checkbox_new', 'yes' ); }
else { delete_post_meta( $new_id, '_checkbox_new' ); }
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ){
wp_die();
}
}
add_action('wp_ajax_ajax_novelty', 'ajax_novelty_save' );
Создание шорткода вывода товаров по полю описан здесь.
[site-socialshare]
Спасибо за познавательную статейку, как раз то что искал.
Есть вопрос по коду. Для чего нужна строка:
foreach( $producttags as $tag ){
echo '<div class="label-'.$tag->slug.'">'.$tag->name.'</div>';
}
в блоке Вывод лейблов ?
Эта строка выводит метки товаров над изображением товара.
Да, именно для этого. На ряде проектов бывает такая необходимость, помечать товары какими либо метками.
Я правильно понимаю, чтобы изменить надпись при отсутствии товара «Нет в наличии» на свой ярлык, какой ни будь, в условие нужно добавить !$product->is_in_stock() == 1
Получится что то вроде этого
if (!empty($producttags) || $product->is_on_sale() == 1 || $product->is_featured() == 1 || !$product->is_in_stock() == 1|| $label_new == 'yes' ) {
echo '<div class="labels">';
if ( !$product->is_in_stock() ) { echo '<div class="label-instock">Продано!</div>'; }
}
Логика верная.
Поюзал Ваш код, еще раз спасибо, очень пригодился.
Хочу поделиться по этому поводу своими соображениями, может кому пригодится.
1. На функциях
'woocommerce_show_product_loop_sale_flash' и 'woocommerce_show_product_sale_flash'
также висит и вывод ярлыка при отсутствии товара на складе «Нет в наличии»Так что при удалении штатных экшенов для отображения ярлыков надо иметь это в виду.
remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_show_product_loop_sale_flash', 10 );
remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_sale_flash', 10 );
Становится актуальным мой предыдущий комментарий о добавлении своего ярлыка «Нет в наличии».
2. Если использовать весь код как плагин, а не в файле
functions.php,
просто так не удастся удалить экшины, нужно использовать событие'plugins_loaded'
либо'init'
add_action( 'plugins_loaded', 'my_remove_hoock_flash' );
function my_remove_hoock_flash() {
remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_show_product_loop_sale_flash', 10 );
remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_sale_flash', 10 );
}
3. У меня при использовании акционной цены скидка отображается в «% » , полностью заменять ярлык «Акция» вроде как не актуально.
Решение — скрывать штатные ярлыки при помощи CSS.
Спасибо Вам за полезные дополнения!