WOOT - WooCommerce Active Products Tables

ACF fields in a WooCommerce product table: columns, links and filters

To show ACF fields in a WooCommerce product table, you first need to know where the value lives. Product attributes, categories and brands are taxonomies, and the table offers them as columns on its own. ACF fields, and the fields most other plugins add to products, are post meta: the table shows them only after you tell it the exact meta key. Below is how both cases work, which ACF field types display correctly without code, and how to turn URLs, files and IDs into links or images.

Add ACF fields to a WooCommerce product table in the Meta tab

ACF saves each value in the standard wp_postmeta table under the field name. The table can read any such value, but it cannot guess which of the hundreds of meta keys in a shop matter to you, so fields from ACF, Pods, pricing plugins and other sources never appear automatically. You register them per table:

  1. On the WOOT admin page, click the gear icon (table options) of your table and open the Meta tab.
  2. Click Add meta field. A row appears with the placeholder key 0 write key here.
  3. Fill in Title, put the exact field name into Meta key and choose the Type: text, number or calendar. Do not leave it on not defined: the type decides how the value is sorted and filtered.
  4. Go to the Columns tab, add a column and select the new field (it is listed under its Title). Switch it Active.
  5. To filter by it, drag it into the filter form in the Filter tab.
TypeCellSortingFilter element
textThe value as storedAlphabeticalText input, matches any part of the value
numberThe value as storedNumericRange slider; min and max are read from the database, whole numbers
calendarA date in the site date formatNumeric: exact for timestamps, by year only for ACF date-time valuesFrom and To calendars; set Data type to datetime for ACF or unixtimestamp for timestamps

Three details save time. Use the field name (spec_sheet), not the field key (field_5f2a…) and not the hidden twin that starts with an underscore (_spec_sheet): ACF stores the field key there, so a cell showing field_… means the wrong key. Sorting by a meta key hides products that have no value for it, which is how WordPress queries work; this FAQ shows how to keep them. And meta fields belong to one table; to add a key to every table at once, see adding a meta key globally.

Which ACF field types work without code

What the cell shows depends on what ACF writes to the database, not on the Return Format you chose in ACF (that setting affects only get_field() in templates).

ACF field typeStored asIn the table
Text, Text Area, Number, Range, Email, Color PickerPlain valueWorks with text or number
Select (single), Radio Button, Button GroupThe choice valueWorks; shows the value, not the label
True / False1 or 0Works, but prints the digit
Date Time Picker2026-12-31 18:00:00Works with calendar and data type datetime
Date Picker20261231Not the format the calendar filter is built for; prefer Date Time Picker, or add it as text and format it with code
URLThe address as textShows the address, not a link; needs code
Image, File, Post Object, Page LinkA post or attachment IDShows a number; needs code
Checkbox, multiple Select, Gallery, Relationship, LinkA serialized arrayNot readable as is; needs code
GroupOne meta key per sub fieldAdd a sub field by its full key, groupname_subfieldname
Repeater, Flexible ContentNumbered keys, name_0_subNot one key; use a custom column

Links, PDF manuals, images: format the cell with woot_meta_data_cell

A typical first attempt is to type <a href="…">Spec PDF</a> into a product attribute. It cannot work: an attribute value is a term name, WordPress strips HTML from term names, and the table already wraps each term in a link to its archive. Store only the URL in a meta field instead (an ACF URL or File field, or a plain custom field with no spaces in its key), add it in the Meta tab with type text, and build the link in the woot_meta_data_cell filter. It receives the raw value, the Meta tab row, the product ID and the table ID, and whatever it returns goes into the cell as HTML:

/*
 * Products tables: display meta fields added in the Meta tab.
 * Child theme functions.php or a code snippets plugin.
 * Replace the keys in "case" with your own ACF field names.
 */
