WooCommerce TM Extra Product Options #3
Need all product options in one row? Not one row per option?
Previous code created multiple rows. This one is different.
All options stay in the same product row. Each option type becomes a comma-separated list.
What this code does
Takes multiple TM options. Combines them into single cells.
Example: One product with “Size: Large”, “Color: Blue”, “Gift Wrap: Yes”
Becomes one row with “Size: Large, Color: Blue, Gift Wrap: Yes” in the TM value column.
The complete code
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
// add all options to SINGLE product row class WOE_add_TM_cols{ var $tm_cols = array( 'pos','name','value','price','quantity', 'name_value'); function __construct() { add_filter('woe_get_order_product_fields',array($this,'add_product_fields') ); add_filter('woe_fetch_order_products', array($this,'fill_tm_cols') ,10, 5); } function add_product_fields($fields) { foreach($this->tm_cols as $tm_col) { $fields['tm_field_'.$tm_col] = array('label'=>'TM '.$tm_col,'colname'=>'TM '.$tm_col,'checked'=>1); } return $fields; } function fill_tm_cols($products, $order, $labels, $format,$static_vals) { $new_products = array(); foreach( $products as $item_id=>$product) { $item_meta = get_metadata( 'order_item', $item_id ); $pos = 1; if( isset($item_meta["_tmcartepo_data"]) AND is_array($tmfields = maybe_unserialize($item_meta["_tmcartepo_data"][0])) ) { $new_product = $product; foreach($tmfields as $tm_field) { $tm_field['pos']= $pos++;//set fake field $tm_field['name_value'] = $tm_field['name'] . ':' .$tm_field['value']; // fill TM columns foreach($this->tm_cols as $tm_col) { if( !isset($new_product['tm_field_'.$tm_col])) continue; if( !empty($new_product['tm_field_'.$tm_col])) $new_product['tm_field_'.$tm_col] .= ", " .$tm_field[$tm_col]; else $new_product['tm_field_'.$tm_col] = $tm_field[$tm_col]; } } //don't add each option as new product! $new_products[] = $new_product; $pos++; } if( isset($item_meta["_tmcartfee_data"]) AND is_array($tmfields = maybe_unserialize($item_meta["_tmcartfee_data"][0])) ) { $new_product = $product; foreach($tmfields[0] as $tm_field) { $tm_field['pos']= $pos++;//set fake field $tm_field['name_value'] = $tm_field['name'] . ':' .$tm_field['value']; // fill TM columns foreach($this->tm_cols as $tm_col) { if( !isset($new_product['tm_field_'.$tm_col])) continue; if( !empty($new_product['tm_field_'.$tm_col])) $new_product['tm_field_'.$tm_col] .= ", " .$tm_field[$tm_col]; else $new_product['tm_field_'.$tm_col] = $tm_field[$tm_col]; } } //don't add each option as new product! $new_products[] = $new_product; $pos++; } if($pos==1) //nothing added - just copy product as is $new_products[] = $product; } return $new_products; } } new WOE_add_TM_cols(); |
Setup steps
- Copy the entire code block
- Paste into your theme’s
functions.php - Go to Advanced Order Export for WooCommerce
- Create or edit an export profile
- Open Setup Fields → Products
- You’ll see TM columns. Check the ones you need
- Save and test on an order with TM options
What your export looks like
One product. One row. Combined options.
| Product | TM name | TM value | TM price | TM quantity |
|---|---|---|---|---|
| T-Shirt | Size, Color, Gift Wrap | Large, Blue, Yes | 0, 0, 5 | 1, 1, 1 |
Or with name_value column:
| TM name_value |
|---|
| Size:Large, Color:Blue, Gift Wrap:Yes |
Real example from the image
In the screenshot, a product has:
- Front Label: “Happy Birthday!”
- Gender: “Male”
- Age: “12”
Output with this code (single row):
| TM name | TM value |
|---|---|
| Front Label, Gender, Age | Happy Birthday!, Male, 12 |
TM name_value column:
| TM name_value |
|---|
| Front Label:Happy Birthday!, Gender:Male, Age:12 |
Which TM columns to use
- TM name – Option labels (Front Label, Gender, Age)
- TM value – Customer selections (Happy Birthday!, Male, 12)
- TM price – Extra costs (0.00, 0.00, 0.00)
- TM quantity – How many of each option
- TM name_value – Combined label:value pairs
- TM pos – Order of options (1, 2, 3)
When to use this version
You want compact exports. One row per product. No matter how many options.
Your spreadsheet needs to be short. Easy to scroll through.
You don’t need to analyze each option separately. Just need to see all options together.
You’re sending data to a system that expects one row per product.
When to use the other version
Use the “one row per option” version when:
- You need option-level totals
- You’re calculating costs per option
- Your warehouse picks each option separately
Common mistake
Mixing this code with the previous “one row per option” code. They do opposite things.
Pick one version. Stick with it.
Pro tip
Change the separator. Replace ", " with " | " or " / " or "\n" (newline).
|
1 |
$new_product['tm_field_' . $tm_col] .= " | " . $tm_field[$tm_col]; |
Need only the values? Uncheck “TM name” column. Keep only “TM value”.
Real talk
Three ways to export TM Extra Product Options:
- One row per option – Maximum detail. More rows.
- One column per option – Wide spreadsheets. Compact.
- One row, combined cells – This version. Balanced.
Choose based on what your team needs. Test all three. Pick the winner.