/ Wordpress / Новинка (товар NEW полем)

Новинка (товар NEW полем)

HIT

27.02.2022

1134

6

Ранее были рассмотрены варианты добавления лэйбла 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' );
Если выбрать товары с включенным полем, в массовом редактировании, чекбокс все равно будет отключен. И если не включая чекбокс произвести обновление, то поля у этих товаров отключаться. А если включить его то товары все станут NEW. Необходимо доработать массовое редактирование.

Создание шорткода вывода товаров по полю описан здесь.

Поделиться в соц. сетях:

  • Похожие записи
  • Комментарии
  • Вложения
Разные шаблоны для разных категорий товаров

Разные шаблоны для разных категорий товаров

Учимся создавать разные шаблоны товаров для разных категорий. Данная технология пригодится в оформлении принципиально разных по подаче товаров. Также на основе этого можно создавать посадочные страницы категорий, создавая им любое Читать далее »

Фильтры Woocommerce

Фильтры Woocommerce

В базовую комплектацию Woocommerce входит набор виджетов для фильтрации товаров. Но данные виджеты необходимо несколько доработать. WooCommerce Навигация по слоям В этом виджете необходимо задать атрибут товара по которому будет Читать далее »

/ /
Интересные фишки для Woocommerce

Интересные фишки для Woocommerce

Продолжаем серию интересных доработок для Woocmmerce. Выведем дату последней покупки товара У товара такого мета поля нет, нужно сопоставлять наименования (перебирая заказы). Для этого создаем запрос на перебор БД: В Читать далее »

Добавить комментарий

6 комментариев

  1. Евгений

    Спасибо за познавательную статейку, как раз то что искал.
    Есть вопрос по коду. Для чего нужна строка:
    foreach( $producttags as $tag ){
    echo '<div class="label-'.$tag->slug.'">'.$tag->name.'</div>';

     
    в блоке  Вывод лейблов ?
    Эта строка выводит метки товаров над изображением товара.

    1. Alexandr

      Да, именно для этого. На ряде проектов бывает такая необходимость, помечать товары какими либо метками.

  2. Евгений

    Я правильно понимаю, чтобы изменить надпись при отсутствии товара «Нет в наличии» на свой ярлык, какой ни будь, в условие нужно добавить  !$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. Alexandr

      Логика верная.

  3. Евгений

    Поюзал Ваш код, еще раз спасибо, очень пригодился.
    Хочу поделиться по этому поводу своими соображениями, может кому пригодится.
    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.
     

    1. Alexandr

      Спасибо Вам за полезные дополнения!

Новинка (товар NEW полем) Новинка (товар NEW полем)
Удалить дубли товаров
Рекомендации для васУдалить дубли товаровOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.