fervor [>]CODING & CURIOSITY
FERVOR LEARNING SYSTEMTUTORIALS
← WordPress

WordPress / 12 MIN READ

Woo Commerce Product Accordion

Creating WooCommerce Product Accordions with Custom Expand/Collapse Behavior

From the original Fervor library. Examples may use older package versions.

Creating WooCommerce Product Accordions with Custom Expand/Collapse Behavior

In this tutorial, you’ll learn how to create a customized product accordion layout for your WooCommerce store. This accordion will display products in a table format with expandable sections showing detailed specifications and pricing tiers. The layout includes a two-column expanded view, allowing customers to view additional product details seamlessly.

Table of Contents


Prerequisites

Before you begin, ensure you have the following:

  • A WordPress website with WooCommerce installed and activated.
  • Basic knowledge of PHP, CSS, and JavaScript.
  • Access to your theme’s files (preferably using a child theme to prevent loss of customizations during updates).

Note: Always back up your website before making changes to theme files.


Step 1: Setting Up Custom Fields in WooCommerce

To display additional product information such as specifications and multiple pricing tiers, you’ll need to add custom fields to your WooCommerce products.

Adding Custom Fields via Advanced Custom Fields (ACF) Plugin

  1. Install and Activate ACF:

    • Navigate to Plugins > Add New in your WordPress dashboard.
    • Search for Advanced Custom Fields.
    • Install and activate the plugin.
  2. Create a New Field Group:

    • Go to Custom Fields > Add New.
    • Name the field group, e.g., Product Specifications and Pricing.
  3. Add Custom Fields:

    • Pricing Tiers:
      • Field Label: Price for 1-5 pcs.
      • Field Name: _price_1_5
      • Field Type: Number
      • Field Label: Price for 6-10 pcs.
      • Field Name: _price_6_10
      • Field Type: Number
      • Field Label: Price for 10+ pcs.
      • Field Name: _price_10_plus
      • Field Type: Number
    • Specifications:
      • Field Label: Center Wavelength
      • Field Name: _center_wavelength
      • Field Type: Text
      • Field Label: Bandwidth
      • Field Name: _bandwidth
      • Field Type: Text
      • <!-- Add additional specification fields as needed -->
  4. Set Location Rules:

    • Under Location, set the rule to display these fields if Post Type is equal to Product.
  5. Publish the Field Group:

    • Click Publish to save the field group.
  6. Populate Custom Fields for Products:

    • Edit each product and fill in the newly added custom fields with appropriate data.

Alternative: If you prefer not to use a plugin, you can add custom fields programmatically using WooCommerce’s built-in custom field functionality or by editing your theme’s functions.php. However, using ACF simplifies the process.


Step 2: Creating a Custom Template File

