=== Pomp Product Personalizer for WooCommerce ===
Contributors: ipomper
Tags: woocommerce, personalization, custom products, print on demand, product designer
Requires at least: 6.4
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.0.1
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Let customers personalise products with their own name, see it on the product before buying, and send you a print-ready file.

== Description ==

Your customers pick a design, type a name, and watch it appear on the product — a shirt, a mug, whatever you sell. When they order, you get a print-ready vector file. No back-and-forth, no guessing what they meant.

Everything runs on your own server. There is no external service, no per-order fee and no account to sign up for.

= Set up a product once, sell every design on it =

Customers choose the design first and the product second. So you set up a shirt or a mug only once: where the print sits, its colours and its variations. From then on every design in your catalogue works on it, including the ones you add next month. A new slogan is just its text: type it, save it, and it is ready on every product.

= How it works =

1. Set up each product once: where the print sits and which colour it prints in on each variation.
2. Add designs to your catalogue, or import a whole batch from CSV. Each one works on every product straight away.
3. Customers pick a design, type their name, choose the product and add it to the cart.
4. Every order carries an SVG file, ready for print.

= What you get =

* A searchable catalogue of designs, with categories
* Live preview on a mockup of the real product, with no page reloads
* Print-ready SVG with every order, at the exact size you set
* Per-product print position, colour and canvas
* Bulk CSV import for large catalogues
* Works with variable products: colour and size change the mockup
* Production email with the print file attached
* Each design gets its own address and its own page, so search engines can find it

= Pro =

