60, 'width' => 200, 'flex-height' => true, 'flex-width' => true, 'header-text' => array( 'site-title', 'site-description' ), ) ); add_theme_support( 'woocommerce' ); add_theme_support( 'wc-product-gallery-zoom' ); add_theme_support( 'wc-product-gallery-lightbox' ); add_theme_support( 'wc-product-gallery-slider' ); add_theme_support( 'html5', array( 'search-form', 'comment-form', 'comment-list', 'gallery', 'caption', 'style', 'script', ) ); add_theme_support( 'align-wide' ); add_theme_support( 'responsive-embeds' ); register_nav_menus( array( 'primary' => esc_html__( 'منوی اصلی', 'motayeb' ), 'footer' => esc_html__( 'منوی فوتر', 'motayeb' ), ) ); add_image_size( 'motayeb-product-grid', 400, 400, true ); add_image_size( 'motayeb-product-single', 600, 600, true ); } add_action( 'after_setup_theme', 'motayeb_theme_setup' ); // ============================================================ // ۲. بارگذاری فایل‌های استایل و اسکریپت (Enqueue) — اصلاح‌شده // ============================================================ /** * تابع کمکی: enqueue امن برای استایل — فقط اگه فایل وجود داشته باشه. * از filemtime برای cache-busting استفاده می‌کنه تا با هر تغییر، کش مرورگر بشکنه. */ function motayeb_enqueue_style_safe( $handle, $rel_path, $deps = array(), $media = 'all' ) { $path = get_theme_file_path( $rel_path ); if ( ! $path || ! file_exists( $path ) || 0 === filesize( $path ) ) { return false; } wp_enqueue_style( $handle, get_theme_file_uri( $rel_path ), $deps, filemtime( $path ), $media ); return true; } /** * تابع کمکی: enqueue امن برای اسکریپت — فقط اگه فایل وجود داشته باشه. * jQuery به‌صورت پیش‌فرض بارگذاری نمی‌شه؛ اگه واقعاً لازم بود، deps بده. */ function motayeb_enqueue_script_safe( $handle, $rel_path, $deps = array(), $in_footer = true ) { $path = get_theme_file_path( $rel_path ); if ( ! $path || ! file_exists( $path ) || 0 === filesize( $path ) ) { return false; } wp_enqueue_script( $handle, get_theme_file_uri( $rel_path ), $deps, filemtime( $path ), $in_footer ); return true; } function motayeb_scripts() { $ver = MOTAYEB_VERSION; // ۱. استایل اصلی تم (style.css در ریشه) wp_enqueue_style( 'motayeb-style', get_stylesheet_uri(), array(), $ver ); // ۲. استایل Tailwind ساخته‌شده (پس از build استاتیک جایگزین Play CDN می‌شه) motayeb_enqueue_style_safe( 'motayeb-tailwind', '/assets/css/tailwind.css', array( 'motayeb-style' ) ); // ۳. استایل ووکامرس — فقط اگه فایل واقعاً وجود داشت و خالی نبود if ( class_exists( 'WooCommerce' ) ) { motayeb_enqueue_style_safe( 'motayeb-woocommerce', '/assets/css/woocommerce.css', array( 'motayeb-style' ) ); } // ۴. استایل ریسپانسیو motayeb_enqueue_style_safe( 'motayeb-responsive', '/assets/css/responsive.css', array( 'motayeb-style' ) ); // ۵. اسکریپت اصلی (بدون jQuery — فرض بر اینه که با vanilla JS نوشته شده) $main_loaded = motayeb_enqueue_script_safe( 'motayeb-main', '/assets/js/main.js' ); // ۶. پاس دادن متغیرها به JS — با guard ووکامرس if ( $main_loaded ) { $localize_data = array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( MOTAYEB_NONCE_ACTION ), 'home_url' => home_url( '/' ), ); if ( class_exists( 'WooCommerce' ) ) { $localize_data['checkout_url'] = wc_get_checkout_url(); $localize_data['cart_url'] = wc_get_cart_url(); } wp_localize_script( 'motayeb-main', 'motayeb_ajax', $localize_data ); } // ۷. اسکریپت ووکامرس — فقط روی صفحات فروشگاهی و اگه فایل پر بود if ( class_exists( 'WooCommerce' ) ) { if ( is_woocommerce() || is_cart() || is_checkout() || is_account_page() ) { motayeb_enqueue_script_safe( 'motayeb-woocommerce', '/assets/js/woocommerce.js', array( 'motayeb-main' ) ); } } // ۸. اسکریپت دارک‌مود motayeb_enqueue_script_safe( 'motayeb-darkmode', '/assets/js/darkmode.js' ); // ۹. اسکریپت‌های پیش‌فرض ووکامرس روی صفحات مربوطه if ( class_exists( 'WooCommerce' ) ) { if ( is_product() ) { wp_enqueue_script( 'wc-single-product' ); } if ( is_cart() ) { wp_enqueue_script( 'wc-cart' ); } if ( is_checkout() ) { wp_enqueue_script( 'wc-checkout' ); } } } add_action( 'wp_enqueue_scripts', 'motayeb_scripts' ); /** * افزودن `defer` به اسکریپت‌های خودمان برای بهبود بارگذاری. * این کار parsing HTML رو مسدود نمی‌کنه. */ function motayeb_script_loader_tag( $tag, $handle ) { $defer_handles = array( 'motayeb-main', 'motayeb-darkmode', 'motayeb-woocommerce' ); if ( in_array( $handle, $defer_handles, true ) ) { return str_replace( ' src', ' defer src', $tag ); } return $tag; } add_filter( 'script_loader_tag', 'motayeb_script_loader_tag', 10, 2 ); // ============================================================ // ۳. ثبت ناحیه‌های ویجت (Widget Areas) // ============================================================ function motayeb_widgets_init() { register_sidebar( array( 'name' => esc_html__( 'سایدبار اصلی', 'motayeb' ), 'id' => 'sidebar-main', 'before_widget' => '
', 'after_widget' => '
', 'before_title' => '