add_filter('woot_meta_data_cell', function ($value, $meta_data, $post_id, $table_id) {

    switch ($meta_data['meta_key']) {

        case 'spec_sheet': // ACF URL field: the value is a web address
            $value = $value ? '<a href="' . esc_url($value) . '" target="_blank" rel="noopener">Spec sheet (PDF)</a>' : '';
            break;

        case 'manual': // ACF File field: the database holds the attachment ID
            $url = $value ? wp_get_attachment_url((int) $value) : '';
            $value = $url ? '<a href="' . esc_url($url) . '" target="_blank" rel="noopener">Manual</a>' : '';
            break;

        case 'energy_label': // ACF Image field: attachment ID
            $value = $value ? wp_get_attachment_image((int) $value, 'thumbnail') : '';
            break;

        case 'colors': // ACF Checkbox or multiple Select: an array of values
            $value = is_array($value) ? implode(', ', $value) : $value;
            break;

        case 'release_date': // ACF Date Picker: stored as Ymd
            $date = $value ? DateTime::createFromFormat('!Ymd', $value) : false;
            $value = $date ? date_i18n(get_option('date_format'), $date->getTimestamp()) : '';
            break;
    }

    return $value;
}, 10, 4);

The empty checks matter: without them every row shows a link, including products that have no file. To limit a rule to one table, add a condition such as (int) $table_id === 21. Use this filter with text and number fields; a calendar field converts the returned value to a date afterwards, so HTML returned for it would be lost. Many values at once are easiest to fill with any bulk editor that can edit custom fields.

Values that are not one meta key: a custom column

When the cell needs data from several places, or from something that is not a single meta key (a repeater, a custom attribute typed in the product, a calculation), register your own column with woot_profile_extend. The callback in action receives the product ID for every row and can use any WordPress, WooCommerce or ACF function, including get_field():

/*
 * Products tables: a "Material" column built from a product attribute.
 * Works for global attributes and for custom attributes typed in the product.
 * Child theme functions.php or a code snippets plugin.
 */
add_filter('woot_profile_extend', function ($profile, $action) {

    if ('woot_woocommerce_tables' !== $action) {
        return $profile;
    }

    $profile['material_text'] = [
        'title'  => 'Material',
        'order'  => false, // not sortable
        'action' => function ($post_id) {
            $product = wc_get_product($post_id);
            return $product ? $product->get_attribute('material') : '';
        },
    ];

    return $profile;
}, 10, 2);

The new field appears in the Field list of the Columns tab under its title. A column like this is display-only: sorting and filtering need query logic, which the Meta tab adds for you and which you would otherwise write yourself.

Attributes, categories and brands: ready-made columns

Every taxonomy registered for products appears in the Field list of the Columns tab: categories, tags, each global attribute (WooCommerce prints them with a "Product" prefix, for example Product Color) and custom taxonomies such as brands. Product type, visibility and shipping class are left out. Add a column with Prepend column or Append column, choose the taxonomy in Field and switch the column Active.

  • Terms are printed as links to their archive pages, so categories as links need no code. To print plain text, open the column's options and switch on Display as text.
  • The same taxonomies are available in the Filter tab as drop-downs or multi-selects.
  • Taxonomy columns cannot be sorted by clicking the header. A product can have many terms, so there is no single value per row to sort by.
  • Custom attributes typed directly in a product (not created under Products > Attributes) are not taxonomies. WooCommerce keeps them inside one serialized meta field, so they do not appear in the list. Use a global attribute, or a custom column as shown above.

Custom post types such as portfolio items

WOOT builds tables of WooCommerce products only. For a portfolio, events or any other post type, use its sister plugin TableOn (posts-table.com), which is built on the same engine. ACF works there the same way: a Meta tab for simple fields, and hooks of its own for the field types listed above as needing code.

If the column stays empty

  • Compare the meta key letter by letter with the ACF Field Name; keys are case-sensitive and must not contain spaces.
  • Open one product that has a value and check that it is saved there, not only shown on the product page by a template.
  • Make sure the Meta tab row has a type and the column is Active in the same table whose shortcode is on the page.
  • A cell with a number instead of an image or a title means an ID-storing field; a cell with field_… means the underscore key.
  • Clear any page cache after changing the snippet, and check the PHP error log if the whole table stops loading after adding it.

If a field still does not show, open a topic on the WOOT support forum with the ACF field type, the meta key and the table shortcode.