Files
repa-woocommerce/theme/woocommerce/archive-product.php
FrontendDev de8d1b8bef Fix products, search, and newsletter form per REPA-17
- Search: replace static <a href="/?s="> with togglable search overlay
  form that submits post_type=product for proper WooCommerce results
- Newsletter: remove mc4wp shortcode (plugin not installed), replace
  with self-contained HTML form + JS confirmation handler
- Shop by Design: link each design card to real product_tag pages
  (passive-aggressive, email-signatures, meeting-recovery, etc.)
  and show live tag.count instead of hardcoded numbers
- Category slugs: update $cat_meta mapping to match actual WC slugs
  (drinkware, wall-decor, stationery, apparel, stickers, accessories)
  in both front-page.php and archive-product.php
- Footer dept links updated to real WC category slugs

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-02 21:25:45 -04:00

239 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* WooCommerce Archive/Category page — shop product listing with filter sidebar + sort
*/
defined('ABSPATH') || exit;
get_header('shop');
$term = get_queried_object();
$is_category = $term instanceof WP_Term;
$cat_name = $is_category ? $term->name : 'Shop';
$cat_desc = $is_category ? $term->description : '';
$cat_count = $is_category ? $term->count : wp_count_posts('product')->publish;
$cat_slug = $is_category ? $term->slug : 'shop';
// Category descriptions
$cat_desc_map = [
'drinkware' => 'Dishwasher safe. Microwave safe. HR safe (mostly). Mugs, tumblers, and vessels for the passively aggressive.',
'wall-decor' => 'Print-on-demand wall art for the soul-tired and decoratively passive-aggressive.',
'stationery' => 'For the person who plans a lot and does a little. Or the other way around.',
'apparel' => 'Wear your grievances. Business casual with a quiet fury.',
'stickers' => 'Stick your opinions where they'll be seen. Water-resistant, like your resolve.',
'accessories' => 'The extras that speak for you when you've run out of words.',
];
if (empty($cat_desc)) {
$cat_desc = $cat_desc_map[$cat_slug] ?? 'The complete collection. Curated for the chronically employed.';
}
// Sort order
$orderby = isset($_GET['orderby']) ? sanitize_text_field($_GET['orderby']) : 'menu_order';
?>
<!-- Breadcrumb -->
<div class="rar-breadcrumb">
<a href="<?php echo esc_url(home_url('/')); ?>">Shop</a> /
<?php if ($is_category) : ?>
<a href="<?php echo esc_url(home_url('/shop/')); ?>">Departments</a> /
<span><?php echo esc_html($cat_name); ?></span>
<?php else : ?>
<span>All Products</span>
<?php endif; ?>
</div>
<!-- Category Hero -->
<div class="rar-cat-hero">
<?php if ($is_category) : ?>
<div class="rar-folder-tab">DEPT. <?php echo strtoupper($cat_slug); ?> · <?php echo esc_html(strtoupper($cat_name)); ?></div>
<?php endif; ?>
<div class="rar-cat-hero__inner">
<div>
<h1>
<?php echo esc_html($cat_name); ?>.<br>
<em style="color:var(--stamp);font-style:italic;"><?php echo esc_html(wp_trim_words($cat_desc, 6)); ?></em>
</h1>
</div>
<div>
<p style="font-size:14px;line-height:1.6;color:var(--ink-muted);margin:0 0 18px;max-width:380px;"><?php echo esc_html($cat_desc); ?></p>
<div class="rar-cat-hero__stats">
<span><?php echo esc_html($cat_count); ?> ITEMS</span>
<span>·</span>
<span>FREE SHIP OVER $40</span>
</div>
</div>
</div>
</div>
<!-- Toolbar -->
<div class="rar-toolbar">
<div class="rar-toolbar__left">
Showing
<?php woocommerce_result_count(); ?>
</div>
<div class="rar-toolbar__right">
<!-- Grid/List toggle -->
<div class="rar-view-toggle">
<button class="rar-view-toggle__btn active" id="rar-grid-btn" onclick="rarSetView('grid')">Grid</button>
<button class="rar-view-toggle__btn" id="rar-list-btn" onclick="rarSetView('list')">List</button>
</div>
<!-- Sort -->
<div class="rar-sort-wrap">
<button class="rar-sort-btn" onclick="document.getElementById('rar-sort-menu').classList.toggle('open')">
Sort: <span id="rar-sort-label"><?php echo esc_html(wc_get_loop_prop('orderby', 'Featured')); ?></span>
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"></path></svg>
</button>
<div class="rar-sort-menu" id="rar-sort-menu">
<?php
$sort_options = WC()->query->get_catalog_ordering_args();
foreach (wc_get_catalog_ordering_args() as $val => $opt) {
$current = (isset($_GET['orderby']) ? $_GET['orderby'] : get_option('woocommerce_default_catalog_orderby')) === $val;
$url = add_query_arg('orderby', $val);
echo '<a href="' . esc_url($url) . '" class="' . ($current ? 'active' : '') . '" onclick="document.getElementById(\'rar-sort-label\').textContent=this.textContent;document.getElementById(\'rar-sort-menu\').classList.remove(\'open\');">' . esc_html($opt) . '</a>';
}
?>
</div>
</div>
</div>
</div>
<!-- Category layout: filter sidebar + product grid -->
<div class="rar-cat-layout">
<!-- Filter Sidebar -->
<aside class="rar-filter-sidebar">
<div class="rar-form-tag" style="margin-bottom:14px;">FORM 06-B · FILTERS</div>
<!-- Subcategories -->
<?php if ($is_category) {
$subcats = get_terms(['taxonomy' => 'product_cat', 'parent' => $term->term_id, 'hide_empty' => true]);
if (!empty($subcats)) {
echo '<div class="rar-filter-group">';
echo '<div class="rar-filter-group__label">Subcategories <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14"></path></svg></div>';
foreach ($subcats as $sc) {
$active = (isset($_GET['product_cat']) && $_GET['product_cat'] === $sc->slug) ? ' checked' : '';
echo '<label class="rar-filter-item"><input type="checkbox" name="product_cat" value="' . esc_attr($sc->slug) . '"' . $active . ' onchange="rarApplyFilter(this)"> ' . esc_html($sc->name) . ' <span style="font-family:var(--mono);font-size:10px;color:var(--ink-faint);margin-left:auto;">' . esc_html($sc->count) . '</span></label>';
}
echo '</div>';
}
} ?>
<!-- Price filter -->
<div class="rar-filter-group">
<div class="rar-filter-group__label">
Price
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14"></path></svg>
</div>
<?php
$price_ranges = [
['under-25', 'Under $25', '0', '25'],
['25-40', '$25 $40', '25', '40'],
['over-40', 'Over $40', '40', '999'],
];
foreach ($price_ranges as [$id, $label, $min, $max]) {
$active = (isset($_GET['min_price']) && $_GET['min_price'] === $min) ? ' checked' : '';
echo '<label class="rar-filter-item"><input type="checkbox" id="price-' . esc_attr($id) . '" data-min="' . esc_attr($min) . '" data-max="' . esc_attr($max) . '"' . $active . ' onchange="rarPriceFilter(this)"> ' . esc_html($label) . '</label>';
}
?>
</div>
<!-- In-stock filter -->
<div class="rar-filter-group">
<div class="rar-filter-group__label">
Availability
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14"></path></svg>
</div>
<label class="rar-filter-item">
<input type="checkbox" id="rar-in-stock" <?php echo (isset($_GET['availability']) && $_GET['availability'] === 'instock') ? 'checked' : ''; ?> onchange="rarStockFilter(this)">
In Stock Only
</label>
</div>
<?php if (is_active_sidebar('shop-filter')) : ?>
<?php dynamic_sidebar('shop-filter'); ?>
<?php endif; ?>
<div class="rar-filter-apply">
<button class="rar-btn" style="width:100%;" onclick="rarApplyAllFilters()">Apply filters</button>
</div>
</aside>
<!-- Product Grid -->
<div>
<div class="rar-product-grid" id="rar-product-grid">
<?php
if (have_posts()) :
while (have_posts()) :
the_post();
global $product;
if (!$product) $product = wc_get_product(get_the_ID());
if (!$product) continue;
$img_id = $product->get_image_id();
$img_url = $img_id ? wp_get_attachment_image_url($img_id, 'rar-product-card') : '';
$sku = $product->get_sku() ?: 'SKU-' . $product->get_id();
$cats = get_the_terms(get_the_ID(), 'product_cat');
$catname = $cats ? $cats[0]->name : '';
$price = $product->get_price_html();
$url = get_permalink();
$stock = $product->get_stock_status();
$tag = $product->is_featured() ? 'Featured' : '';
if ($product->is_on_sale()) $tag = 'Sale';
if ($stock === 'onbackorder') $tag = 'Backorder';
$stock_label = $stock === 'instock' ? 'IN STOCK' : ($stock === 'onbackorder' ? 'BACKORDER' : 'OUT OF STOCK');
$stock_color = $stock === 'instock' ? 'var(--olive-dark)' : ($stock === 'onbackorder' ? 'var(--ink-faint)' : 'var(--stamp)');
?>
<a href="<?php echo esc_url($url); ?>" class="rar-card">
<div class="rar-card__media">
<div class="rar-card__sku">SKU <?php echo esc_html($sku); ?></div>
<?php if ($tag) : ?>
<div class="rar-card__badge"><?php echo esc_html($tag); ?></div>
<?php endif; ?>
<?php if ($img_url) : ?>
<img src="<?php echo esc_url($img_url); ?>" alt="<?php echo esc_attr($product->get_name()); ?>" />
<?php else : ?>
<div class="rar-placeholder__label"><?php echo esc_html(strtoupper($catname ?: $product->get_name())); ?></div>
<?php endif; ?>
</div>
<div class="rar-card__body">
<?php if ($catname) : ?>
<div class="rar-card__cat"><?php echo esc_html($catname); ?></div>
<?php endif; ?>
<div class="rar-card__title"><?php echo esc_html($product->get_name()); ?></div>
<div class="rar-card__row">
<span class="rar-card__price"><?php echo wp_kses_post($price); ?></span>
<span style="color:<?php echo esc_attr($stock_color); ?>;font-family:var(--mono);font-size:9px;letter-spacing:0.18em;"><?php echo esc_html($stock_label); ?></span>
</div>
</div>
</a>
<?php
endwhile;
else :
echo '<p style="font-family:var(--serif);font-size:18px;font-style:italic;color:var(--ink-muted);grid-column:1/-1;">No products found. The warehouse is confused.</p>';
endif;
?>
</div>
<!-- Pagination -->
<div class="rar-pagination">
<span class="rar-mono" style="font-size:10px;letter-spacing:0.16em;text-transform:uppercase;color:var(--ink-muted);">
Page <?php echo max(1, get_query_var('paged')); ?> of <?php echo max(1, $wp_query->max_num_pages); ?>
</span>
<div class="rar-page-btns">
<?php
the_posts_pagination([
'mid_size' => 2,
'prev_text' => '',
'next_text' => '',
'screen_reader_text' => ' ',
'before_page_number' => '',
'after_page_number' => '',
]);
?>
</div>
</div>
</div>
</div>
<?php get_footer('shop'); ?>