Changeset 3786796
- Timestamp:
- 11/05/2026 09:52:12 PM (23 hours ago)
- Location:
- giftlight
- Files:
-
- 6 edited
- 7 copied
-
tags/1.0.1 (copied) (copied from giftlight/trunk )
-
tags/1.0.1/admin.php (copied) (copied from giftlight/trunk/admin.php )
-
tags/1.0.1/assets (copied) (copied from giftlight/trunk/assets )
-
tags/1.0.1/assets/giftlight.js (modified) (3 diffs)
-
tags/1.0.1/blocks (copied) (copied from giftlight/trunk/blocks )
-
tags/1.0.1/blocks/gift-guide/block.json (modified) (1 diff)
-
tags/1.0.1/giftlight.php (copied) (copied from giftlight/trunk/giftlight.php ) (2 diffs)
-
tags/1.0.1/readme.txt (copied) (copied from giftlight/trunk/readme.txt ) (3 diffs)
-
tags/1.0.1/uninstall.php (copied) (copied from giftlight/trunk/uninstall.php )
-
trunk/assets/giftlight.js (modified) (3 diffs)
-
trunk/blocks/gift-guide/block.json (modified) (1 diff)
-
trunk/giftlight.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
giftlight/tags/1.0.1/assets/giftlight.js
r3786748 r3786796 95 95 // Build a gift finder from the catalog. It only asks what the catalog can answer: a question goes in only when at least 96 96 // two of its options each lead to `min` products and none of them matches everything. Returns { questions, products }. 97 // A product filed only under wholesale collections (a bulk case, a trade pack) isn't a gift. Nov 5: the WooCommerce walk's 98 // $300 "Bulk Mug Case", in "WholeSale7" alone, reached "Gifts $60 and up" once sections stopped repeating gifts. 99 // A product that is also in a shopper-facing collection stays. 100 const wholesaleOnly = (p, names) => { 101 const in_ = (p.cols || []).map(id => names.get(id)).filter(Boolean); 102 return in_.length > 0 && in_.every(n => /wholesale/i.test(n)); 103 }; 104 97 105 function buildGiftFinder({ products = [], collections = [], money } = {}, { min = 2, maxOptions = 6 } = {}) { 106 const colNames = new Map(collections.map(c => [c.id, clean(c.title)])); 98 107 const live = products 99 .filter(p => p.available !== false && p.image && p.price > 0 )108 .filter(p => p.available !== false && p.image && p.price > 0 && !wholesaleOnly(p, colNames)) 100 109 .map(p => ({ ...p, aud: audienceOf(p, collections) })); 101 110 const narrows = n => n >= min && n < live.length; … … 200 209 const live = (quiz.products || []).filter(p => p.available !== false).sort(byRank); 201 210 const sections = []; 211 // Nov 4, 2026: a gift already shown higher up gives way to one that hasn't been, so a store's first few products 212 // don't fill every section (16 of 50 merchant critics named the repeats). A section still shows as many gifts as 213 // before, in store order; a gift repeats only when its section has nothing new left. 214 const shown = new Map(); 215 const seen = p => shown.get(p.id) || 0; 202 216 for (const id of ['who', 'budget', 'into']) { 203 217 const q = (quiz.questions || []).find(x => x.id === id); … … 208 222 if (fit.length < min) continue; 209 223 if (o.rule.kind === 'price') fit = fit.map(p => { const v = inBand(p, o.rule); return v && v[0] !== p.variant ? { ...p, variant: v[0], price: v[1] } : p; }); 210 sections.push({ id: `${id}-${o.id}`, title: GUIDE_TITLE[id](o), products: fit.slice(0, per), total: fit.length }); 224 const pick = [...fit].sort((a, b) => seen(a) - seen(b) || byRank(a, b)).slice(0, per).sort(byRank); 225 for (const p of pick) shown.set(p.id, seen(p) + 1); 226 sections.push({ id: `${id}-${o.id}`, title: GUIDE_TITLE[id](o), products: pick, total: fit.length }); 211 227 } 212 228 } -
giftlight/tags/1.0.1/blocks/gift-guide/block.json
r3786748 r3786796 3 3 "apiVersion": 3, 4 4 "name": "giftlight/gift-guide", 5 "version": "1.0. 0",5 "version": "1.0.1", 6 6 "title": "Gift guide", 7 7 "category": "woocommerce", -
giftlight/tags/1.0.1/giftlight.php
r3786748 r3786796 4 4 * Plugin URI: https://giftlight.app/ 5 5 * Description: A gift guide and a gift finder quiz built from your own WooCommerce products: by who it's for, what to spend and what they're into. 6 * Version: 1.0. 06 * Version: 1.0.1 7 7 * Requires at least: 6.3 8 8 * Requires PHP: 7.4 … … 21 21 } 22 22 23 define( 'GIFTLIGHT_VERSION', '1.0. 0' );23 define( 'GIFTLIGHT_VERSION', '1.0.1' ); 24 24 define( 'GIFTLIGHT_FILE', __FILE__ ); 25 25 define( 'GIFTLIGHT_MAX_PRODUCTS', 300 ); -
giftlight/tags/1.0.1/readme.txt
r3786748 r3786796 6 6 Requires PHP: 7.4 7 7 Requires Plugins: woocommerce 8 Stable tag: 1.0. 08 Stable tag: 1.0.1 9 9 License: GPLv2 or later 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 41 41 == Frequently Asked Questions == 42 42 43 = Can I try it before I install it? = 44 45 Yes. [Open the demo shop](https://playground.wordpress.net/?blueprint-url=https://giftlight.app/demo/woo-preview.json): a temporary WordPress in your browser with WooCommerce, 90 sample products and the Gift Guide page Giftlight made from them. Nothing is installed on your site, and it's gone when you close the tab. It takes a minute or two to load. 46 47 = Will it slow my shop down? = 48 49 It adds one deferred script (about 30 KB) and one small stylesheet, and only on pages that show the guide or the quiz. The product list it reads is cached for 12 hours and refreshed when you change a product or category. 50 43 51 = Do I have to write the questions? = 44 52 … … 73 81 == Changelog == 74 82 83 = 1.0.1 = 84 * Sections share out your products: a gift already shown in a section above gives way to one that hasn't been, so shoppers see more of your shop. 85 75 86 = 1.0.0 = 76 87 * First release: the gift guide block and shortcode, the gift quiz, and the one-click Gift Guide page. -
giftlight/trunk/assets/giftlight.js
r3786748 r3786796 95 95 // Build a gift finder from the catalog. It only asks what the catalog can answer: a question goes in only when at least 96 96 // two of its options each lead to `min` products and none of them matches everything. Returns { questions, products }. 97 // A product filed only under wholesale collections (a bulk case, a trade pack) isn't a gift. Nov 5: the WooCommerce walk's 98 // $300 "Bulk Mug Case", in "WholeSale7" alone, reached "Gifts $60 and up" once sections stopped repeating gifts. 99 // A product that is also in a shopper-facing collection stays. 100 const wholesaleOnly = (p, names) => { 101 const in_ = (p.cols || []).map(id => names.get(id)).filter(Boolean); 102 return in_.length > 0 && in_.every(n => /wholesale/i.test(n)); 103 }; 104 97 105 function buildGiftFinder({ products = [], collections = [], money } = {}, { min = 2, maxOptions = 6 } = {}) { 106 const colNames = new Map(collections.map(c => [c.id, clean(c.title)])); 98 107 const live = products 99 .filter(p => p.available !== false && p.image && p.price > 0 )108 .filter(p => p.available !== false && p.image && p.price > 0 && !wholesaleOnly(p, colNames)) 100 109 .map(p => ({ ...p, aud: audienceOf(p, collections) })); 101 110 const narrows = n => n >= min && n < live.length; … … 200 209 const live = (quiz.products || []).filter(p => p.available !== false).sort(byRank); 201 210 const sections = []; 211 // Nov 4, 2026: a gift already shown higher up gives way to one that hasn't been, so a store's first few products 212 // don't fill every section (16 of 50 merchant critics named the repeats). A section still shows as many gifts as 213 // before, in store order; a gift repeats only when its section has nothing new left. 214 const shown = new Map(); 215 const seen = p => shown.get(p.id) || 0; 202 216 for (const id of ['who', 'budget', 'into']) { 203 217 const q = (quiz.questions || []).find(x => x.id === id); … … 208 222 if (fit.length < min) continue; 209 223 if (o.rule.kind === 'price') fit = fit.map(p => { const v = inBand(p, o.rule); return v && v[0] !== p.variant ? { ...p, variant: v[0], price: v[1] } : p; }); 210 sections.push({ id: `${id}-${o.id}`, title: GUIDE_TITLE[id](o), products: fit.slice(0, per), total: fit.length }); 224 const pick = [...fit].sort((a, b) => seen(a) - seen(b) || byRank(a, b)).slice(0, per).sort(byRank); 225 for (const p of pick) shown.set(p.id, seen(p) + 1); 226 sections.push({ id: `${id}-${o.id}`, title: GUIDE_TITLE[id](o), products: pick, total: fit.length }); 211 227 } 212 228 } -
giftlight/trunk/blocks/gift-guide/block.json
r3786748 r3786796 3 3 "apiVersion": 3, 4 4 "name": "giftlight/gift-guide", 5 "version": "1.0. 0",5 "version": "1.0.1", 6 6 "title": "Gift guide", 7 7 "category": "woocommerce", -
giftlight/trunk/giftlight.php
r3786748 r3786796 4 4 * Plugin URI: https://giftlight.app/ 5 5 * Description: A gift guide and a gift finder quiz built from your own WooCommerce products: by who it's for, what to spend and what they're into. 6 * Version: 1.0. 06 * Version: 1.0.1 7 7 * Requires at least: 6.3 8 8 * Requires PHP: 7.4 … … 21 21 } 22 22 23 define( 'GIFTLIGHT_VERSION', '1.0. 0' );23 define( 'GIFTLIGHT_VERSION', '1.0.1' ); 24 24 define( 'GIFTLIGHT_FILE', __FILE__ ); 25 25 define( 'GIFTLIGHT_MAX_PRODUCTS', 300 ); -
giftlight/trunk/readme.txt
r3786748 r3786796 6 6 Requires PHP: 7.4 7 7 Requires Plugins: woocommerce 8 Stable tag: 1.0. 08 Stable tag: 1.0.1 9 9 License: GPLv2 or later 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 41 41 == Frequently Asked Questions == 42 42 43 = Can I try it before I install it? = 44 45 Yes. [Open the demo shop](https://playground.wordpress.net/?blueprint-url=https://giftlight.app/demo/woo-preview.json): a temporary WordPress in your browser with WooCommerce, 90 sample products and the Gift Guide page Giftlight made from them. Nothing is installed on your site, and it's gone when you close the tab. It takes a minute or two to load. 46 47 = Will it slow my shop down? = 48 49 It adds one deferred script (about 30 KB) and one small stylesheet, and only on pages that show the guide or the quiz. The product list it reads is cached for 12 hours and refreshed when you change a product or category. 50 43 51 = Do I have to write the questions? = 44 52 … … 73 81 == Changelog == 74 82 83 = 1.0.1 = 84 * Sections share out your products: a gift already shown in a section above gives way to one that hasn't been, so shoppers see more of your shop. 85 75 86 = 1.0.0 = 76 87 * First release: the gift guide block and shortcode, the gift quiz, and the one-click Gift Guide page.
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)