- Add mobile hamburger toggle button and full-screen nav drawer (≤1024px) - Fix product tab styles: complete tab CSS without relying on WC parent selectors; explicit wc-single-product enqueue on product pages - Fix STOCK field: conditionally hide when get_stock_quantity() returns null instead of showing '— units' - Add page-designs.php template + template_include filter so /designs/ uses themed layout instead of raw WooCommerce output - Align nav/footer terminology: 'Canvas' → 'Wall Decor' in nav fallback; correct broken category URL slugs (mugs→drinkware, canvas→wall-decor, planners→stationery, blog→the-memo); add 'Bulk / HR' to mobile drawer Co-Authored-By: Paperclip <noreply@paperclip.ing>
212 lines
10 KiB
PHP
212 lines
10 KiB
PHP
<?php
|
|
/**
|
|
* WooCommerce Single Product — gallery + variants + add-to-cart + reviews
|
|
*/
|
|
defined('ABSPATH') || exit;
|
|
|
|
get_header('shop');
|
|
the_post();
|
|
global $product;
|
|
if (!$product) $product = wc_get_product(get_the_ID());
|
|
|
|
$sku = $product->get_sku() ?: 'SKU-' . $product->get_id();
|
|
$cats = get_the_terms(get_the_ID(), 'product_cat');
|
|
$catname = $cats ? $cats[0]->name : 'Product';
|
|
$cat_url = $cats ? get_term_link($cats[0]) : get_permalink(wc_get_page_id('shop'));
|
|
$gallery_ids = $product->get_gallery_image_ids();
|
|
$main_img_id = $product->get_image_id();
|
|
$all_imgs = $main_img_id ? array_merge([$main_img_id], $gallery_ids) : $gallery_ids;
|
|
$price = $product->get_price_html();
|
|
$stock = $product->get_stock_status();
|
|
$stock_label = $stock === 'instock' ? '● IN STOCK' : ($stock === 'onbackorder' ? '◐ BACKORDER' : '○ OUT OF STOCK');
|
|
$stock_color = $stock === 'instock' ? 'var(--olive-dark)' : ($stock === 'onbackorder' ? 'var(--stamp)' : 'var(--ink-faint)');
|
|
?>
|
|
|
|
<!-- Breadcrumb -->
|
|
<div class="rar-breadcrumb">
|
|
<a href="<?php echo esc_url(home_url('/')); ?>">Shop</a> /
|
|
<a href="<?php echo esc_url($cat_url); ?>"><?php echo esc_html($catname); ?></a> /
|
|
<span><?php the_title(); ?></span>
|
|
</div>
|
|
|
|
<!-- Product layout -->
|
|
<div class="rar-product-detail">
|
|
|
|
<!-- Gallery -->
|
|
<div class="rar-gallery" id="rar-gallery">
|
|
<div class="rar-gallery__thumbs">
|
|
<?php foreach ($all_imgs as $i => $img_id) :
|
|
$thumb_url = wp_get_attachment_image_url($img_id, 'thumbnail');
|
|
$full_url = wp_get_attachment_image_url($img_id, 'rar-product-card');
|
|
?>
|
|
<button class="rar-gallery__thumb <?php echo $i === 0 ? 'active' : ''; ?>"
|
|
onclick="rarSwitchGallery(<?php echo esc_attr($i); ?>, '<?php echo esc_url($full_url); ?>')"
|
|
aria-label="View image <?php echo esc_attr($i + 1); ?>">
|
|
<?php if ($thumb_url) : ?>
|
|
<img src="<?php echo esc_url($thumb_url); ?>" alt="Image <?php echo esc_attr($i + 1); ?>" />
|
|
<?php endif; ?>
|
|
<span style="position:absolute;bottom:4px;left:4px;font-family:var(--mono);font-size:8px;color:var(--ink-soft);background:var(--paper);padding:1px 4px;border:1px solid var(--ink);">0<?php echo esc_html($i + 1); ?></span>
|
|
</button>
|
|
<?php endforeach; ?>
|
|
|
|
<?php if (empty($all_imgs)) : ?>
|
|
<button class="rar-gallery__thumb active" aria-label="Default image">
|
|
<span style="position:absolute;bottom:4px;left:4px;font-family:var(--mono);font-size:8px;color:var(--ink-soft);background:var(--paper);padding:1px 4px;border:1px solid var(--ink);">01</span>
|
|
</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="rar-gallery__main" id="rar-gallery-main">
|
|
<?php if (!empty($all_imgs)) :
|
|
$main_url = wp_get_attachment_image_url($all_imgs[0], 'rar-product-card');
|
|
?>
|
|
<img id="rar-gallery-img" src="<?php echo esc_url($main_url); ?>" alt="<?php the_title_attribute(); ?>" />
|
|
<?php else : ?>
|
|
<div class="rar-placeholder__label"><?php echo esc_html(strtoupper($catname)); ?></div>
|
|
<?php endif; ?>
|
|
<div class="rar-gallery__label" id="rar-gallery-label">FIG. 1 — FRONT</div>
|
|
<div style="position:absolute;bottom:18px;left:18px;">
|
|
<span class="rar-stamp">SKU <?php echo esc_html($sku); ?></span>
|
|
</div>
|
|
<div style="position:absolute;bottom:18px;right:18px;font-family:var(--mono);font-size:9px;letter-spacing:0.18em;text-transform:uppercase;color:var(--ink-muted);background:var(--paper);padding:4px 8px;border:1px solid var(--hairline-strong);">
|
|
<span id="rar-gallery-counter">1</span> / <?php echo esc_html(max(1, count($all_imgs))); ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Product Info -->
|
|
<div class="rar-product-info">
|
|
<div class="rar-form-tag" style="margin-bottom:14px;">
|
|
<?php echo esc_html(strtoupper($catname)); ?> · <?php echo esc_html(strtoupper($product->get_type())); ?> · <?php echo esc_html($sku); ?>
|
|
</div>
|
|
|
|
<h1><?php the_title(); ?></h1>
|
|
|
|
<?php if ($product->get_short_description()) : ?>
|
|
<p class="rar-product-subtitle"><?php echo wp_kses_post($product->get_short_description()); ?></p>
|
|
<?php endif; ?>
|
|
|
|
<!-- Rating -->
|
|
<div style="display:flex;align-items:center;gap:16px;margin-bottom:24px;">
|
|
<?php if ($product->get_rating_count() > 0) : ?>
|
|
<?php echo wc_get_rating_html($product->get_average_rating()); ?>
|
|
<span class="rar-mono" style="font-size:11px;letter-spacing:0.06em;">
|
|
<?php echo esc_html($product->get_average_rating()); ?> · <?php echo esc_html($product->get_rating_count()); ?> reviews
|
|
</span>
|
|
<span style="color:var(--hairline-strong);">·</span>
|
|
<?php endif; ?>
|
|
<span class="rar-mono" style="font-size:10px;letter-spacing:0.18em;text-transform:uppercase;color:<?php echo esc_attr($stock_color); ?>;">
|
|
<?php echo esc_html($stock_label); ?>
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Price -->
|
|
<div class="rar-product-price"><?php echo wp_kses_post($price); ?></div>
|
|
<div class="rar-product-price-sub">USD · ship $4.50 · free over $40</div>
|
|
|
|
<!-- Description -->
|
|
<?php if ($product->get_description()) : ?>
|
|
<div class="rar-product-desc"><?php echo wp_kses_post(wp_trim_words($product->get_description(), 40)); ?></div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Add to Cart Form -->
|
|
<?php woocommerce_template_single_add_to_cart(); ?>
|
|
|
|
<!-- Specs from short description / attributes -->
|
|
<?php $attrs = $product->get_attributes(); ?>
|
|
<?php if (!empty($attrs)) : ?>
|
|
<div class="rar-spec-list">
|
|
<div class="rar-spec-list__label">SECTION 4-A · SPECIFICATIONS</div>
|
|
<ul>
|
|
<?php $i = 1; foreach ($attrs as $attr) :
|
|
$attr_name = wc_attribute_label($attr->get_name());
|
|
$attr_vals = $attr->is_taxonomy()
|
|
? wc_get_product_terms($product->get_id(), $attr->get_name(), ['fields' => 'names'])
|
|
: $attr->get_options();
|
|
?>
|
|
<li>
|
|
<span class="rar-spec-num"><?php echo str_pad($i++, 2, '0', STR_PAD_LEFT); ?>.</span>
|
|
<span><strong><?php echo esc_html($attr_name); ?>:</strong> <?php echo esc_html(implode(', ', $attr_vals)); ?></span>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Shipping meta -->
|
|
<div class="rar-shipping-grid">
|
|
<div class="rar-shipping-item">
|
|
<div class="rar-shipping-item__key">Ships</div>
|
|
<div class="rar-shipping-item__val">In 3-5 biz days · USPS</div>
|
|
</div>
|
|
<div class="rar-shipping-item">
|
|
<div class="rar-shipping-item__key">Returns</div>
|
|
<div class="rar-shipping-item__val">30-day grievance window</div>
|
|
</div>
|
|
<div class="rar-shipping-item">
|
|
<div class="rar-shipping-item__key">Origin</div>
|
|
<div class="rar-shipping-item__val">Cleveland, OH</div>
|
|
</div>
|
|
<?php $stock_qty = $product->get_stock_quantity(); if ($stock_qty !== null): ?>
|
|
<div class="rar-shipping-item">
|
|
<div class="rar-shipping-item__key">Stock</div>
|
|
<div class="rar-shipping-item__val"><?php echo esc_html($stock_qty); ?> units</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Product tabs: description, reviews -->
|
|
<div style="padding:0 56px 64px;">
|
|
<?php woocommerce_output_product_data_tabs(); ?>
|
|
</div>
|
|
|
|
<!-- Reviews -->
|
|
<?php if ($product->get_rating_count() > 0) : ?>
|
|
<section class="rar-reviews">
|
|
<?php rar_section_head('FORM 12-C · TESTIMONIALS', 'What the chronically CC\'d are saying.', esc_html($product->get_rating_count()) . ' REVIEWS<br/>AVG. ' . esc_html($product->get_average_rating()) . ' ★'); ?>
|
|
<?php comments_template(); ?>
|
|
</section>
|
|
<?php endif; ?>
|
|
|
|
<!-- Related Products -->
|
|
<?php
|
|
$related_ids = wc_get_related_products($product->get_id(), 3);
|
|
if (!empty($related_ids)) :
|
|
$related_products = array_filter(array_map('wc_get_product', $related_ids));
|
|
?>
|
|
<section class="rar-products" style="background:var(--paper);border-top:1px solid var(--hairline-strong);">
|
|
<?php rar_section_head('FORM 13 · RELATED ITEMS', 'You might also regret buying...'); ?>
|
|
<div class="rar-products__grid">
|
|
<?php foreach ($related_products as $rp) :
|
|
$ri = $rp->get_image_id();
|
|
$ru = $ri ? wp_get_attachment_image_url($ri, 'rar-product-card') : '';
|
|
$rc = get_the_terms($rp->get_id(), 'product_cat');
|
|
$rcat = $rc ? $rc[0]->name : '';
|
|
?>
|
|
<a href="<?php echo esc_url(get_permalink($rp->get_id())); ?>" class="rar-card">
|
|
<div class="rar-card__media">
|
|
<div class="rar-card__sku">SKU <?php echo esc_html($rp->get_sku() ?: $rp->get_id()); ?></div>
|
|
<?php if ($ru) : ?>
|
|
<img src="<?php echo esc_url($ru); ?>" alt="<?php echo esc_attr($rp->get_name()); ?>" />
|
|
<?php else : ?>
|
|
<div class="rar-placeholder__label"><?php echo esc_html(strtoupper($rcat ?: $rp->get_name())); ?></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="rar-card__body">
|
|
<?php if ($rcat) : ?><div class="rar-card__cat"><?php echo esc_html($rcat); ?></div><?php endif; ?>
|
|
<div class="rar-card__title"><?php echo esc_html($rp->get_name()); ?></div>
|
|
<div class="rar-card__row">
|
|
<span class="rar-card__price"><?php echo wp_kses_post($rp->get_price_html()); ?></span>
|
|
<span style="color:var(--ink-muted);">→</span>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</section>
|
|
<?php endif; ?>
|
|
|
|
<?php get_footer('shop'); ?>
|