WooCommerce商品归档页灵活插内容:求无需改模板的钩子方案
Alright, let's fix this problem the right way—no template edits required, just using WooCommerce's built-in hooks to get flexible, category-specific content insertion. First, let's cover why your original code didn't work:
- You were checking
$wp_query->current_post == 1, which only targets the 2nd product (since the index starts at 0) - You modified the template file, but missed using the proper WooCommerce hooks designed exactly for this use case
Instead, we'll use the woocommerce_after_shop_loop_item hook—it runs right after each product in the archive loop, so we can inject content conditionally without touching template files.
Option 1: Hardcoded Category Configuration (Quick Setup)
This is perfect if you want a set-it-and-forget-it setup with different rules per category. Add this to your theme's functions.php file or a custom code plugin like Code Snippets:
/** * Inject custom content after every Nth product in WooCommerce category archives */ function wc_insert_custom_content_after_products() { global $wp_query, $product; // Only run on product category archive pages if ( ! is_product_category() ) return; // Get the current category's slug $current_category = get_queried_object(); $category_slug = $current_category->slug; // Configure your rules here—add/remove categories as needed $category_rules = array( 'electronics' => array( 'interval' => 3, // Insert after 3rd, 6th, 9th... products 'content' => '<div class="custom-archive-content"><h4>Pro Tip!</h4><p>Check out our exclusive electronics warranty plans.</p></div>' ), 'clothing' => array( 'interval' => 2, // Insert after 2nd, 4th, 6th... products 'content' => '<div class="custom-archive-content"><p>Free shipping on all clothing orders over $50!</p></div>' ), 'books' => array( 'interval' => 4, // Insert after 4th, 8th, 12th... products 'content' => '<div class="custom-archive-content"><p>New releases added weekly—subscribe to our newsletter!</p></div>' ) ); // Skip if current category has no rules set if ( ! isset( $category_rules[$category_slug] ) ) return; $rules = $category_rules[$category_slug]; $interval = $rules['interval']; $content = $rules['content']; // Get 1-based position of current product (since current_post starts at 0) $current_position = $wp_query->current_post + 1; // Insert content if current position is a multiple of the interval if ( $current_position % $interval === 0 ) { echo $content; } } add_action( 'woocommerce_after_shop_loop_item', 'wc_insert_custom_content_after_products', 10 );
How This Works:
- We first check if we're on a product category archive to avoid running this code elsewhere
- We map category slugs to their specific rules (interval and content)
- We calculate the 1-based position of the current product (so the 3rd product is position 3, not 2)
- If the position is a multiple of the interval, we echo our custom content
Option 2: Admin-Configurable Categories (Flexible, No Code Edits Later)
If you want to adjust rules directly from the WordPress admin (without touching code), we can add custom fields to the product category edit page:
Step 1: Add Custom Fields to Category Edit Page
/** * Add custom fields to product category edit screen */ function wc_add_category_insertion_fields() { ?> <div class="form-field"> <label for="insert_interval"><?php _e( 'Content Insert Interval', 'your-text-domain' ); ?></label> <input type="number" name="insert_interval" id="insert_interval" value="" min="1" placeholder="e.g., 3"> <p class="description"><?php _e( 'Insert content after every Nth product (3 = after 3rd, 6th, 9th...)', 'your-text-domain' ); ?></p> </div> <div class="form-field"> <label for="insert_content"><?php _e( 'Custom Insert Content', 'your-text-domain' ); ?></label> <textarea name="insert_content" id="insert_content" rows="4" placeholder="Add HTML or text here..."></textarea> <p class="description"><?php _e( 'Content to display after specified products', 'your-text-domain' ); ?></p> </div> <?php } add_action( 'product_cat_add_form_fields', 'wc_add_category_insertion_fields', 10 ); add_action( 'product_cat_edit_form_fields', 'wc_add_category_insertion_fields', 10 );
Step 2: Save the Custom Field Data
/** * Save custom category fields when category is updated/created */ function wc_save_category_insertion_fields( $term_id ) { // Save interval value if ( isset( $_POST['insert_interval'] ) ) { update_term_meta( $term_id, 'insert_interval', absint( $_POST['insert_interval'] ) ); } // Save content (sanitize for safety) if ( isset( $_POST['insert_content'] ) ) { update_term_meta( $term_id, 'insert_content', wp_kses_post( $_POST['insert_content'] ) ); } } add_action( 'edited_product_cat', 'wc_save_category_insertion_fields', 10 ); add_action( 'create_product_cat', 'wc_save_category_insertion_fields', 10 );
Step 3: The Insertion Logic
/** * Insert content based on admin-configured category settings */ function wc_insert_admin_configured_content() { global $wp_query, $product; if ( ! is_product_category() ) return; $current_category = get_queried_object(); // Get saved settings from category meta $interval = get_term_meta( $current_category->term_id, 'insert_interval', true ); $content = get_term_meta( $current_category->term_id, 'insert_content', true ); // Skip if no interval or content is set if ( empty( $interval ) || empty( $content ) ) return; $current_position = $wp_query->current_post + 1; if ( $current_position % $interval === 0 ) { echo $content; } } add_action( 'woocommerce_after_shop_loop_item', 'wc_insert_admin_configured_content', 10 );
How This Works:
- You'll now see two new fields on every product category edit page: "Content Insert Interval" and "Custom Insert Content"
- Set the interval (e.g., 3) and your desired content (supports HTML)
- The code automatically reads these settings and inserts content at the specified positions
Why This Beats Your Original Code:
- No template edits: All logic uses official WooCommerce hooks, so theme updates won't break your changes
- Full flexibility: Either hardcode rules or let admins configure them via the dashboard
- Targets all multiples of your interval (3,6,9...) instead of a single position
Pro Tip:
Add CSS to style your inserted content:
.custom-archive-content { padding: 1rem; background: #f8f9fa; margin: 1rem 0; border-radius: 4px; text-align: center; }
内容的提问来源于stack exchange,提问作者Cray

