motayeb/archive.php
Kazem Alghasi c16648678d - install local Tailwind
- fix more problems
2026-09-23 00:32:16 +03:30

278 lines
15 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
/**
* صفحه فروشگاه (آرشیو محصولات) - مطابق با UI Kolli.html
*
* @package Motayeb
* @version 1.0.1
*
* تغییرات نسخه ۱.۰.۱:
* - guard کامل WooCommerce (بدون fatal error اگه غیرفعال باشه)
* - رفع term_description با wp_kses_post
* - افزودن دکمه toggle فیلتر در موبایل
* - افزودن نمایش فیلترهای فعال
* - استفاده از motayeb_count_category_products (شامل زیردسته‌ها)
* - Breadcrumb Schema برای صفحات دسته‌بندی
* - aria-label روی sectionها
* - width/height + fetchpriority روی بنر
* - رفع sticky همپوشانی با هدر
* - استایل Tailwind-friendly برای pagination و ordering
* - اعتبارسنجی فیلتر قیمت
*/
get_header();
// guard: اگه ووکامرس غیرفعال باشه
if ( ! class_exists( 'WooCommerce' ) ) {
echo '<main class="pt-16 md:pt-20"><div class="max-w-7xl mx-auto px-4 py-20 text-center">';
echo '<h1 class="text-2xl font-bold mb-4">فروشگاه فعال نیست</h1>';
echo '<p class="text-cream-500">برای مشاهده محصولات، افزونه ووکامرس را فعال کنید.</p>';
echo '</div></main>';
get_footer();
return;
}
// داده‌های صفحه
$banner_img = get_option( 'motayeb_shop_banner', '' );
$banner_img = $banner_img ? $banner_img : 'https://picsum.photos/seed/forest-shop/1600/600';
$is_category = is_product_category();
$current_term = $is_category ? get_queried_object() : null;
// بررسی اینکه آیا سایدبار فیلتر داره یا خیر
$has_shop_sidebar = is_active_sidebar( 'sidebar-shop' );
?>
<!-- ===== SHOP HEADER ===== -->
<section class="relative py-20 md:py-28 overflow-hidden" aria-label="عنوان فروشگاه">
<div class="absolute inset-0">
<img src="<?php echo esc_url( $banner_img ); ?>"
alt="<?php echo esc_attr( $is_category && $current_term ? $current_term->name : 'فروشگاه مطیب' ); ?>"
width="1600" height="600"
fetchpriority="high"
decoding="async"
class="w-full h-full object-cover">
</div>
<div class="absolute inset-0 bg-gradient-to-t from-forest-900/90 via-forest-700/70 to-forest-500/40" aria-hidden="true"></div>
<div class="relative max-w-7xl mx-auto px-4 md:px-6 text-center">
<h1 class="text-3xl md:text-4xl lg:text-5xl font-extrabold text-white drop-shadow-md">
<?php woocommerce_page_title(); ?>
</h1>
<?php if ( $is_category && $current_term && $current_term->description ) : ?>
<p class="text-white/90 text-center mt-3 max-w-2xl mx-auto drop-shadow-md text-sm md:text-base">
<?php echo wp_kses_post( wpautop( $current_term->description ) ); ?>
</p>
<?php endif; ?>
</div>
</section>
<!-- ===== FEATURES ===== -->
<div class="relative z-10 -mt-8 lg:-mt-12 max-w-7xl mx-auto px-4 md:px-6 mb-8">
<div class="grid grid-cols-2 md:grid-cols-4 gap-3 md:gap-4 bg-white/90 dark:bg-dark-card/90 backdrop-blur-lg p-4 md:p-5 rounded-2xl shadow-lg border border-cream-200/50 dark:border-dark-border/50">
<?php for ( $i = 1; $i <= 4; $i++ ) : ?>
<?php
$default_icons = array( 1 => 'lucide:leaf', 2 => 'lucide:truck', 3 => 'lucide:shield-check', 4 => 'lucide:package' );
$icon = get_option( 'motayeb_feature_' . $i . '_icon', $default_icons[ $i ] );
$text = get_option( 'motayeb_feature_' . $i . '_text', 'ویژگی ' . $i );
?>
<div class="flex items-center gap-3 justify-center">
<iconify-icon icon="<?php echo esc_attr( $icon ); ?>" width="22" class="text-forest-500 dark:text-forest-300 flex-shrink-0"></iconify-icon>
<span class="text-xs md:text-sm font-medium text-earth-400 dark:text-dark-text"><?php echo esc_html( $text ); ?></span>
</div>
<?php endfor; ?>
</div>
</div>
<!-- ===== Breadcrumb (برای صفحات دسته‌بندی) ===== -->
<?php if ( $is_category && $current_term ) :
// ساخت BreadcrumbList Schema
$crumbs = array(
array( 'name' => 'خانه', 'url' => home_url( '/' ) ),
array( 'name' => 'فروشگاه', 'url' => get_permalink( wc_get_page_id( 'shop' ) ) ),
);
// افزودن دسته‌بندی‌های والد
$parents = get_ancestors( $current_term->term_id, 'product_cat' );
$parents = array_reverse( $parents );
foreach ( $parents as $parent_id ) {
$parent = get_term( $parent_id, 'product_cat' );
if ( $parent && ! is_wp_error( $parent ) ) {
$crumbs[] = array( 'name' => $parent->name, 'url' => get_term_link( $parent ) );
}
}
$crumbs[] = array( 'name' => $current_term->name, 'url' => get_term_link( $current_term ) );
$breadcrumb_schema = array(
'@context' => 'https://schema.org',
'@type' => 'BreadcrumbList',
'itemListElement' => array(),
);
foreach ( $crumbs as $index => $crumb ) {
$breadcrumb_schema['itemListElement'][] = array(
'@type' => 'ListItem',
'position' => $index + 1,
'name' => $crumb['name'],
'item' => $crumb['url'],
);
}
?>
<nav class="max-w-7xl mx-auto px-4 md:px-6 mb-4 text-xs text-cream-500 dark:text-dark-muted flex items-center gap-2 flex-wrap" aria-label="مسیر صفحه">
<?php foreach ( $crumbs as $index => $crumb ) :
$is_last = ( $index === count( $crumbs ) - 1 );
?>
<?php if ( ! $is_last ) : ?>
<a href="<?php echo esc_url( $crumb['url'] ); ?>" class="hover:text-forest-500 dark:hover:text-forest-300 transition"><?php echo esc_html( $crumb['name'] ); ?></a>
<iconify-icon icon="lucide:chevron-left" width="14"></iconify-icon>
<?php else : ?>
<span class="text-earth-400 dark:text-dark-text font-medium"><?php echo esc_html( $crumb['name'] ); ?></span>
<?php endif; ?>
<?php endforeach; ?>
</nav>
<script type="application/ld+json"><?php echo wp_json_encode( $breadcrumb_schema ); ?></script>
<?php endif; ?>
<!-- ===== SHOP CONTENT ===== -->
<section class="pb-8 md:pb-12 bg-cream-100 dark:bg-dark-bg" aria-label="محصولات فروشگاه">
<div class="max-w-7xl mx-auto px-4 md:px-6">
<!-- دکمه toggle فیلتر در موبایل -->
<button id="filter-toggle"
class="lg:hidden w-full mb-4 flex items-center justify-center gap-2 py-3 bg-white dark:bg-dark-card rounded-xl border border-cream-200 dark:border-dark-border text-sm font-medium hover:bg-cream-50 dark:hover:bg-dark-bg transition"
aria-label="نمایش فیلترها"
aria-expanded="false"
aria-controls="shop-sidebar">
<iconify-icon icon="lucide:sliders-horizontal" width="18"></iconify-icon>
<span>فیلترها</span>
<iconify-icon icon="lucide:chevron-down" width="16" class="transition-transform" id="filter-toggle-icon"></iconify-icon>
</button>
<div class="flex flex-col lg:flex-row gap-8">
<!-- Sidebar -->
<aside id="shop-sidebar"
class="lg:w-1/4 xl:w-1/5 flex-shrink-0 <?php echo $has_shop_sidebar ? '' : 'hidden lg:block'; ?> lg:!block"
aria-label="فیلترهای فروشگاه">
<div class="bg-white dark:bg-dark-card rounded-2xl p-5 border border-cream-200/50 dark:border-dark-border/50 lg:sticky lg:top-28">
<?php if ( $has_shop_sidebar ) : ?>
<?php dynamic_sidebar( 'sidebar-shop' ); ?>
<?php else : ?>
<!-- ===== پیش‌فرض: دسته‌بندی‌ها ===== -->
<div class="mb-6">
<h3 class="font-bold text-sm mb-3 text-earth-400 dark:text-dark-text">دسته‌بندی محصولات</h3>
<ul class="space-y-2 text-sm">
<?php
$product_categories = get_terms( array(
'taxonomy' => 'product_cat',
'hide_empty' => true,
'parent' => 0,
) );
if ( ! empty( $product_categories ) && ! is_wp_error( $product_categories ) ) {
foreach ( $product_categories as $cat ) {
$count = motayeb_count_category_products( $cat->term_id );
$is_active = ( $is_category && $current_term && $current_term->term_id === $cat->term_id );
echo '<li><a href="' . esc_url( get_term_link( $cat ) ) . '" class="text-cream-500 dark:text-dark-muted hover:text-forest-500 dark:hover:text-forest-300 transition flex items-center justify-between py-1.5 px-2 rounded-lg ' . ( $is_active ? 'bg-forest-50 dark:bg-forest-900/30 text-forest-500 dark:text-forest-300 font-medium' : '' ) . '">';
echo '<span>' . esc_html( $cat->name ) . '</span>';
echo '<span class="text-xs bg-cream-100 dark:bg-dark-bg px-2 py-0.5 rounded-full">' . esc_html( motayeb_fa_count( $count ) ) . '</span>';
echo '</a></li>';
}
} else {
echo '<li class="text-cream-400 dark:text-dark-muted text-xs">هیچ دسته‌بندی وجود ندارد.</li>';
}
?>
</ul>
</div>
<!-- ===== فیلتر قیمت ===== -->
<div>
<h3 class="font-bold text-sm mb-3 text-earth-400 dark:text-dark-text">فیلتر قیمت</h3>
<form method="get" action="<?php echo esc_url( wc_get_page_permalink( 'shop' ) ); ?>">
<div class="flex items-center gap-2 mb-3">
<input type="number" name="min_price" placeholder="حداقل" min="0"
value="<?php echo esc_attr( isset( $_GET['min_price'] ) ? intval( $_GET['min_price'] ) : '' ); ?>"
class="w-1/2 px-3 py-2 bg-cream-50 dark:bg-dark-bg border border-cream-200 dark:border-dark-border rounded-xl text-sm outline-none focus:border-forest-500 dark:focus:border-forest-300 transition placeholder:text-cream-400 dark:placeholder:text-dark-muted">
<span class="text-cream-400 dark:text-dark-muted">تا</span>
<input type="number" name="max_price" placeholder="حداکثر" min="0"
value="<?php echo esc_attr( isset( $_GET['max_price'] ) ? intval( $_GET['max_price'] ) : '' ); ?>"
class="w-1/2 px-3 py-2 bg-cream-50 dark:bg-dark-bg border border-cream-200 dark:border-dark-border rounded-xl text-sm outline-none focus:border-forest-500 dark:focus:border-forest-300 transition placeholder:text-cream-400 dark:placeholder:text-dark-muted">
</div>
<button type="submit" class="w-full py-2 bg-forest-500 text-white rounded-xl text-sm font-medium hover:bg-forest-600 transition">اعمال فیلتر</button>
</form>
</div>
<?php endif; ?>
</div>
</aside>
<!-- Product Grid -->
<div class="lg:w-3/4 xl:w-4/5">
<!-- Toolbar -->
<div class="flex flex-wrap items-center justify-between gap-4 mb-6 bg-white dark:bg-dark-card rounded-2xl p-4 border border-cream-200/50 dark:border-dark-border/50 motayeb-shop-toolbar">
<div class="flex items-center gap-3 text-sm text-cream-500 dark:text-dark-muted">
<span class="motayeb-result-count"><?php woocommerce_result_count(); ?></span>
</div>
<div class="flex items-center gap-3 motayeb-ordering">
<?php woocommerce_catalog_ordering(); ?>
</div>
</div>
<!-- نمایش فیلترهای فعال -->
<?php
// نمایش فیلترهای فعال (اگه ووکامرس ساپورت کنه)
if ( function_exists( 'woocommerce_output_active_filters' ) ) {
echo '<div class="mb-4 motayeb-active-filters">';
the_widget( 'WC_Widget_Price_Filter' );
echo '</div>';
}
?>
<!-- Products -->
<?php if ( woocommerce_product_loop() ) : ?>
<div class="grid grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 motayeb-products-grid">
<?php while ( have_posts() ) : the_post(); ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; ?>
</div>
<div class="mt-10 motayeb-pagination">
<?php woocommerce_pagination(); ?>
</div>
<?php else : ?>
<div class="text-center py-16">
<iconify-icon icon="lucide:package-x" width="64" class="text-cream-400 dark:text-dark-muted mx-auto mb-4"></iconify-icon>
<p class="text-cream-500 dark:text-dark-muted mb-4">محصولی یافت نشد.</p>
<a href="<?php echo esc_url( get_permalink( wc_get_page_id( 'shop' ) ) ); ?>" class="inline-flex items-center gap-2 px-6 py-2.5 bg-forest-500 text-white rounded-xl text-sm hover:bg-forest-600 transition">
<iconify-icon icon="lucide:rotate-ccw" width="16"></iconify-icon>
<span>نمایش همه محصولات</span>
</a>
</div>
<?php endif; ?>
</div>
</div>
</div>
</section>
<script>
// toggle فیلتر در موبایل
(function() {
var btn = document.getElementById('filter-toggle');
var sidebar = document.getElementById('shop-sidebar');
var icon = document.getElementById('filter-toggle-icon');
if (!btn || !sidebar) return;
btn.addEventListener('click', function() {
var isHidden = sidebar.classList.contains('hidden');
if (isHidden) {
sidebar.classList.remove('hidden');
btn.setAttribute('aria-expanded', 'true');
if (icon) icon.style.transform = 'rotate(180deg)';
} else {
sidebar.classList.add('hidden');
btn.setAttribute('aria-expanded', 'false');
if (icon) icon.style.transform = '';
}
});
// روی دسکتاپ، همیشه visible
window.addEventListener('resize', function() {
if (window.innerWidth >= 1024) {
sidebar.classList.remove('hidden');
}
});
})();
</script>
<?php
get_footer();