We’ll create a custom template file that structures the product accordion layout.

  1. Access Your Theme Directory:

    • Using FTP or your hosting file manager, navigate to wp-content/themes/your-active-theme/.
  2. Create a New Template File:

    • Create a new file named product-accordion-template.php.
  3. Add Template Header:

    • At the top of product-accordion-template.php, add the following lines to define it as a custom template:
    <?php
    /*
    Template Name: Product Accordion Template
    */
    ?>
    
  4. Insert the Provided PHP Code:

    • Paste the PHP code provided in your original message into this file. This code sets up the accordion structure, queries products, and displays them with custom fields.
    <?php
    /*
    Template Name: Product Accordion Template
    */
    
    get_header();
    ?>
    
    <div class="product-table-accordion">
        <div class="header-row">
            <div class="part-no">PART NO.</div>
            <div class="description">DESCRIPTION</div>
            <div class="price-1-5">1 - 5 pcs.</div>
            <div class="price-6-10">6 - 10 pcs.</div>
            <div class="price-10-plus">> 10 pcs.</div>
            <div class="stock">Stock Status</div>
            <div class="buy">Buy</div>
        </div>
    
        <?php
        $args = array(
            'post_type' => 'product',
            'posts_per_page' => -1,
        );
        $products = new WP_Query($args);
    
        if ($products->have_posts()) :
            while ($products->have_posts()) : $products->the_post();
                global $product;
                // Get your custom fields/attributes here
        ?>
            <div class="product-row">
                <div class="product-summary">
                    <div class="expand-button">▼</div>
                    <div class="part-no"><?php echo $product->get_sku(); ?></div>
                    <div class="description"><?php echo $product->get_name(); ?></div>
                    <div class="price-1-5">$<?php echo get_post_meta($product->get_id(), '_price_1_5', true); ?></div>
                    <div class="price-6-10">$<?php echo get_post_meta($product->get_id(), '_price_6_10', true); ?></div>
                    <div class="price-10-plus">$<?php echo get_post_meta($product->get_id(), '_price_10_plus', true); ?></div>
                    <div class="stock"><?php echo $product->get_stock_status(); ?></div>
                    <div class="buy">
                        <input type="number" class="quantity" min="1">
                        <button class="buy-button">Buy</button>
                    </div>
                </div>
                <div class="product-details">
                    <div class="specifications">
                        <table>
                            <tr>
                                <td>Center Wavelength</td>
                                <td><?php echo get_post_meta($product->get_id(), '_center_wavelength', true); ?></td>
                            </tr>
                            <tr>
                                <td>Bandwidth</td>
                                <td><?php echo get_post_meta($product->get_id(), '_bandwidth', true); ?></td>
                            </tr>
                            <!-- Add other specification rows -->
                        </table>
                    </div>
                    <div class="pricing">
                        <h4>Quantity Discounts</h4>
                        <table>
                            <tr>
                                <td>1 - 5 pcs.</td>
                                <td>$<?php echo get_post_meta($product->get_id(), '_price_1_5', true); ?></td>
                            </tr>
                            <!-- Add other pricing rows -->
                        </table>
                    </div>
                </div>
            </div>
        <?php
            endwhile;
        endif;
        wp_reset_postdata();
        ?>
    </div>
    
    <?php
    get_footer();
    ?>
    

Step 3: Adding the Accordion PHP Code

The PHP code in the template file above performs the following:

  • Header Row: Displays the table headers for product information.
  • Product Query: Retrieves all products from WooCommerce.
  • Product Rows: For each product, displays a summary row with key details and an expandable section with specifications and pricing tiers.
  • Accordion Functionality: Uses CSS and JavaScript to handle the expand/collapse behavior.

Ensure that you have populated the custom fields for your products as outlined in Step 1.


Step 4: Creating a Custom Page Template

To utilize the custom template, you need to create a new page in WordPress and assign the custom template to it.

  1. Create the Page Template File:

    • If you followed Step 2, you already have product-accordion-template.php. If not, ensure it’s created with the appropriate PHP code.
  2. Create a New Page in WordPress:

    • Navigate to Pages > Add New in your WordPress dashboard.
    • Title the page, e.g., Product Accordion.
  3. Assign the Custom Template:

    • In the Page Attributes section on the right sidebar, locate the Template dropdown.
    • Select Product Accordion Template.
    • Publish the page.

Note: If you don’t see the Template option, ensure your theme supports custom page templates and that you’ve correctly added the template header in product-accordion-template.php.


Step 5: Modifying functions.php for Query Variables

To filter products by subcategories via URL parameters, you need to add a function to handle query variables.

  1. Access functions.php:

    • Navigate to wp-content/themes/your-active-theme/ and open functions.php.
  2. Add the Following Code:

    // Allow 'product_cat' as a query variable
    function add_query_vars_filter($vars) {
        $vars[] = "product_cat";
        return $vars;
    }
    add_filter('query_vars', 'add_query_vars_filter');
    
  3. Save the File:

    • Save and upload the modified functions.php.

Caution: Editing functions.php can break your site if done incorrectly. Ensure you have backups and consider using a child theme.


Step 6: Adding CSS for Styling

