Skip to content

Commit f0a9e6b

Browse files
authored
Merge pull request #349 from Weaverse/dev
Refine variant media grouping matching logic
2 parents e20a3f8 + 01dbb1f commit f0a9e6b

4 files changed

Lines changed: 20 additions & 18 deletions

File tree

.guides/cookbooks/variant-media-grouping.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ Groups product media by variant option (e.g., Color). When a visitor selects "Bl
66

77
1. Get the selected option value from `selectedVariant.selectedOptions` (e.g., "Black")
88
2. Get all known option values from `product.options` for the grouping option (e.g., ["Black", "Cream"])
9-
3. For each media item, extract the option value from the image filename URL
10-
4. **Filename matching** supports:
9+
3. Sort option values by length (descending) so longer values match first (e.g., "Gray Eucalyptus" before "Gray")
10+
4. For each media item, extract the option value from the image filename URL
11+
5. **Filename matching** supports:
1112
- Single-word values: `_black`, `-black`, `black_`, `black-`, `black` (end)
12-
- Multi-word values: space is replaced with `_`, `-`, or removed
13-
- "Slate Brown" matches `slate-brown`, `slate_brown`, `slatebrown`
14-
5. Group media into a `Map<string, MediaFragment[]>` keyed by option value. Media not matching any option goes to `ungrouped[]`
15-
6. Return `{ media: [...matched, ...ungrouped], isGrouped: true }`. If no matches, return `{ media: allMedia, isGrouped: false }` as fallback
13+
- Multi-word values: space is replaced with `_` or `-`
14+
- "Slate Brown" matches `slate-brown`, `slate_brown`
15+
6. Group media into a `Map<string, MediaFragment[]>` keyed by option value. Media not matching any option goes to `ungrouped[]`
16+
7. Return `{ media: [...matched, ...ungrouped], isGrouped: true }`. If no matches, return `{ media: allMedia, isGrouped: false }` as fallback
1617

1718
## Files
1819

.weaverse/specs/2026-03-03--variant-media-grouping/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
| **Status** | `completed` |
66
| **Owner** | @hta218 |
77
| **Created** | 2026-03-03 |
8-
| **Last Updated** | 2026-03-09 |
8+
| **Last Updated** | 2026-03-09 (refined matching logic) |
99

1010
## Original Prompt
1111

.weaverse/specs/2026-03-03--variant-media-grouping/plan.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -288,29 +288,28 @@ Same two settings as main-product:
288288

289289
## 7. Filename Matching Strategy
290290

291-
Media is grouped by extracting option values from image filenames using delimiter-based pattern matching (`_`, `-`). The matching checks for the option value at the start, middle, or end of the filename, bounded by delimiters.
291+
Media is grouped by extracting option values from image filenames using delimiter-based pattern matching (`_`, `-`). The matching checks for the option value at the start or end of the filename, bounded by delimiters.
292+
293+
**Priority Matching**: Option values are sorted by length (descending) so longer, more specific values match first. This prevents "Gray" from matching before "Gray Eucalyptus".
292294

293295
**Single-word option values** (e.g., "black"):
294296
```
295297
black_xxx.jpg (start + _)
296298
black-xxx.jpg (start + -)
297299
xxx_black.jpg (end + _)
298300
xxx-black.jpg (end + -)
299-
xxx_black_yyy.jpg (middle + _)
300-
xxx-black-yyy.jpg (middle + -)
301301
xxxblack.jpg (end, no delimiter)
302302
```
303303

304304
**Multi-word option values** (e.g., "Slate Brown") are matched against transformed versions:
305305
```
306306
slate-brown_xxx.jpg (space → dash)
307307
slate_brown_xxx.jpg (space → underscore)
308-
slatebrown_xxx.jpg (space removed)
309308
xxx_slate-brown.jpg (end + dash)
310309
xxx_slate_brown.jpg (end + underscore)
311310
```
312311

313-
This handles common filename conventions while avoiding false positives.
312+
Note: Middle-of-filename matching and space-removed transformations (e.g., "slatebrown") were removed to reduce false positives.
314313

315314
---
316315

app/components/product/product-media/variant-media-group.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ interface VariantGroupedMediaResult {
2323
* e.g., filename "24b_xxx_black.jpg" with options ["Black", "Cream"] → "black"
2424
*
2525
* Handles multi-word option values by checking transformed versions:
26-
* - "Slate Brown" matches "slate-brown", "slate_brown", "slatebrown"
26+
* - "Slate Brown" matches "slate-brown", "slate_brown"
2727
*/
2828
function extractOptionValueFromUrl(
2929
url: string,
@@ -36,16 +36,20 @@ function extractOptionValueFromUrl(
3636
const nameWithoutExt = filename.replace(/\.[^.]+$/, "").toLowerCase();
3737

3838
// Check if any known option value appears in the filename
39-
for (let optionValue of knownOptionValues) {
39+
// Sort by length descending to match longer (more specific) values first
40+
// e.g., "Gray Eucalyptus" should match before "Gray"
41+
let sortedOptionValues = [...knownOptionValues].sort(
42+
(a, b) => b.length - a.length,
43+
);
44+
for (let optionValue of sortedOptionValues) {
4045
let optionLower = optionValue.toLowerCase();
4146

4247
// Generate transformed versions for multi-word option values
43-
// e.g., "Slate Brown" → "slate-brown", "slate_brown", "slatebrown"
48+
// e.g., "Slate Brown" → "slate-brown", "slate_brown"
4449
let transformations = [optionLower];
4550
if (optionLower.includes(" ")) {
4651
transformations.push(optionLower.replace(/\s+/g, "-")); // space → dash
4752
transformations.push(optionLower.replace(/\s+/g, "_")); // space → underscore
48-
transformations.push(optionLower.replace(/\s+/g, "")); // remove spaces
4953
}
5054

5155
// Check each transformation against the filename
@@ -55,8 +59,6 @@ function extractOptionValueFromUrl(
5559
nameWithoutExt.startsWith(`${transformed}-`) ||
5660
nameWithoutExt.endsWith(`_${transformed}`) ||
5761
nameWithoutExt.endsWith(`-${transformed}`) ||
58-
nameWithoutExt.includes(`_${transformed}_`) ||
59-
nameWithoutExt.includes(`-${transformed}-`) ||
6062
nameWithoutExt.endsWith(transformed)
6163
) {
6264
return optionLower;

0 commit comments

Comments
 (0)