# 🎨 Factorize Colorways

> One product, every color, every placement — the picture switches by itself.

> **Suite identity:** icon 🎨 · accent `#3d6fe5` · Selling tab · part of the [Factorize suite](../README-FACTORIZE.md)

## What it does

Apparel and print-on-demand stores sell a design in many garment colors and
print placements. WooCommerce can model that (variable products), but it
expects someone to attach an image to every variation by hand — hundreds of
clicks per product. Colorways resolves the image from a **file-name
template** instead:

```
{name}-{color}-{category}.svg                       default template, e.g. skyline-black-tee.svg
{name}-{color}-{category}-{location}.svg            optional placement mockup, e.g. skyline-black-tee-back.svg
{name}-{color}-{view}-{category}-{location}.svg     a richer grammar, e.g. asset-10-black-person-hoodie-large-front.svg
```

- `{name}` — the product's "Colorway image name" (defaults to its slug).
- `{color}` — the color term slug (`black`, `heather-gray`, `royal-blue`).
- `{category}` — the product's first category slug or its override (`tee`, `hoodie`, `cap`).
- `{location}` — a placement slug. Without `{location}` in the template a placement file is `<base>-<location>` and optional; with it in the template every file names a placement and the main image uses the product's default placement.
- `{view}` — an alternate rendering that is not something the customer buys (`product` = flat shot, `person` = worn). The product page shows a Product / On model toggle; cards, carts, and emails use the default view.

Files are found in the **media library by file name** (any folder) or in the
**library folder** `wp-content/uploads/colorways/` — any depth of sub-folders,
indexed once. A folder file is registered in the media library **lazily**, the
first time a cart, order, email, or the block cart needs an attachment id for
it, so a 3 GB library never has to be bulk-imported. The folder may be a
read-only mount.

### Storefront

| Where | What happens |
|---|---|
| Product page | Color dropdown becomes **swatches** (hex from the term's "Swatch color" or a built-in name map); Placement and Size dropdowns become **buttons**. Picking a color swaps the gallery image immediately; picking a placement moves a dashed **print-area marker** (per-category coordinates) or switches to the placement mockup when one exists. The WooCommerce selects stay in the DOM (hidden) as the source of truth, so prices, stock, and add-to-cart are untouched. |
| Shop / category / search cards | A **swatch strip** under the title: hover or tap switches the card image; the card link then opens the product with `?attribute_pa_color=<slug>` so that color is preselected. |
| Cart, checkout, orders, emails, Store API | Variations without their own image resolve to the colorway attachment (`woocommerce_product_variation_get_image_id`), and variable products without a featured image show their default color (`woocommerce_product_get_image_id`). |
| Variation form data | `woocommerce_available_variation` carries the resolved image, so WooCommerce's own JS shows it when all attributes are chosen. |

### Admin (Factorize → Colorways)

- **Settings** — template, folder, extensions, attribute slugs, card swatches,
  marker on/off, SVG uploads, nominal SVG size, placement labels, print-area
  JSON (category → placement → `[x, y, w, h]` in percent).
- **Colors** — a swatch color per `pa_color` term (also on the term's own edit
  screen and as a column in the term list) plus the editable name map.
- **Coverage** — every product × color with found / missing, placement counts,
  a copyable list of the exact missing file names, *Rescan folder*, and
  *Generate placeholder mockups* (flat garment drawings in the right color,
  optionally one per placement).
- **Examples** — creates the InstaAttire demo catalog: Color / Placement /
  Size attributes and terms, seven garment categories, twelve designs as
  variable products with every color × placement as a real variation (size
  "Any"), generated mockups for each following the template, featured images,
  and default attributes. Idempotent by SKU.
- **Product edit** — "Colorway image name", "Colorway image category",
  "Design label" fields and a side box that shows each color's resolved file.

### Importing a whole library

`wp colorways import` (or Colorways → Examples → *Import the catalog from the
library*) parses every file name with the template and creates one **variable
product per design × garment** with every color × placement as a real
variation (size as "Any" where the garment has sizes), the sub-folder two
levels up as a **collection category**, the garment as a second category, the
default color's mockup as the featured image, and default attributes set.
SKUs are `CW-<design>-<garment>`; re-running updates instead of duplicating and
keeps names and prices you changed. `wp colorways scan` shows what would be
created (designs, colors, placements, views, unparsed names) without writing.

### SVG

WordPress blocks SVG uploads by default. With `svg_uploads` on, administrators
and shop managers may upload `.svg`; every upload is parsed with DOMDocument
(`LIBXML_NONET`), DOCTYPE/entities rejected, non-SVG elements and
`foreignObject`/`script` removed, `on*` attributes stripped, `href`s limited to
`#fragment` (and `data:image/*` on `<image>`), and `@import`/`url(` in styles
removed. Files that cannot be parsed are refused. SVGs also get a nominal size
so media modals and WooCommerce galleries render them.

## Configuration

| key | default | effect |
|---|---|---|
| `folder` | `colorways` | library sub-folder under uploads |
| `template` | `{name}-{color}-{category}` | file-name template (no extension) |
| `extensions` | `svg, png, jpg, jpeg, webp` | tried in order |
| `color_attribute` / `location_attribute` / `size_attribute` | `color` / `location` / `size` | global attribute slugs (`pa_*`) |
| `views`, `default_view` | `product / person`, `product` | alternate renderings when the template has `{view}` |
| `default_location` | `front` | main-image placement when the template has `{location}` |
| `garments` | tee, hoodie, tank, … | words the importer accepts as `{category}` |
| `card_swatches`, `card_swatch_limit` | `true`, `6` | swatch strip on cards |
| `overlay`, `overlay_labels` | `true`, `true` | print-area marker |
| `svg_uploads` | `true` | sanitized SVG uploads for managers |
| `image_width`, `image_height` | `1200`, `1400` | nominal SVG size |
| `locations` | front, back, left-chest, right-chest, sleeve, side | placement labels |
| `areas` | see config.php | print areas per category |
| `colors` | ~60 apparel color names | slug → hex map |

Override via the `factorize-colorways_options` option or the
`factorize-colorways_config` filter.

## WP-CLI

```
wp colorways examples [--no-placements]   # create / refresh the example catalog
wp colorways scan                         # parse the library with the template: designs, colors, placements, views, unparsed
wp colorways import [--collection=<text>] [--limit=<n>] [--offset=<n>] [--dry-run]   # build the catalog from the library
wp colorways coverage                     # per-product found/missing + the missing file names
wp colorways generate [--placements]      # placeholder mockups for whatever is missing
wp colorways rescan [--index-only]        # re-index the folder (and register everything as media unless --index-only)
```

## Works with

Standalone (WooCommerce required). Uses the Factorize hub's Selling tab.
Uninstall removes only the plugin options and its transients — products,
terms, and files stay.

## Publishing and license

Distributed from the Factorize site under the proprietary Factorize License
(`LICENSE.txt` here and in the zip). See `../README-FACTORIZE.md`.