To style the accordion and ensure it matches your theme’s design, add the following CSS to your theme’s stylesheet (style.css).

  1. Access style.css:

    • Navigate to wp-content/themes/your-active-theme/ and open style.css.
  2. Add the Following CSS:

    .product-table-accordion {
        width: 100%;
        border: 1px solid #ddd;
        margin: 20px 0;
    }
    
    .header-row, .product-summary {
        display: grid;
        grid-template-columns: auto 2fr 1fr 1fr 1fr 1fr auto;
        padding: 10px;
        align-items: center;
    }
    
    .header-row {
        background-color: #4C6B22;
        color: white;
    }
    
    .product-summary {
        background-color: #f5f5f5;
        cursor: pointer;
        border-bottom: 1px solid #ddd;
    }
    
    .product-details {
        display: none;
        grid-template-columns: 1fr 1fr;
        padding: 20px;
        background-color: #fff;
        border-bottom: 1px solid #ddd;
    }
    
    .product-row.active .product-details {
        display: grid;
    }
    
    .expand-button {
        transition: transform 0.3s;
        font-size: 18px;
    }
    
    .product-row.active .expand-button {
        transform: rotate(180deg);
    }
    
    .specifications table,
    .pricing table {
        width: 100%;
        border-collapse: collapse;
    }
    
    .specifications td,
    .pricing td {
        padding: 8px;
        border-bottom: 1px solid #eee;
    }
    
    .buy-button {
        background-color: #4C6B22;
        color: white;
        border: none;
        padding: 5px 15px;
        cursor: pointer;
        transition: background-color 0.3s;
    }
    
    .buy-button:hover {
        background-color: #3a5218;
    }
    
    .quantity {
        width: 60px;
        padding: 5px;
        margin-right: 10px;
    }
    
    /* Responsive Design */
    @media (max-width: 768px) {
        .header-row, .product-summary {
            grid-template-columns: repeat(4, 1fr);
        }
    
        .price-1-5, .price-6-10, .price-10-plus, .stock, .buy {
            display: none;
        }
    
        .product-details {
            grid-template-columns: 1fr;
        }
    }
    
  3. Save the File:

    • Save and upload the modified style.css.

Customization: Adjust colors, padding, fonts, and other styles as needed to match your theme’s aesthetics.


Step 7: Adding JavaScript for Accordion Functionality

The accordion’s expand/collapse behavior is controlled via JavaScript. We’ll use jQuery for this purpose.

  1. Enqueue jQuery:

    • Ensure that jQuery is enqueued in your theme. Most WordPress themes already include jQuery. If not, add the following to your functions.php:
    function enqueue_custom_scripts() {
        wp_enqueue_script('jquery');
    }
    add_action('wp_enqueue_scripts', 'enqueue_custom_scripts');
    
  2. Add the Accordion Script:

    • You can add the JavaScript directly in the template file or enqueue it as a separate file. For simplicity, we’ll add it directly.
  3. Insert the Following Script Before </body> in product-accordion-template.php:

    <script>
    jQuery(document).ready(function($) {
        $('.product-summary').click(function() {
            const productRow = $(this).closest('.product-row');
            
            // Close other open rows
            $('.product-row').not(productRow).removeClass('active');
            $('.product-details').not(productRow.find('.product-details')).slideUp();
            
            // Toggle the clicked row
            productRow.toggleClass('active');
            productRow.find('.product-details').slideToggle();
        });
    });
    </script>
    

    Alternative: For better practices, consider creating a separate JavaScript file (e.g., accordion.js) and enqueueing it in functions.php.

  4. Save the Template File:

    • Save and upload product-accordion-template.php with the embedded script.

Note: Ensure that jQuery is loaded before this script. WordPress typically loads jQuery in the header or footer, depending on your theme.


Step 8: Creating and Configuring the Page in WordPress

Now, we’ll set up the page that uses the custom template.

  1. Create a New Page:

    • Navigate to Pages > Add New.
    • Title the page, e.g., Product Accordion.
  2. Assign the Custom Template:

    • In the Page Attributes section, select Product Accordion Template from the Template dropdown.
  3. Publish the Page:

    • Click Publish to make the page live.
  4. View the Page:

    • Visit the newly created page (e.g., yoursite.com/product-accordion) to see the product accordion in action.

