Per-product settings (the Polski Pro tab)
Five PRO modules are configured per product, not globally: gift cards, pre-orders, subscriptions, product bundles and frequently bought together. Each one decides whether to run for a product by reading a meta key on that product. Since Polski PRO 1.26.0 there is a screen that writes those keys: a Polski Pro tab in the product data box of the WooCommerce product editor.
Where the tab is, and when it appears
Section titled “Where the tab is, and when it appears”Open any product and look at the Product data box. The Polski Pro tab sits after the standard WooCommerce tabs and is shown for simple, variable and external products.
The tab appears only if at least one of the five modules is enabled on Polski > Modules. With all five off there is nothing to configure, so the tab is not added at all. Inside the tab, only the enabled modules get a group of fields: switch two on and you see two groups, not five.
That gating is the first thing to check if a field you expect is missing. The module is the switch for the whole shop; this tab is the switch for one product.
The fields
Section titled “The fields”Each group below matches one module. The meta key is the one the module’s own service reads, so the key column is also the answer to “what do I set from WP-CLI or from code”.
Gift card
Section titled “Gift card”| Field | Meta key | Type | Notes |
|---|---|---|---|
| Sell as a gift card | _polski_gift_card_enabled |
yes / no |
The gate. The module treats the product as a gift card only when this is yes. |
| Preset amounts | _polski_gift_card_amounts |
text | Comma separated, for example 50, 100, 200. Empty falls back to the module’s global presets. |
| Allow a custom amount | _polski_gift_card_allow_custom_amount |
yes / no |
Lets the buyer type their own amount. The module also honours its global setting, so a shop-wide “allow custom” stays in force even when this box is clear. |
| Minimum custom amount | _polski_gift_card_min_amount |
number | Read as an override of the module’s global minimum. |
| Maximum custom amount | _polski_gift_card_max_amount |
number | Read as an override of the module’s global maximum. |
Pre-order
Section titled “Pre-order”| Field | Meta key | Type | Notes |
|---|---|---|---|
| Sell as a pre-order | _polski_preorder_enabled |
yes / no |
Half of the gate. |
| Release date | _polski_preorder_date |
date (Y-m-d) |
The other half. Both are required: with the box ticked and no date the product stays an ordinary product, because the module asks for the flag and a parsable date before it changes anything. |
| Button text | _polski_preorder_button_text |
text | Overrides the module’s global pre-order button text for this product. |
Subscription
Section titled “Subscription”| Field | Meta key | Type | Notes |
|---|---|---|---|
| Sell as a subscription | _polski_subscription_enabled |
yes / no |
The gate. |
| Bill every | _polski_subscription_interval |
integer | Number of periods between charges. Read as at least 1. |
| Billing period | _polski_subscription_period |
day, week, month, year |
Defaults to month when unset. |
| Number of payments | _polski_subscription_length |
integer | 0 renews until the customer cancels. |
| Sign-up fee | _polski_subscription_signup_fee |
number | Charged once, with the first payment. |
| Trial days | _polski_subscription_trial_days |
integer | Days before the first charge. 0 for no trial. |
Product bundle
Section titled “Product bundle”| Field | Meta key | Type | Notes |
|---|---|---|---|
| Bundled products | _polski_bundle_items |
textarea | One component per line, see the format below. |
| Section title | _polski_bundle_title |
text | Overrides the module’s global bundle heading for this product. |
| Button text | _polski_bundle_button_text |
text | Overrides the global bundle button text. |
| Bundle discount | _polski_bundle_discount_type |
empty, percent, fixed |
Empty means no discount. |
| Discount value | _polski_bundle_discount_value |
number | Read together with the type above. |
Bundled products takes one component per line, each written as the product id, then a vertical bar, then the quantity, then a vertical bar, then whether the component is required:
42|2|yes57|1|no88The quantity and the required flag may be left off, so a bare 88 is one optional unit of product 88. A required flag counts as required when it reads yes, 1, true or required. A single line of comma separated ids is accepted as a shorthand for one unit each. Ids that do not resolve to an existing product are skipped.
There is no separate “enable bundle” box: a product is a bundle when Bundled products resolves to at least one real product.
Frequently bought together
Section titled “Frequently bought together”| Field | Meta key | Type | Notes |
|---|---|---|---|
| Suggested products | _polski_fbt_product_ids |
text | Product ids, separated by commas, spaces or semicolons. The product’s own id is skipped, duplicates are dropped, and the list is cut at the module’s Maximum products taken from the product list setting (4 by default). |
| Section title | _polski_fbt_title |
text | Overrides the module’s global heading for this product. |
| Intro text | _polski_fbt_intro |
textarea | Optional line under the heading. |
| Button text | _polski_fbt_button_text |
text | Overrides the global add-all button text. |
As with bundles, there is no per-product on switch: the block appears for a product once Suggested products lists at least one usable id.
How the save works
Section titled “How the save works”Every field is sanitised on the way in: a checkbox is stored as yes or no, an integer field as a whole number of at least 0, a number field as a float of at least 0, the two textareas through sanitize_textarea_field, and everything else through sanitize_text_field. A number field left blank is stored blank rather than cast to 0, because an empty field means “no per-product value” and a zero you type means zero. WooCommerce has already checked the nonce and the capability before this runs.
The save pass skips every group whose module is off. This matters more than it sounds: an unticked checkbox posts nothing, and the loop reads a missing value as “cleared”. That is right for a box the merchant just unticked and wrong for a field that was never on the page, so a module you switch off does not silently blank the per-product settings you had already entered. Switch the module back on and the product is configured as it was.
Progressive disclosure
Section titled “Progressive disclosure”The gift-card, pre-order and subscription sub-fields each sit in a block that collapses while its master checkbox is clear, so a product that is not a gift card does not show five gift-card fields.
This is presentation only. The markup ships open, so with JavaScript blocked every field is visible, editable and saved exactly the same way; nothing is gated behind the script. While a block is collapsed it is also out of the tab order, so a hidden field cannot be filled by keyboard and then saved without anyone seeing it.
If a module still does nothing
Section titled “If a module still does nothing”- Is the module enabled on Polski > Modules? Each of the five ships off, because each changes what a shopper sees.
- Is the per-product gate set? Gift cards, pre-orders and subscriptions each need their own checkbox ticked on the product; a pre-order also needs a release date.
- For bundles and frequently bought together, does the list resolve to real, existing products?
- Does the module’s own Show on the product page setting (on the Modules screen) still allow it?