', 'after_title' => '

', ) ); if ( class_exists( 'WooCommerce' ) ) { register_sidebar( array( 'name' => esc_html__( 'سایدبار فروشگاه', 'motayeb' ), 'id' => 'sidebar-shop', 'before_widget' => '
', 'after_widget' => '
', 'before_title' => '

', 'after_title' => '

', ) ); } for ( $i = 1; $i <= 4; $i++ ) { register_sidebar( array( 'name' => esc_html__( 'فوتر - ستون ' . $i, 'motayeb' ), 'id' => 'footer-' . $i, 'before_widget' => '', 'before_title' => '', ) ); } } add_action( 'widgets_init', 'motayeb_widgets_init' ); // ============================================================ // ۴. توابع کمکی ووکامرس // ============================================================ add_filter( 'loop_shop_columns', function() { return 4; } ); add_filter( 'loop_shop_per_page', function() { return 12; } ); function motayeb_body_classes( $classes ) { if ( class_exists( 'WooCommerce' ) ) { if ( is_product() ) { $classes[] = 'motayeb-product-page'; } if ( is_shop() ) { $classes[] = 'motayeb-shop-page'; } } // کوکی با sanitize_key بررسی می‌شه تا فقط 'on' یا '' قبول بشه if ( isset( $_COOKIE['motayeb_darkmode'] ) && 'on' === sanitize_key( wp_unslash( $_COOKIE['motayeb_darkmode'] ) ) ) { $classes[] = 'dark-mode'; } return $classes; } add_filter( 'body_class', 'motayeb_body_classes' ); // ============================================================ // ۵. کلاس‌های Walker برای منو // ============================================================ class Motayeb_Desktop_Walker extends Walker_Nav_Menu { public function start_lvl( &$output, $depth = 0, $args = array() ) { $output .= '