/** * --- Per-widget grid controller for Elementor Products / Archive Products --- * Reads widget settings (columns, rows) and applies them only during that widget's render * so Woo outputs the exact grid requested by the widget. */ if (!isset($GLOBALS['plf_el_widget_stack'])) { $GLOBALS['plf_el_widget_stack'] = []; } function plf_push_widget_grid_controls($cols, $rows) { $state = [ 'cols' => max(1, (int)$cols), 'pp' => max(1, (int)$cols) * max(1, (int)$rows), 'cols_filter_added' => false, 'pp_filter_added' => false, ]; // Columns filter (late to beat theme) $state['cols_cb'] = add_filter('loop_shop_columns', function($c) use (&$state) { return $state['cols']; }, 9999); // Per-page filter $state['pp_cb'] = add_filter('loop_shop_per_page', function($pp) use (&$state) { return $state['pp']; }, 9999); $GLOBALS['plf_el_widget_stack'][] = $state; } function plf_pop_widget_grid_controls() { $state = array_pop($GLOBALS['plf_el_widget_stack']); if (!$state) return; // Remove the specific callbacks we added remove_filter('loop_shop_columns', $state['cols_cb'], 9999); remove_filter('loop_shop_per_page', $state['pp_cb'], 9999); } /** * Identify widget types and capture their settings * Works for: * - Archive Products widget (Elementor Pro archive loop) * - Products widget (Elementor Pro products grid) */ add_action('elementor/widget/before_render_content', function($widget) { if (!is_object($widget) || !method_exists($widget, 'get_name')) return; $name = $widget->get_name(); // Normalize widget types $is_archive_products = $name === 'woocommerce-archive-products' || $name === 'archive-products' || $name === 'woocommerce-products-archive'; $is_products = $name === 'woocommerce-products' || $name === 'products'; if (!$is_archive_products && !$is_products) return; if (!method_exists($widget, 'get_settings_for_display')) return; $s = $widget->get_settings_for_display(); if (!is_array($s)) return; // Elementor control names (desktop) $cols = isset($s['columns']) ? (int)$s['columns'] : 0; $rows = isset($s['rows']) ? (int)$s['rows'] : 0; // Some widget variations name the row count differently; fall back if needed if ($rows <= 0 && isset($s['rows_count'])) $rows = (int)$s['rows_count']; if ($cols <= 0) $cols = 4; // safe fallback if ($rows <= 0) $rows = 1; // safe fallback // Activate per-widget loop overrides for the duration of THIS widget render plf_push_widget_grid_controls($cols, $rows); }, 8); // earlier than your other captures so props are ready // After the widget output, remove overrides so other widgets/pages are unaffected add_action('elementor/widget/after_render_content', function($widget) { if (!is_object($widget) || !method_exists($widget, 'get_name')) return; $name = $widget->get_name(); $is_archive_products = $name === 'woocommerce-archive-products' || $name === 'archive-products' || $name === 'woocommerce-products-archive'; $is_products = $name === 'woocommerce-products' || $name === 'products'; if (!$is_archive_products && !$is_products) return; plf_pop_widget_grid_controls(); }, 9999); Black Powder Archives - Page 3 of 17 - Powder & Lead