Step 9: Linking to Specific Subcategories

To display products from specific subcategories, modify the template to filter products based on the product_cat query parameter.

Updating the Template File

  1. Edit product-accordion-template.php:

    • Replace the product query section with a dynamic query that filters by subcategory if provided.
    <?php
    /*
    Template Name: Product Accordion Template
    */
    
    get_header();
    
    // Get the current category/subcategory from URL parameter
    $current_category = get_query_var('product_cat');
    
    // If no category is specified, you might want to show a list of categories
    if (!$current_category) {
        $product_categories = get_terms(['taxonomy' => 'product_cat', 'hide_empty' => true]);
        echo '<div class="product-categories">';
        foreach ($product_categories as $category) {
            echo '<a href="' . get_permalink() . '?product_cat=' . $category->slug . '">' . $category->name . '</a><br>';
        }
        echo '</div>';
    } else {
        // Get subcategory term
        $term = get_term_by('slug', $current_category, 'product_cat');
        
        // Query products from this subcategory
        $args = array(
            'post_type' => 'product',
            'posts_per_page' => -1,
            'tax_query' => array(
                array(
                    'taxonomy' => 'product_cat',
                    'field' => 'slug',
                    'terms' => $current_category
                )
            )
        );
        
        $products = new WP_Query($args);
        ?>
        
        <div class="product-table-accordion">
            <div class="header-row">
                <div class="part-no">PART NO.</div>
                <div class="description">DESCRIPTION</div>
                <div class="price-1-5">1 - 5 pcs.</div>
                <div class="price-6-10">6 - 10 pcs.</div>
                <div class="price-10-plus">> 10 pcs.</div>
                <div class="stock">Stock Status</div>
                <div class="buy">Buy</div>
            </div>
    
            <?php
            if ($products->have_posts()) :
                while ($products->have_posts()) : $products->the_post();
                    global $product;
                    ?>
                    <div class="product-row">
                        <div class="product-summary">
                            <div class="expand-button">▼</div>
                            <div class="part-no"><?php echo $product->get_sku(); ?></div>
                            <div class="description"><?php echo $product->get_name(); ?></div>
                            <div class="price-1-5">$<?php echo get_post_meta($product->get_id(), '_price_1_5', true); ?></div>
                            <div class="price-6-10">$<?php echo get_post_meta($product->get_id(), '_price_6_10', true); ?></div>
                            <div class="price-10-plus">$<?php echo get_post_meta($product->get_id(), '_price_10_plus', true); ?></div>
                            <div class="stock"><?php echo $product->get_stock_status(); ?></div>
                            <div class="buy">
                                <input type="number" class="quantity" min="1">
                                <button class="buy-button">Buy</button>
                            </div>
                        </div>
                        <div class="product-details">
                            <div class="specifications">
                                <table>
                                    <tr>
                                        <td>Center Wavelength</td>
                                        <td><?php echo get_post_meta($product->get_id(), '_center_wavelength', true); ?></td>
                                    </tr>
                                    <tr>
                                        <td>Bandwidth</td>
                                        <td><?php echo get_post_meta($product->get_id(), '_bandwidth', true); ?></td>
                                    </tr>
                                    <!-- Add other specification rows -->
                                </table>
                            </div>
                            <div class="pricing">
                                <h4>Quantity Discounts</h4>
                                <table>
                                    <tr>
                                        <td>1 - 5 pcs.</td>
                                        <td>$<?php echo get_post_meta($product->get_id(), '_price_1_5', true); ?></td>
                                    </tr>
                                    <!-- Add other pricing rows -->
                                </table>
                            </div>
                        </div>
                    </div>
                    <?php
                endwhile;
            else:
                echo '<p>No products found in this category.</p>';
            endif;
            wp_reset_postdata();
            ?>
        </div>
        <?php
    }
    
    get_footer();
    ?>
    
  2. Save the Template File:

    • Save and upload product-accordion-template.php.

