Тема магазина по макету Figma
Каталог, карточка товара, корзина, оформление заказа и блог на WooCommerce. Стили разложены по слоям: токены из Figma, база, компоненты, страницы, брейкпоинты. Цвета, типографика, радиусы и отступы взяты из Variables и текстовых стилей макета, ниже по слоям хардкода нет. Иконки — Phosphor, вставляются инлайном как SVG, символами ничего не рисуется. Стили WooCommerce отключены, вёрстка своя, !important не используется.
This commit is contained in:
commit
29d10ce4cf
72 files changed
+7465
No files matched your search
@@ -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();
|
||||
@@ -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>
|
||||
@@ -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' );
|
||||
@@ -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>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce product card adapter.
|
||||
*
|
||||
* @package VyatkaShop
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
get_template_part( 'template-parts/product-card' );
|
||||
@@ -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();
|
||||
Reference in new issue
Block a user