Files
mataba/shop/xshop-theme/woocommerce/archive-product.php
T

104 lines
4.3 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
/**
* Shop / category archive — XShop filters + AJAX grid + no-JS fallback.
*
* Integrates product-filters sidebar (desktop) + drawer (mobile) + toolbar.
* Server render uses Woo hooks + ProductQuery via pre_get_posts (inc/woocommerce/setup.php) for no-JS.
* JS enhances via REST /xshop/v1/products.
*
* WC version tested: 11.1.0
* Template version: 3.4.0
*/
defined('ABSPATH') || exit;
get_header('shop');
do_action('woocommerce_before_main_content');
if (is_product_category() || is_product_tag() || is_tax('product_brand')) {
$term = get_queried_object();
if ($term instanceof WP_Term) {
echo '<header class="xshop-page-header">';
echo '<h1 class="xshop-page-header__title">' . esc_html($term->name) . '</h1>';
if (!empty($term->description)) {
echo '<div class="xshop-page-header__desc">' . wp_kses_post(wpautop($term->description)) . '</div>';
}
echo '<p class="xshop-text-muted" style="font-size:var(--xshop-text-sm)">' . esc_html(sprintf(esc_html__('%s products', 'xshop'), number_format_i18n((int) $term->count))) . '</p>';
echo '</header>';
}
} elseif (is_shop()) {
$shopId = wc_get_page_id('shop');
$title = $shopId ? get_the_title($shopId) : esc_html__('Shop', 'xshop');
echo '<header class="xshop-page-header"><h1 class="xshop-page-header__title">' . esc_html($title) . '</h1></header>';
}
?>
<div class="xshop-shop" data-xshop-shop>
<!-- Mobile filter toggle -->
<button type="button" class="xshop-btn xshop-btn--secondary xshop-shop__filter-toggle" data-xshop-drawer-toggle aria-expanded="false" aria-controls="xshop-filter-drawer">
<?php esc_html_e('Filters', 'xshop'); ?>
</button>
<div class="xshop-shop__layout">
<!-- Desktop sidebar -->
<aside class="xshop-shop__sidebar" aria-label="<?php esc_attr_e('Filters', 'xshop'); ?>">
<?php get_template_part('template-parts/components/product-filters'); ?>
</aside>
<!-- Mobile drawer -->
<div class="xshop-drawer" id="xshop-filter-drawer" hidden data-xshop-drawer role="dialog" aria-modal="true" aria-label="<?php esc_attr_e('Filters', 'xshop'); ?>">
<div class="xshop-drawer__header">
<h2 class="xshop-drawer__title"><?php esc_html_e('Filters', 'xshop'); ?></h2>
<button type="button" class="xshop-btn xshop-btn--ghost" data-xshop-drawer-close aria-label="<?php esc_attr_e('Close filters', 'xshop'); ?>">×</button>
</div>
<div class="xshop-drawer__body">
<?php get_template_part('template-parts/components/product-filters'); ?>
</div>
</div>
<div class="xshop-drawer__overlay" hidden data-xshop-drawer-overlay></div>
<!-- Main -->
<div class="xshop-shop__main" data-xshop-shop-main>
<div class="xshop-shop__toolbar" data-xshop-toolbar>
<?php do_action('woocommerce_before_shop_loop'); ?>
</div>
<div class="xshop-search__loading" hidden data-xshop-loading style="display:none">
<span class="xshop-loading__spinner" aria-hidden="true"></span> <?php esc_html_e('Loading…', 'xshop'); ?>
</div>
<div class="xshop-search__error" hidden data-xshop-error role="alert"></div>
<div data-xshop-products-container>
<?php
if (woocommerce_product_loop()) {
woocommerce_product_loop_start();
while (have_posts()) { the_post(); do_action('woocommerce_shop_loop'); wc_get_template_part('content', 'product'); }
woocommerce_product_loop_end();
do_action('woocommerce_after_shop_loop');
} else {
do_action('woocommerce_no_products_found');
get_template_part('template-parts/components/empty-state', null, [
'title' => esc_html__('No products found', 'xshop'),
'text' => esc_html__('Try adjusting your filters or browse all products.', 'xshop'),
'cta_label' => esc_html__('Browse shop', 'xshop'),
'cta_url' => wc_get_page_permalink('shop'),
]);
}
?>
</div>
<div data-xshop-pagination>
<?php
// Woo pagination rendered via woocommerce_after_shop_loop already inside loop; for AJAX we render custom via JS
// Ensure result count is accessible
?>
</div>
</div>
</div>
</div>
<?php
do_action('woocommerce_after_main_content');
get_footer('shop');