[Pomp Product Personalizer Pro](https://personalizer.pomp.site/pro/) is the full version of this plugin, sold separately. It does everything this one does, and adds three things:

* **Custom text** — the customer writes the wording themselves, line by line, choosing the font, spacing and margins.
* **Custom artwork** — they upload their own SVG or image, which is checked and rebuilt before it ever reaches print.
* **Personalised on the product's own page** — one row above Add to cart, for a product that needs no catalogue.

This plugin is complete on its own and nothing in it is waiting to be unlocked. Pro is installed *instead of* it, never alongside; the designs, settings and orders are the same under either.

= Where the files go, and when they are removed =

Two files are written for every configuration a customer builds: a preview,
and the print file itself. Both are SVG, both land in your uploads folder:

* `uploads/pomp-personalizer/generated/YEAR/MONTH/` for previews
* `uploads/pomp-personalizer/generated/print/YEAR/MONTH/` for print files

File names carry the configuration's UUID, so they cannot be guessed, and the
print folder ships an .htaccess rule that denies direct access. That rule is
honoured by Apache and LiteSpeed; **on nginx it is ignored**, so if you serve
files with nginx, deny the folder in your server config as well. Print files are
handed out through the plugin, which checks who is asking.

A preview and a print file together take about 27 kB on the designs this was
built against, ranging from 1 to 67 kB depending on how much text there is.

An hourly task clears up after browsing. A configuration that was never ordered
expires after seven days, and its two files go with it. **Anything attached to
an order is left alone, however old** — you have to be able to print what you
have already sold. Temporary files are removed after a day, and previews left
behind by deleted designs go the same way.

Seven days is a filter, not a fixed number: `pomp_configuration_ttl_days` moves it.

= What it costs to run =

The output is vector, so nothing is rasterised. There are no image libraries in
the path that draws a design, no headless browser, no queue, and no calls to
anyone else's server.

Measured on a modest development machine, rendering a two-line design on a mug:

* Preview: 15-28 ms, typically 17 ms
* Preview plus print file: 18 ms
* Memory beyond what WordPress already uses: under 0.1 MB

There is no background processing. Nothing is rendered until a customer asks for
it, and the hourly cleanup is a single indexed query plus a few file deletions.
Shared hosting is enough.

Imagick is used in exactly one place: the small raster thumbnail in the
production email, because email clients do not render SVG. Without Imagick the
email falls back to the vector preview and everything else carries on.

= Fonts =

Anton and Amatic SC are put in place when the plugin is first activated, so a new shop can draw a design straight away instead of having to find a font first. Both are Google Fonts under the SIL Open Font License; the licence and its copyright notices ship with them. Delete one and it stays deleted - an update will not put it back.

Upload your own as well, as **TrueType (.ttf)**. The design is traced glyph by glyph into a vector print file, so the font's outlines have to be readable: WOFF and WOFF2 keep them compressed, and OpenType with CFF curves stores them in a form this cannot read. Google Fonts offers a .ttf for every family. The plugin also ships Space Mono and Inter, used for the configurator's own interface.

== Installation ==

1. Install and activate WooCommerce first.
2. Upload the plugin through **Plugins → Add New**, or unzip it into `wp-content/plugins/`.
3. Activate it through **Plugins**.
4. Create two pages: one for the configurator, one for the design catalogue. They can be left empty.
5. Open **Pomp → Settings** and choose which page is which. That is enough - each page then shows what it is meant for, with no shortcode to write.
6. To place them inside a layout of your own instead, put `[pomp_personalizer]` on the configurator page and `[pomp_catalog]` on the catalogue page. A page that carries the shortcode is left exactly as you built it.
7. On a classic theme there is also a full-width, title-free page template for each, under **Page Attributes → Template**: *Pomp: configurator* and *Pomp: design catalogue*. Block themes do not offer plugin page templates in their editor, so there step 5 is the way.
8. Open any product, tick **Include this product in the configurator** in the Personalisation configurator box, and set where the print sits.

== Frequently Asked Questions ==

= Do I need an account with an external service? =

No. Everything runs on your own server. Designs live in your database, generated files in your uploads folder.

= What file do I get when someone orders? =

An SVG, at the ratio you set for that product. It is vector, so it scales to any print size without loss. The production email links to it, and it is also on the order in the admin.

= Can a customer order a personalised product without going through the configurator? =

No. Products you include in the configurator cannot be added to the cart directly — otherwise you would receive orders with nothing to print.

= Does it work with variable products? =

Yes. Colour and size are read from the variation, and you can give each colour its own mockup image. Size does not change the print, so all sizes of one colour share an image.

= Can customers write their own text or upload their own graphic? =

Not with this plugin, which offers the designs you put in the catalogue. Both are in Pro, which is the full version of this plugin sold separately - not an unlock, and none of its code is in here.

= Can I use my own placeholder backgrounds instead of the bundled ones? =

Yes. Under Pomp -> Settings, "Placeholder backgrounds" lets you add your own images alongside the bundled set, and set the text colour for any of them - built in or your own - instead of the default (its own colour, darkened).

= I use a size guide plugin. Will it show up on a personalised product? =

Yes, on its own. A product in the configurator never shows its normal WooCommerce page, so anything a plugin adds there would otherwise go unseen - this plugin reads it back out from the same two places WooCommerce's own product page does (the product tabs, and the area around the Add to cart button), so a size guide (or similar) plugin needs no changes on its side.

= Can I change how the configurator page looks? =

Yes, and you can pick how far you want to go. Place the `[pomp_personalizer]` shortcode in a page you have built yourself and the configurator fits into your own layout. Or pick the *Pomp: configurator* page template and restyle it with CSS - the body carries an `pomp-template--configurator` class to target. Or, for full control of the markup, copy `templates/pomp-configurator.php` out of the plugin into `yourtheme/pomp-personalizer/pomp-configurator.php` and edit it there: a copy in the theme is always used ahead of the plugin's own, and it survives plugin updates. The same goes for `pomp-catalog.php`.

= What can I change about the shortcodes? =

`[pomp_personalizer]` takes `product_id` and `design`, to open on a particular product or a particular design.

`[pomp_catalog]` takes `chrome`, `search`, `categories`, `products`, `count`, `pagination` and `per_page`. `chrome="no"` turns off everything around the grid at once, and any of the others can still be named to override that - so `[pomp_catalog chrome="no" per_page="8"]` is eight designs and nothing else, ready to drop into a page you have laid out yourself.

= Will it slow my shop down? =

No. Nothing is rendered until a customer asks for it, and a render takes about 17 ms without touching an image library. See "What it costs to run" above for the measurements.

= The configurator or the cart came up empty after I switched on a cache plugin =

Turn off **combine JavaScript** (Autoptimize calls it "aggregate", LiteSpeed and WP Rocket call it "combine") and clear the cache. Combining puts every script on the page into one file, so if any single one of them comes out of the minifier broken, nothing on the page runs at all - and the broken one is usually not this plugin's. WooCommerce's block cart and block checkout draw themselves with JavaScript, so there it shows as a page with nothing on it.

Minifying, deferring and page caching are all fine. This plugin marks the configurator and the design pages as not to be cached - `DONOTCACHEPAGE`, backed by real no-cache headers - so caches leave those alone and keep serving the rest of the shop from cache.

One more thing worth checking: some optimisers hand scripts and stylesheets out of their cache folder as .php files, and some hosts refuse to serve .php from inside `wp-content/cache` (a 403 or a 410 in the browser console, with "refused to execute script" beside it). Then nothing on the page loads, this plugin included. Switching that optimiser to write plain .js and .css files fixes it.

= How much disk space does it use? =

About 27 kB per configuration, for the preview and the print file together. Configurations that were never ordered are cleared after seven days; anything attached to an order is kept.

== Screenshots ==

1. Where the customer starts: the catalogue of designs you have put in.
2. The customer types a name and watches it appear on the product.
3. The catalogue of designs, searchable, and shown on whichever product and colour the customer picks.
4. Designs in the admin: a line each, with previews, and CSV import for a whole batch.
5. Setting where the print sits on a product - its place, its size, and how it follows the shape.
6. An order carries the design, the name, the preview and the print file.
7. The print file itself: vector, at the size set for that product.

== Changelog ==

= 1.0.1 =
* Buttons no longer move when hovered, and hover is left to devices that have a pointer.

= 1.0.0 =
* First release.
