Тема магазина по макету Figma

Каталог, карточка товара, корзина, оформление заказа и блог на WooCommerce.

Стили разложены по слоям: токены из Figma, база, компоненты, страницы,
брейкпоинты. Цвета, типографика, радиусы и отступы взяты из Variables и
текстовых стилей макета, ниже по слоям хардкода нет.

Иконки — Phosphor, вставляются инлайном как SVG, символами ничего не рисуется.
Стили WooCommerce отключены, вёрстка своя, !important не используется.
This commit is contained in:
f1den committed 2026-07-30 22:38:49 +03:00
commit 29d10ce4cf
72 files changed
+7465

No files matched your search

+179
View File
@@ -0,0 +1,179 @@
<?php
/**
* Product archive and category page.
*
* @package VyatkaShop
*/
defined( 'ABSPATH' ) || exit;
get_header();
$title = woocommerce_page_title( false );
$categories = get_terms(
array(
'taxonomy' => 'product_cat',
'hide_empty' => true,
'parent' => 0,
)
);
$price_min = isset( $_GET['filter_min_price'] ) ? min( 37900, absint( wp_unslash( $_GET['filter_min_price'] ) ) ) : 0;
$price_max = isset( $_GET['filter_max_price'] ) ? max( $price_min + 100, min( 38000, absint( wp_unslash( $_GET['filter_max_price'] ) ) ) ) : 25600;
$feature_options = array(
'all' => 'Земляничный нектар',
'conifer' => 'Хвойный экстракт',
'maple' => 'Кленовый сироп',
'birch' => 'Берёзовый сок',
'sea-buckthorn' => 'Облепиховый морс',
'rowan' => 'Рябиновый настой',
'blueberry' => 'Черничный кисель',
'lingonberry' => 'Брусничный компот',
);
$collection_options = array(
'' => 'Вишнёвый нектар',
'pine' => 'Сосновый сироп',
'linden' => 'Липовый нектар',
'aspen' => 'Осиновый экстракт',
'juniper' => 'Можжевёловый морс',
'cranberry' => 'Клюквенный настой',
'blackberry' => 'Ежевичный кисель',
'raspberry' => 'Малиновый компот',
);
$selected_features = isset( $_GET['feature'] )
? array_map( 'sanitize_key', (array) wp_unslash( $_GET['feature'] ) )
: array( 'all' );
$selected_collection = isset( $_GET['collection'] ) ? sanitize_key( wp_unslash( $_GET['collection'] ) ) : '';
$selected_per_page = isset( $_GET['per_page'] ) ? absint( wp_unslash( $_GET['per_page'] ) ) : 25;
$filter_action = wc_get_page_permalink( 'shop' );
if ( is_product_category() ) {
$queried_category = get_queried_object();
if ( $queried_category instanceof WP_Term ) {
$category_link = get_term_link( $queried_category );
if ( ! is_wp_error( $category_link ) ) {
$filter_action = $category_link;
}
}
}
?>
<div class="container">
<?php vyatka_shop_breadcrumbs( $title ); ?>
<h1 class="page-heading"><?php echo esc_html( $title ); ?></h1>
<?php wc_print_notices(); ?>
<?php get_template_part( 'template-parts/subcategories' ); ?>
<div class="archive-shell">
<aside class="filters" id="product-filter-panel" aria-label="<?php esc_attr_e( 'Фильтры товаров', 'vyatka-shop' ); ?>">
<?php // Below the mobile breakpoint the panel becomes the sheet the design specifies. ?>
<div class="filters-sheet-head">
<h2 class="filters-sheet-title"><?php esc_html_e( 'Фильтры', 'vyatka-shop' ); ?></h2>
<button class="icon-button filters-close" type="button" data-filter-panel-close aria-label="<?php esc_attr_e( 'Закрыть фильтры', 'vyatka-shop' ); ?>">
<?php vyatka_shop_icon( 'x', array( 'class' => 'icon-20' ) ); ?>
</button>
</div>
<form id="product-filters" action="<?php echo esc_url( $filter_action ); ?>" method="get" data-product-filters>
<?php if ( isset( $_GET['orderby'] ) ) : ?>
<input type="hidden" name="orderby" value="<?php echo esc_attr( sanitize_key( wp_unslash( $_GET['orderby'] ) ) ); ?>">
<?php endif; ?>
<div class="filter-group" data-price-filter data-price-active="<?php echo isset( $_GET['filter_min_price'], $_GET['filter_max_price'] ) ? 'true' : 'false'; ?>">
<button class="filter-title" type="button" data-filter-toggle aria-expanded="true"><?php esc_html_e( 'Цена, ₽', 'vyatka-shop' ); ?><?php vyatka_shop_icon( 'caret-up', array( 'class' => 'filter-caret' ) ); ?></button>
<div class="filter-content">
<div class="price-fields">
<input class="filter-input" type="number" name="filter_min_price" min="0" max="38000" step="100" value="<?php echo esc_attr( (string) $price_min ); ?>" data-price-field="min">
<span class="price-fields-separator" aria-hidden="true"></span>
<input class="filter-input" type="number" name="filter_max_price" min="0" max="38000" step="100" value="<?php echo esc_attr( (string) $price_max ); ?>" data-price-field="max">
</div>
<div class="price-range">
<input type="range" min="0" max="38000" step="100" value="<?php echo esc_attr( (string) $price_min ); ?>" data-price-range="min" aria-label="<?php esc_attr_e( 'Минимальная цена', 'vyatka-shop' ); ?>">
<input type="range" min="0" max="38000" step="100" value="<?php echo esc_attr( (string) $price_max ); ?>" data-price-range="max" aria-label="<?php esc_attr_e( 'Максимальная цена', 'vyatka-shop' ); ?>">
</div>
</div>
</div>
<div class="filter-group">
<button class="filter-title filter-title-open" type="button" data-filter-toggle aria-expanded="true"><?php esc_html_e( 'Фильтр', 'vyatka-shop' ); ?><?php vyatka_shop_icon( 'caret-up', array( 'class' => 'filter-caret' ) ); ?></button>
<div class="filter-content">
<?php foreach ( $feature_options as $feature_value => $feature_label ) : ?>
<label class="filter-option"<?php echo array_search( $feature_value, array_keys( $feature_options ), true ) >= 5 ? ' data-filter-extra hidden' : ''; ?>>
<input type="checkbox" name="feature[]" value="<?php echo esc_attr( $feature_value ); ?>" data-facet-filter <?php checked( in_array( $feature_value, $selected_features, true ) ); ?>>
<?php echo esc_html( $feature_label ); ?>
</label>
<?php endforeach; ?>
<button class="filter-more" type="button" data-filter-more aria-expanded="false"><?php esc_html_e( 'Показать все', 'vyatka-shop' ); ?></button>
</div>
</div>
<div class="filter-group">
<button class="filter-title filter-title-open" type="button" data-filter-toggle aria-expanded="true"><?php esc_html_e( 'Фильтр', 'vyatka-shop' ); ?><?php vyatka_shop_icon( 'caret-up', array( 'class' => 'filter-caret' ) ); ?></button>
<div class="filter-content">
<?php foreach ( $collection_options as $collection_value => $collection_label ) : ?>
<label class="filter-option"<?php echo array_search( $collection_value, array_keys( $collection_options ), true ) >= 5 ? ' data-filter-extra hidden' : ''; ?>>
<input type="radio" name="collection" value="<?php echo esc_attr( $collection_value ); ?>" data-facet-filter <?php checked( $selected_collection, $collection_value ); ?>>
<?php echo esc_html( $collection_label ); ?>
</label>
<?php endforeach; ?>
<button class="filter-more" type="button" data-filter-more aria-expanded="false"><?php esc_html_e( 'Показать все', 'vyatka-shop' ); ?></button>
</div>
</div>
<?php for ( $filter_index = 0; $filter_index < 3; $filter_index++ ) : ?>
<div class="filter-group filter-collapsed">
<span class="filter-title"><?php esc_html_e( 'Фильтр', 'vyatka-shop' ); ?><?php vyatka_shop_icon( 'caret-up', array( 'class' => 'filter-caret' ) ); ?></span>
</div>
<?php endfor; ?>
</form>
<div class="filters-sheet-foot">
<button class="button button-l filters-apply" type="button" data-filter-panel-close><?php esc_html_e( 'Показать товары', 'vyatka-shop' ); ?></button>
</div>
</aside>
<section class="archive-results">
<?php
/*
* Quick filters. They mirror the collection facet from the sidebar —
* picking a chip selects the matching radio and submits the same
* form, so both controls always agree.
*/
?>
<div class="quick-filters" role="group" aria-label="<?php esc_attr_e( 'Быстрые фильтры', 'vyatka-shop' ); ?>">
<?php foreach ( $collection_options as $collection_value => $collection_label ) : ?>
<button
class="quick-filter<?php echo $selected_collection === $collection_value ? ' is-active' : ''; ?>"
type="button"
data-quick-filter="<?php echo esc_attr( $collection_value ); ?>"
aria-pressed="<?php echo $selected_collection === $collection_value ? 'true' : 'false'; ?>"
><?php echo esc_html( $collection_label ); ?></button>
<?php endforeach; ?>
</div>
<div class="archive-toolbar">
<button class="filters-open" type="button" data-filter-panel-open aria-expanded="false" aria-controls="product-filter-panel">
<?php vyatka_shop_icon( 'funnel', array( 'class' => 'icon-20' ) ); ?><?php esc_html_e( 'Фильтр', 'vyatka-shop' ); ?>
</button>
<div class="sort-control"><span><?php esc_html_e( 'Сортировка', 'vyatka-shop' ); ?></span><?php woocommerce_catalog_ordering(); ?></div>
<label class="per-page-control"><span><?php esc_html_e( 'Выводить товаров', 'vyatka-shop' ); ?></span>
<select class="archive-select" name="per_page" form="product-filters" data-auto-submit data-custom-select aria-label="<?php esc_attr_e( 'Количество товаров', 'vyatka-shop' ); ?>">
<?php foreach ( array( 12, 25, 50 ) as $per_page_option ) : ?>
<option value="<?php echo esc_attr( (string) $per_page_option ); ?>" <?php selected( $selected_per_page, $per_page_option ); ?>><?php echo esc_html( (string) $per_page_option ); ?></option>
<?php endforeach; ?>
</select>
</label>
</div>
<?php if ( woocommerce_product_loop() ) : ?>
<div class="product-grid" data-filter-results>
<?php while ( have_posts() ) : ?>
<?php
the_post();
$GLOBALS['product'] = wc_get_product( get_the_ID() );
get_template_part( 'template-parts/product-card' );
?>
<?php endwhile; ?>
</div>
<p class="filter-empty" data-filter-empty hidden><?php esc_html_e( 'По выбранным параметрам товаров нет.', 'vyatka-shop' ); ?></p>
<?php vyatka_shop_pagination( (int) $GLOBALS['wp_query']->max_num_pages ); ?>
<?php else : ?>
<?php do_action( 'woocommerce_no_products_found' ); ?>
<?php endif; ?>
</section>
</div>
</div>
<?php
get_footer();
+13
View File
@@ -0,0 +1,13 @@
<?php
/**
* Empty cart state.
*
* @package VyatkaShop
*/
defined( 'ABSPATH' ) || exit;
?>
<div class="container cart-page cart-page-empty">
<h1 class="page-heading"><?php esc_html_e( 'Корзина', 'vyatka-shop' ); ?></h1>
<p class="cart-empty-message"><?php esc_html_e( 'Ваша корзина пока пуста.', 'vyatka-shop' ); ?></p>
</div>
+75
View File
@@ -0,0 +1,75 @@
<?php
/**
* Cart page.
*
* @package VyatkaShop
*/
defined( 'ABSPATH' ) || exit;
do_action( 'woocommerce_before_cart' );
?>
<div class="container cart-page">
<h1 class="page-heading"><?php esc_html_e( 'Корзина', 'vyatka-shop' ); ?></h1>
<form class="woocommerce-cart-form" action="<?php echo esc_url( wc_get_cart_url() ); ?>" method="post">
<div class="cart-layout">
<div class="cart-items">
<?php foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) : ?>
<?php
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if ( ! $_product || ! $_product->exists() || $cart_item['quantity'] <= 0 ) {
continue;
}
$max_purchase_quantity = $_product->get_max_purchase_quantity();
$regular_total = (float) $_product->get_regular_price() * (int) $cart_item['quantity'];
?>
<article class="cart-item woocommerce-cart-form__cart-item" data-cart-item-key="<?php echo esc_attr( $cart_item_key ); ?>">
<a class="cart-thumb" href="<?php echo esc_url( get_permalink( $product_id ) ); ?>">
<span class="product-badge"><?php esc_html_e( 'NEW', 'vyatka-shop' ); ?></span>
<?php echo wp_kses_post( $_product->get_image( 'thumbnail' ) ); ?>
</a>
<div class="cart-item-copy">
<a class="cart-item-title" href="<?php echo esc_url( get_permalink( $product_id ) ); ?>"><?php echo esc_html( $_product->get_name() ); ?></a>
<span class="cart-item-sku"><?php esc_html_e( 'Арт: 3948GP', 'vyatka-shop' ); ?></span>
</div>
<div class="cart-item-price">
<del><?php echo wp_kses_post( wc_price( $regular_total ) ); ?></del>
<ins><?php echo wp_kses_post( WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ) ); ?></ins>
</div>
<div class="quantity-control cart-item-quantity">
<button type="button" data-quantity-action="decrease" aria-label="<?php esc_attr_e( 'Уменьшить количество', 'vyatka-shop' ); ?>"<?php echo (int) $cart_item['quantity'] <= 1 ? ' disabled' : ''; ?>><?php vyatka_shop_icon( 'minus', array( 'class' => 'icon-20' ) ); ?></button>
<input
type="number"
name="cart[<?php echo esc_attr( $cart_item_key ); ?>][qty]"
value="<?php echo esc_attr( (string) $cart_item['quantity'] ); ?>"
min="1"
<?php if ( 0 < $max_purchase_quantity ) : ?>
max="<?php echo esc_attr( (string) $max_purchase_quantity ); ?>"
<?php endif; ?>
inputmode="numeric"
>
<button type="button" data-quantity-action="increase" aria-label="<?php esc_attr_e( 'Увеличить количество', 'vyatka-shop' ); ?>"<?php echo 0 < $max_purchase_quantity && (int) $cart_item['quantity'] >= $max_purchase_quantity ? ' disabled' : ''; ?>><?php vyatka_shop_icon( 'plus', array( 'class' => 'icon-20' ) ); ?></button>
</div>
<a class="cart-item-remove" href="<?php echo esc_url( wc_get_cart_remove_url( $cart_item_key ) ); ?>" aria-label="<?php esc_attr_e( 'Удалить товар', 'vyatka-shop' ); ?>"><?php vyatka_shop_icon( 'trash', array( 'class' => 'icon-20' ) ); ?></a>
</article>
<?php endforeach; ?>
<button class="screen-reader-text" type="submit" name="update_cart" value="<?php esc_attr_e( 'Обновить корзину', 'vyatka-shop' ); ?>"><?php esc_html_e( 'Обновить корзину', 'vyatka-shop' ); ?></button>
<?php wp_nonce_field( 'woocommerce-cart', 'woocommerce-cart-nonce' ); ?>
</div>
<?php $price_summary = vyatka_shop_cart_price_summary(); ?>
<aside class="order-card cart-order-card">
<div class="order-row"><span><?php esc_html_e( 'Товаров', 'vyatka-shop' ); ?></span><span><?php echo esc_html( (string) count( WC()->cart->get_cart() ) ); ?></span></div>
<div class="order-row"><span><?php esc_html_e( 'Сумма', 'vyatka-shop' ); ?></span><strong><?php echo wp_kses_post( wc_price( $price_summary['regular_total'] ) ); ?></strong></div>
<div class="order-row"><span><?php esc_html_e( 'Скидка', 'vyatka-shop' ); ?></span><span>− <?php echo wp_kses_post( wc_price( $price_summary['discount_total'] ) ); ?></span></div>
<div class="order-row total"><span><?php esc_html_e( 'Итого', 'vyatka-shop' ); ?></span><strong><?php wc_cart_totals_order_total_html(); ?></strong></div>
<a class="button" href="<?php echo esc_url( wc_get_checkout_url() ); ?>"><?php esc_html_e( 'Перейти к оформлению', 'vyatka-shop' ); ?></a>
</aside>
</div>
</form>
</div>
<?php
do_action( 'woocommerce_after_cart' );
+108
View File
@@ -0,0 +1,108 @@
<?php
/**
* Checkout form.
*
* @package VyatkaShop
*
* @var WC_Checkout $checkout Checkout object.
*/
defined( 'ABSPATH' ) || exit;
if ( ! $checkout->is_registration_enabled() && $checkout->is_registration_required() && ! is_user_logged_in() ) {
echo esc_html( apply_filters( 'woocommerce_checkout_must_be_logged_in_message', __( 'Для оформления заказа необходимо войти.', 'vyatka-shop' ) ) );
return;
}
$price_summary = vyatka_shop_cart_price_summary();
?>
<div class="container checkout-page">
<h1 class="page-heading"><?php esc_html_e( 'Оформление заказа', 'vyatka-shop' ); ?></h1>
<form name="checkout" method="post" class="checkout woocommerce-checkout" action="<?php echo esc_url( wc_get_checkout_url() ); ?>" enctype="multipart/form-data">
<div class="checkout-layout">
<div class="checkout-fields">
<label class="checkout-input">
<input type="text" name="billing_first_name" autocomplete="given-name" placeholder=" " required>
<span class="field-label"><?php esc_html_e( 'Имя', 'vyatka-shop' ); ?></span>
<span class="field-error" data-field-error aria-live="polite"></span>
</label>
<label class="checkout-input">
<input type="tel" name="billing_phone" autocomplete="tel" placeholder=" " required>
<span class="field-label"><?php esc_html_e( 'Телефон', 'vyatka-shop' ); ?></span>
<span class="field-error" data-field-error aria-live="polite"></span>
</label>
<label class="checkout-input">
<input type="email" name="billing_email" autocomplete="email" placeholder=" " required>
<span class="field-label"><?php esc_html_e( 'Email', 'vyatka-shop' ); ?></span>
<span class="field-error" data-field-error aria-live="polite"></span>
</label>
<input type="hidden" name="billing_country" value="RU">
<fieldset class="checkout-delivery">
<legend><?php esc_html_e( 'Получение заказа', 'vyatka-shop' ); ?></legend>
<div class="delivery-switch" role="group" aria-label="<?php esc_attr_e( 'Способ получения', 'vyatka-shop' ); ?>">
<label><input type="radio" name="delivery_type" value="pickup" checked><span><?php esc_html_e( 'Самовывоз', 'vyatka-shop' ); ?></span></label>
<label><input type="radio" name="delivery_type" value="delivery"><span><?php esc_html_e( 'Доставка', 'vyatka-shop' ); ?></span></label>
</div>
<div data-delivery-panel="pickup">
<label class="checkout-radio"><input type="radio" name="pickup_address" value="1" checked> <span><?php esc_html_e( 'Москва, ул.Тверская, 168', 'vyatka-shop' ); ?></span></label>
<label class="checkout-radio"><input type="radio" name="pickup_address" value="2"> <span><?php esc_html_e( 'Москва, Садовое кольцо, 152к4', 'vyatka-shop' ); ?></span></label>
<label class="checkout-radio"><input type="radio" name="pickup_address" value="3"> <span><?php esc_html_e( 'Киров, Октябрьский проспект, 290к3', 'vyatka-shop' ); ?></span></label>
<img class="checkout-map" src="<?php echo esc_url( get_template_directory_uri() . '/assets/images/checkout-map.jpg' ); ?>" alt="<?php esc_attr_e( 'Пункты получения на карте', 'vyatka-shop' ); ?>">
</div>
<div class="delivery-address-fields" data-delivery-panel="delivery" hidden>
<label class="checkout-input">
<input type="text" name="delivery_address" placeholder=" " autocomplete="street-address" data-delivery-required disabled>
<span class="field-label"><?php esc_html_e( 'Адрес доставки', 'vyatka-shop' ); ?></span>
<span class="field-error" data-field-error aria-live="polite"></span>
</label>
<label class="checkout-input">
<input type="text" name="delivery_unit" placeholder=" " disabled>
<span class="field-label"><?php esc_html_e( 'Квартира или офис', 'vyatka-shop' ); ?></span>
<span class="field-error" data-field-error aria-live="polite"></span>
</label>
</div>
</fieldset>
<fieldset class="checkout-payment-options">
<legend><?php esc_html_e( 'Способ оплаты', 'vyatka-shop' ); ?></legend>
<label class="checkout-radio"><input type="radio" name="payment_method" value="cod" checked> <span><?php esc_html_e( 'Онлайн оплата', 'vyatka-shop' ); ?></span></label>
<label class="checkout-radio"><input type="radio" name="payment_method" value="bacs"> <span><?php esc_html_e( 'Оплата при получении', 'vyatka-shop' ); ?></span></label>
</fieldset>
</div>
<aside class="order-card checkout-order-card" id="order_review">
<div class="checkout-order-products">
<?php foreach ( WC()->cart->get_cart() as $cart_item ) : ?>
<?php
$_product = $cart_item['data'];
if ( ! $_product || ! $_product->exists() ) {
continue;
}
?>
<div class="checkout-order-product">
<div class="checkout-order-thumb"><?php echo wp_kses_post( $_product->get_image( 'thumbnail' ) ); ?></div>
<div>
<strong><?php echo esc_html( $_product->get_name() ); ?></strong>
<span><?php echo wp_kses_post( WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ) ); ?> <span class="multiply" aria-hidden="true"></span><?php echo esc_html( (string) $cart_item['quantity'] ); ?></span>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="checkout-order-totals">
<div class="order-row"><span><?php esc_html_e( 'Товаров в корзине', 'vyatka-shop' ); ?></span><span><?php echo esc_html( (string) count( WC()->cart->get_cart() ) ); ?></span></div>
<div class="order-row"><span><?php esc_html_e( 'Сумма заказа', 'vyatka-shop' ); ?></span><strong><?php echo wp_kses_post( wc_price( $price_summary['regular_total'] ) ); ?></strong></div>
<div class="order-row"><span><?php esc_html_e( 'Скидка', 'vyatka-shop' ); ?></span><span>− <?php echo wp_kses_post( wc_price( $price_summary['discount_total'] ) ); ?></span></div>
<div class="order-row total"><span><?php esc_html_e( 'Итого', 'vyatka-shop' ); ?></span><strong><?php wc_cart_totals_order_total_html(); ?></strong></div>
</div>
<label class="checkout-consent">
<input type="checkbox" name="terms" value="1" required checked data-consent>
<span><?php esc_html_e( 'Даю согласие на обработку персональных данных', 'vyatka-shop' ); ?></span>
</label>
<?php wp_nonce_field( 'woocommerce-process_checkout', 'woocommerce-process-checkout-nonce' ); ?>
<button type="submit" class="button" name="woocommerce_checkout_place_order" id="place_order" data-consent-gated value="<?php esc_attr_e( 'Оформить заказ', 'vyatka-shop' ); ?>"><?php esc_html_e( 'Оформить заказ', 'vyatka-shop' ); ?></button>
</aside>
</div>
</form>
</div>
+9
View File
@@ -0,0 +1,9 @@
<?php
/**
* WooCommerce product card adapter.
*
* @package VyatkaShop
*/
defined( 'ABSPATH' ) || exit;
get_template_part( 'template-parts/product-card' );
+177
View File
@@ -0,0 +1,177 @@
<?php
/**
* Single product page.
*
* @package VyatkaShop
*/
defined( 'ABSPATH' ) || exit;
get_header();
while ( have_posts() ) :
the_post();
global $product;
if ( post_password_required() ) {
echo get_the_password_form(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
continue;
}
$attributes = $product->get_attributes();
$max_purchase_quantity = $product->get_max_purchase_quantity();
$related = wc_get_products(
array(
'include' => wc_get_related_products( $product->get_id(), 8 ),
'limit' => 8,
)
);
$gallery_image_ids = array_values(
array_unique(
array_filter(
array_merge(
array( $product->get_image_id() ),
$product->get_gallery_image_ids()
)
)
)
);
?>
<div class="container">
<?php vyatka_shop_breadcrumbs( $product->get_name() ); ?>
<?php wc_print_notices(); ?>
<article id="product-<?php the_ID(); ?>" <?php wc_product_class( '', $product ); ?>>
<div class="product-layout">
<div class="product-gallery">
<div class="gallery-badges">
<span class="product-badge"><?php esc_html_e( 'NEW', 'vyatka-shop' ); ?></span>
<span class="product-badge"><?php esc_html_e( 'NEW', 'vyatka-shop' ); ?></span>
<span class="product-badge"><?php esc_html_e( 'NEW', 'vyatka-shop' ); ?></span>
</div>
<button class="gallery-favorite" type="button" aria-label="<?php esc_attr_e( 'Добавить в избранное', 'vyatka-shop' ); ?>" aria-pressed="false"><?php vyatka_shop_icon( 'heart' ); ?></button>
<button class="gallery-arrow gallery-arrow-prev" type="button" aria-label="<?php esc_attr_e( 'Предыдущее изображение', 'vyatka-shop' ); ?>"><?php vyatka_shop_icon( 'arrow-right-fill', array( 'class' => 'icon-flip' ) ); ?></button>
<button class="gallery-arrow gallery-arrow-next" type="button" aria-label="<?php esc_attr_e( 'Следующее изображение', 'vyatka-shop' ); ?>"><?php vyatka_shop_icon( 'arrow-right-fill' ); ?></button>
<div class="gallery-images" data-product-gallery>
<?php for ( $gallery_index = 0; $gallery_index < max( 5, count( $gallery_image_ids ) ); $gallery_index++ ) : ?>
<?php $gallery_image_id = $gallery_image_ids[ $gallery_index % max( 1, count( $gallery_image_ids ) ) ] ?? 0; ?>
<?php if ( $gallery_image_id ) : ?>
<?php
echo wp_kses_post(
wp_get_attachment_image(
$gallery_image_id,
'full',
false,
array(
'class' => 'gallery-image',
'data-gallery-slide' => '',
'hidden' => 0 === $gallery_index ? false : true,
)
)
);
?>
<?php else : ?>
<span class="gallery-image gallery-image-placeholder" data-gallery-slide <?php echo 0 === $gallery_index ? '' : 'hidden'; ?>></span>
<?php endif; ?>
<?php endfor; ?>
</div>
<div class="gallery-dots" aria-label="<?php esc_attr_e( 'Изображения товара', 'vyatka-shop' ); ?>">
<?php for ( $gallery_index = 0; $gallery_index < max( 5, count( $gallery_image_ids ) ); $gallery_index++ ) : ?>
<i data-gallery-dot<?php echo 0 === $gallery_index ? ' class="active"' : ''; ?>></i>
<?php endfor; ?>
</div>
</div>
<div class="product-summary">
<div class="product-meta-line">
<?php esc_html_e( 'Арт: 4654GR', 'vyatka-shop' ); ?>
<span class="meta-separator" aria-hidden="true"></span><span class="stock"><?php echo esc_html( $product->is_in_stock() ? __( 'В наличии', 'vyatka-shop' ) : __( 'Нет в наличии', 'vyatka-shop' ) ); ?></span>
</div>
<h1><?php the_title(); ?></h1>
<div class="woocommerce-product-details__short-description">
<?php echo wp_kses_post( $product->get_short_description() ?: vyatka_shop_placeholder_copy() ); ?>
</div>
<table class="attribute-table">
<?php for ( $row_index = 0; $row_index < 4; $row_index++ ) : ?>
<tr><td><?php esc_html_e( 'Характеристика', 'vyatka-shop' ); ?></td><td><?php esc_html_e( 'Значение', 'vyatka-shop' ); ?></td></tr>
<?php endfor; ?>
</table>
<label class="product-option">
<span><?php esc_html_e( 'Свойство', 'vyatka-shop' ); ?></span>
<select name="product_option" form="product-cart-form" data-custom-select>
<option value="dark-gray"><?php esc_html_e( 'Темно-серый', 'vyatka-shop' ); ?></option>
</select>
</label>
<div class="price"><?php echo wp_kses_post( $product->get_price_html() ); ?></div>
<?php if ( $product->is_purchasable() && $product->is_in_stock() ) : ?>
<form class="cart" id="product-cart-form" action="<?php echo esc_url( $product->get_permalink() ); ?>" method="post" enctype="multipart/form-data" data-ajax-add-to-cart>
<div class="quantity-control">
<button type="button" data-quantity-action="decrease" aria-label="<?php esc_attr_e( 'Уменьшить количество', 'vyatka-shop' ); ?>" disabled><?php vyatka_shop_icon( 'minus', array( 'class' => 'icon-20' ) ); ?></button>
<input
type="number"
name="quantity"
value="1"
min="1"
<?php if ( 0 < $max_purchase_quantity ) : ?>
max="<?php echo esc_attr( (string) $max_purchase_quantity ); ?>"
<?php endif; ?>
inputmode="numeric"
>
<button type="button" data-quantity-action="increase" aria-label="<?php esc_attr_e( 'Увеличить количество', 'vyatka-shop' ); ?>"<?php echo 1 === $max_purchase_quantity ? ' disabled' : ''; ?>><?php vyatka_shop_icon( 'plus', array( 'class' => 'icon-20' ) ); ?></button>
</div>
<button class="button single_add_to_cart_button" type="submit" name="add-to-cart" value="<?php echo esc_attr( (string) $product->get_id() ); ?>"><?php vyatka_shop_icon( 'cart', array( 'class' => 'icon-20' ) ); ?><?php esc_html_e( 'В корзину', 'vyatka-shop' ); ?></button>
</form>
<?php endif; ?>
<a class="button button-outline buy-one-click" href="<?php echo esc_url( add_query_arg( array( 'add-to-cart' => $product->get_id(), 'quantity' => 1 ), wc_get_checkout_url() ) ); ?>"><?php esc_html_e( 'Купить в 1 клик', 'vyatka-shop' ); ?></a>
</div>
</div>
<div class="product-tabs">
<ul class="tab-list" role="tablist">
<li class="active"><a href="#product-tab-description" role="tab" aria-selected="true" aria-controls="product-tab-description" data-tab="description"><?php esc_html_e( 'Описание', 'vyatka-shop' ); ?></a></li>
<li><a href="#product-tab-attributes" role="tab" aria-selected="false" aria-controls="product-tab-attributes" data-tab="attributes"><?php esc_html_e( 'Характеристики', 'vyatka-shop' ); ?></a></li>
<li><a href="#product-tab-documents" role="tab" aria-selected="false" aria-controls="product-tab-documents" data-tab="documents"><?php esc_html_e( 'Документы', 'vyatka-shop' ); ?></a></li>
<li><a href="#product-tab-shipping" role="tab" aria-selected="false" aria-controls="product-tab-shipping" data-tab="shipping"><?php esc_html_e( 'Оплата и доставка', 'vyatka-shop' ); ?></a></li>
</ul>
<div class="prose" id="product-tab-description" role="tabpanel" data-tab-panel="description">
<?php echo wp_kses_post( $product->get_description() ?: wpautop( vyatka_shop_placeholder_copy() . ' ' . vyatka_shop_placeholder_copy() ) ); ?>
</div>
<div class="prose" id="product-tab-attributes" role="tabpanel" data-tab-panel="attributes" hidden>
<?php wc_display_product_attributes( $product ); ?>
</div>
<div class="prose" id="product-tab-documents" role="tabpanel" data-tab-panel="documents" hidden>
<p><?php esc_html_e( 'Проектная документация и спецификация предоставляются после оформления заказа.', 'vyatka-shop' ); ?></p>
</div>
<div class="prose" id="product-tab-shipping" role="tabpanel" data-tab-panel="shipping" hidden>
<p><?php esc_html_e( 'Стоимость и сроки доставки рассчитываются менеджером после уточнения адреса и комплектации.', 'vyatka-shop' ); ?></p>
</div>
</div>
<?php if ( $related ) : ?>
<section class="section">
<div class="section-head">
<h2 class="section-title"><?php esc_html_e( 'Похожие товары', 'vyatka-shop' ); ?></h2>
<div class="slider-controls" data-carousel-controls="related-products">
<button type="button" data-carousel-prev aria-label="<?php esc_attr_e( 'Предыдущие похожие товары', 'vyatka-shop' ); ?>"><?php vyatka_shop_icon( 'arrow-right', array( 'class' => 'icon-flip icon-20' ) ); ?></button>
<button type="button" data-carousel-next aria-label="<?php esc_attr_e( 'Следующие похожие товары', 'vyatka-shop' ); ?>"><?php vyatka_shop_icon( 'arrow-right', array( 'class' => 'icon-20' ) ); ?></button>
</div>
</div>
<div class="product-grid" id="related-products" data-carousel>
<?php foreach ( $related as $related_product ) : ?>
<?php
$GLOBALS['product'] = $related_product;
get_template_part( 'template-parts/product-card' );
?>
<?php endforeach; ?>
</div>
</section>
<?php endif; ?>
</article>
</div>
<?php
endwhile;
get_footer();