To link to specific subcategories, create links with the product_cat query parameter.

<a href="/product-accordion?product_cat=bandpass-filters">Bandpass Filters</a>
<a href="/product-accordion?product_cat=optical-filters">Optical Filters</a>
<!-- Add more category links as needed -->

Dynamic Category List: Alternatively, you can dynamically generate category links within the template when no product_cat is specified, as shown in the updated template above.


Optional Steps

Implementing the “Buy” Button Functionality

The “Buy” button in the accordion allows customers to add products to their cart directly from the accordion. To make this functional, integrate WooCommerce’s add-to-cart functionality.

  1. Modify the Buy Button:

    • Replace the existing button with a form that submits the product ID and quantity to WooCommerce.
    <div class="buy">
        <form class="cart" action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" method="post" enctype='multipart/form-data'>
            <input type="number" name="quantity" class="quantity" value="1" min="1">
            <button type="submit" class="buy-button"><?php echo esc_html( $product->add_to_cart_text() ); ?></button>
        </form>
    </div>
    
  2. Ensure WooCommerce Scripts Are Loaded:

    • WooCommerce handles cart operations via AJAX and scripts. Ensure your theme properly enqueues WooCommerce scripts.
  3. Style the Form:

    • Adjust the CSS as needed to style the form elements.

Advanced: For enhanced functionality, consider integrating AJAX add-to-cart to allow adding products without page reloads.

Adding Category Navigation

Improve user experience by adding a navigation section for product categories.

  1. Display Categories When No product_cat is Specified:

    • In the updated template (product-accordion-template.php), the code already includes a section to display categories if no product_cat is present.
  2. Enhance Category Listing:

    • Style the category links to resemble buttons or menu items for better usability.
    <div class="product-categories">
        <?php
        foreach ($product_categories as $category) {
            echo '<a href="' . get_permalink() . '?product_cat=' . $category->slug . '" class="category-link">' . $category->name . '</a><br>';
        }
        ?>
    </div>
    
  3. Add CSS for Category Links:

    .product-categories {
        margin: 20px 0;
    }
    
    .category-link {
        display: inline-block;
        margin: 5px;
        padding: 10px 20px;
        background-color: #4C6B22;
        color: white;
        text-decoration: none;
        border-radius: 4px;
        transition: background-color 0.3s;
    }
    
    .category-link:hover {
        background-color: #3a5218;
    }
    

Conclusion

By following this tutorial, you’ve successfully created a customized WooCommerce product accordion that enhances your store’s user experience. Customers can now view product details and pricing tiers in an organized, expandable format, making it easier for them to make informed purchasing decisions.

Recap of Steps:

  1. Set Up Custom Fields: Added necessary custom fields for product specifications and pricing tiers using the ACF plugin.
  2. Created a Custom Template: Built a PHP template to structure the accordion layout.
  3. Configured the Page Template: Assigned the custom template to a new WordPress page.
  4. Handled Query Variables: Modified functions.php to allow filtering by product categories.
  5. Styled the Accordion: Applied CSS to ensure the accordion is visually appealing and responsive.
  6. Implemented Accordion Behavior: Added JavaScript for interactive expand/collapse functionality.
  7. Linked to Subcategories: Enabled filtering products by specific subcategories via URL parameters.
  8. Enhanced Buy Functionality (Optional): Integrated WooCommerce’s add-to-cart feature within the accordion.

Next Steps:

  • Optimize for Performance: Ensure that loading all products at once doesn’t affect page performance. Consider implementing pagination or lazy loading if you have a large catalog.
  • Enhance Accessibility: Ensure that the accordion is accessible to all users, including those using screen readers.
  • Test Across Devices: Verify that the accordion behaves correctly on various devices and browsers.
  • Further Customizations: Add more product details, integrate with WooCommerce’s dynamic pricing, or incorporate user reviews within the accordion.

Feel free to customize and expand upon this foundation to best suit your WooCommerce store’s needs. Happy coding!

Keep your curiosity going.Explore more WordPress →
287 TUTORIALS · 22 TOPICSREADY