WOOT - WooCommerce Active Products Tables

Show variations as separate rows in a WooCommerce product table

To show variations as separate rows in a WooCommerce product table, you first need to know what the table lists by default: one row per product. A variable product gets a single row, and its variations open in a popup from the select [N] button. Depending on what you need, there are three ways around it: a table of all variations of one product, a table limited to one category with the variations a click away, or a dedicated table that lists the variations of many products as rows, set up with a small piece of code. Each one is below, with its limits.

Why a WooCommerce product table shows one row per variable product

In WooCommerce a variable product and its variations are different kinds of posts. The product is a product, and each variation (Red / L, Blue / M) is a separate product_variation post that belongs to it. A variation has its own price, SKU, stock and image, but no categories, tags or attribute terms of its own: those stay on the parent product, and the variation only stores which attribute values it stands for.

The [woot] table queries products, the same way the shop page does. That is why it shows the parent once, why its Price cell shows a price range, and why the Cart column shows select [N] instead of an Add to cart button. The button, and the Var.[N] button of the Variations column, open a popup that lists the variations as rows, each with a quantity field and its own Add to cart button. How to change the columns, sorting and paging of that popup is covered in customize the variations popup.

Plugins that show single variations in the shop do it by changing WooCommerce's shop query. The table runs its own query, so those plugins do not add variations to it.

All variations of one product as table rows: [woot_variations]

The [woot_variations] shortcode prints the variations of one variable product as a full table, directly on the page instead of in a popup:

[woot_variations id=49]

id is the ID of the variable product, not of a table. Each variation is a row with its title (the product name plus its attribute values, such as T-shirt - Red, L), price, stock and a cart cell with a quantity field, a checkbox and an Add to cart button. The checkboxes work together with the add selected link in the cart column header, so a shopper can tick several variations, set quantities and add them to the cart in one click. That makes the shortcode a good order form for products with many sizes or colours.

  • Columns. Without the columns attribute the table uses WOOT → Settings → Variations columns, the same list as the popup. Set them for one table only with the attribute: [woot_variations id=49 columns='thumbnail,post_title,sku,price,stock_quantity,add_to_cart'].
  • Rows per page. All variations are loaded at once and paged in the browser, 10 per page by default. per_page=-1 shows them all, per_page_position='b' moves the pagination below the table (t, b, tb or none).
  • Sorting. Rows are sorted by title, A to Z. orderby and order change it, for example orderby='id' order='asc' for the order in which the variations were created. The rows are sorted in the browser by the contents of that column, so the id column must be among the columns for this to work.
  • On the single product page. Leave out id, and the shortcode takes the product of the current page. It works in a product page template (Elementor, a block theme template) or added by a hook, as shown in how to insert shortcodes into the single product page. On a page that is not a product page, without id it prints WOOT: Set product id please in the shortcode attribute!.

Only global attributes (created under Products → Attributes) are added to the variation title and can be shown as columns, such as pa_size. Values of custom attributes typed directly into a product do not appear.

A table for one category, variations one click away

Often the request behind "show all variations" is narrower: one table per product line, where each variable product is easy to buy. Create a table, open its Predefinition tab and fill in Included taxonomy with the category's term ID, for example product_cat:25 (several categories: product_cat:25,26). The table then shows only products from that category, and the select [N] buttons open the variations of each one. The FAQ on a different table for each category shows the same setup across several pages.

For a category with only a few variable products, the most direct layout is a page with one [woot_variations] per product, each under its own heading.

Variations of many products as separate rows

The table has no switch that turns every product into its variation rows. It can be done with the woot_wp_query_args hook, which receives the query of a table before it runs. The [woot_variations] shortcode works the same way inside: it asks for posts of the type product_variation. Create a separate table for this, set its columns (Title, SKU, Price, stock, Cart and the attribute columns you need), and add:

/*
 * Products table #25 lists variations instead of products.
 * Child theme functions.php or a code snippets plugin.
 */
add_filter('woot_wp_query_args', function ($args, $table_id) {
    if ((int) $table_id !== 25) { // the ID of your variations table
        return $args;
    }

    // Variations have no categories: find the variable parent products first
    $tax_query = [
        [
            'taxonomy' => 'product_type',
            'field'    => 'slug',
            'terms'    => ['variable'],
        ],
        [
            'taxonomy' => 'product_cat',
            'field'    => 'slug',
            'terms'    => ['t-shirts'], // category slugs; remove this block for all categories
        ],
    ];

    $parent_ids = get_posts([
        'post_type'      => 'product',
        'post_status'    => 'publish',
        'posts_per_page' => -1,
        'fields'         => 'ids',
        'tax_query'      => $tax_query,
    ]);

    $args['post_type'] = 'product_variation';
    $args['post_parent__in'] = $parent_ids ? $parent_ids : [0];

    return $args;
}, 10, 2);

Insert the table with [woot id=25]. Each published variation of the selected products now has its own row, with its own price, stock and Add to cart button. Disabled variations are saved as private posts, so they stay out as long as the table's post status option keeps its default, publish. Know the trade-offs before you build a shop page on it:

  • Category and attribute rules do not apply to variation rows. Variations carry no terms, so Included taxonomy in Predefinition, and category or attribute elements in the table's filter, find nothing in this table. Choose the categories in the code, as above. Price, SKU, stock and title search keep working, because variations have those fields.
  • The title is plain text. A variation has no page of its own, so its Title cell is not a link. Add the Thumbnail column if shoppers need to see the item; it shows the variation's own image.
  • "Any" variations cannot be bought from a row. A variation set to Any Size needs the shopper to pick a size, and a row has no field for it, so WooCommerce refuses to add it to the cart. Give such variations concrete values.
  • Row count. A hundred products with twenty variations each make a table of two thousand rows. Keep pagination on and the number of rows per page moderate.

Which approach to choose

You needUse
All variations of one product, on its product page or on any page[woot_variations id=...]
Products of one category, variations on clickA table with Included taxonomy in Predefinition
An order form with every variation of a product line as a rowA dedicated table and the woot_wp_query_args snippet
Different columns or sorting in the popupVariations columns in Settings and the woot_vurgc_shortcode_data hook

If the variations do not show

  • [woot_variations] shows No Data!: the ID belongs to a simple product, or all its variations are disabled or unpublished.
  • The shortcode prints the "set product id" notice: add id, or place it where a product is the current page.
  • The variations table built with the snippet is empty: check the table ID in the code, the category slugs, and that the table has no Included taxonomy rule in Predefinition.
  • A row has no Add to cart button: the variation has no price or is out of stock, and WooCommerce does not consider it purchasable.

For layouts not covered here, ask on the WOOT support forum.