@@ -572,87 +572,325 @@ Use `.raw` suffix for numeric calculations:
572572| ` {item.finalPrice.raw} ` | Numeric final price |
573573| ` {item.finalLineTotal.raw} ` | Numeric final line total |
574574
575- ## Package Subscription Fields
575+ ## Package Display Attributes
576576
577- Display subscription and recurring billing information for packages .
577+ Display data for specific packages using ` package.[id].* ` syntax. Replace ` [id] ` with your package ID (e.g., ` package.123.price ` ) .
578578
579- ### Package ID Fields
579+ ### Shorthand Syntax
580+
581+ If the element is inside a container with ` data-next-package-id="3" ` , for example, then you can use ` package.price ` instead of ` package.3.price ` . The system resolves the package ID from the parent context.
582+
583+ ``` html
584+ <!-- Using full syntax -->
585+ <div >
586+ <span data-next-display =" package.123.price" >$29.99</span >
587+ <span data-next-display =" package.123.name" >Product Name</span >
588+ </div >
589+
590+ <!-- Using shorthand syntax with parent context -->
591+ <div data-next-package-id =" 123" >
592+ <span data-next-display =" package.price" >$29.99</span >
593+ <span data-next-display =" package.name" >Product Name</span >
594+ </div >
595+ ```
596+
597+ This shorthand is especially useful when building reusable product card components or when iterating over multiple packages.
598+
599+ ### Basic Properties
600+
601+ Display core package information:
602+
603+ ``` html
604+ <!-- Package name and image -->
605+ <h3 data-next-display =" package.123.name" >Product Name</h3 >
606+ <img data-next-display =" package.123.image" alt =" Product image" >
607+
608+ <!-- Package identifiers -->
609+ <span data-next-display =" package.123.ref_id" >123</span >
610+ <span data-next-display =" package.123.external_id" >456</span >
611+ ```
612+
613+ | Variable | Description | Type | Example |
614+ | ----------| -------------| ------| ---------|
615+ | ` package.[id].name ` | Package display name | String | "Premium Bundle" |
616+ | ` package.[id].image ` | Package image URL | String | "https://..." |
617+ | ` package.[id].ref_id ` | Internal reference ID | Number | 123 |
618+ | ` package.[id].external_id ` | External system ID | Number | 456 |
619+
620+ ### Pricing Properties
621+
622+ #### Base Prices
623+
624+ ``` html
625+ <!-- Per-unit price -->
626+ <span data-next-display =" package.123.price" >$29.99</span >
627+
628+ <!-- Total package price -->
629+ <span data-next-display =" package.123.price_total" >$89.97</span >
630+
631+ <!-- Alias for price_total -->
632+ <span data-next-display =" package.123.packageTotal" >$89.97</span >
633+
634+ <!-- Alias for price -->
635+ <span data-next-display =" package.123.unitPrice" >$29.99</span >
636+ ```
637+
638+ | Variable | Description | Type |
639+ | ----------| -------------| ------|
640+ | ` package.[id].price ` | Per-unit price | Currency |
641+ | ` package.[id].price_total ` | Total package price | Currency |
642+ | ` package.[id].packageTotal ` | Alias for ` price_total ` | Currency |
643+ | ` package.[id].unitPrice ` | Alias for ` price ` | Currency |
644+
645+ #### Retail/Compare Prices
646+
647+ ``` html
648+ <!-- Per-unit retail price -->
649+ <span data-next-display =" package.123.price_retail" >$39.99</span >
650+
651+ <!-- Total retail price -->
652+ <span data-next-display =" package.123.price_retail_total" >$119.97</span >
653+
654+ <!-- Aliases for retail prices -->
655+ <span data-next-display =" package.123.unitRetailPrice" >$39.99</span >
656+ <span data-next-display =" package.123.comparePrice" >$119.97</span >
657+ <span data-next-display =" package.123.compareTotal" >$119.97</span >
658+ ```
659+
660+ | Variable | Description | Type |
661+ | ----------| -------------| ------|
662+ | ` package.[id].price_retail ` | Per-unit retail price | Currency |
663+ | ` package.[id].price_retail_total ` | Total retail price | Currency |
664+ | ` package.[id].unitRetailPrice ` | Calculated unit retail price | Currency |
665+ | ` package.[id].comparePrice ` | Alias for ` price_retail_total ` | Currency |
666+ | ` package.[id].compareTotal ` | Alias for ` price_retail_total ` | Currency |
667+
668+ ### Savings Properties
669+
670+ Display savings information:
671+
672+ ``` html
673+ <!-- Savings amount -->
674+ <span data-next-display =" package.123.savingsAmount" >$30.00</span >
675+
676+ <!-- Savings percentage -->
677+ <span data-next-display =" package.123.savingsPercentage" >25</span >%
678+
679+ <!-- Unit savings -->
680+ <span data-next-display =" package.123.unitSavings" >$10.00</span >
681+ <span data-next-display =" package.123.unitSavingsPercentage" >25</span >%
682+
683+ <!-- Check if has savings -->
684+ <div data-next-show =" package.123.hasSavings" >
685+ <span class =" badge" >On Sale!</span >
686+ </div >
687+ ```
688+
689+ | Variable | Description | Type |
690+ | ----------| -------------| ------|
691+ | ` package.[id].savingsAmount ` | Total savings amount | Currency |
692+ | ` package.[id].savingsPercentage ` | Savings percentage | Percentage |
693+ | ` package.[id].unitSavings ` | Savings per unit | Currency |
694+ | ` package.[id].unitSavingsPercentage ` | Savings percentage per unit | Percentage |
695+ | ` package.[id].hasSavings ` | Whether package has savings | Boolean |
696+
697+ #### Raw Values (for calculations)
698+
699+ ``` html
700+ <!-- Raw numeric values for calculations -->
701+ <span data-next-display =" package.123.savingsAmount.raw" >30.00</span >
702+ <span data-next-display =" package.123.savingsPercentage.raw" >25</span >
703+ <span data-next-display =" package.123.unitPrice.raw" >29.99</span >
704+ <span data-next-display =" package.123.unitRetailPrice.raw" >39.99</span >
705+ ```
706+
707+ ### Discount Properties (Cart Context Required)
708+
709+ These properties require cart context to check for applied coupons/discounts. They work even if no coupons are applied (they'll return the regular price or zero).
710+
711+ ``` html
712+ <!-- Discount-adjusted prices -->
713+ <span data-next-display =" package.123.discountedPrice" >$24.99</span >
714+ <span data-next-display =" package.123.discountedPriceTotal" >$74.97</span >
715+
716+ <!-- Discount amount -->
717+ <span data-next-display =" package.123.discountAmount" >$5.00</span >
718+
719+ <!-- Final prices (after discounts) -->
720+ <span data-next-display =" package.123.finalPrice" >$24.99</span >
721+ <span data-next-display =" package.123.finalPriceTotal" >$74.97</span >
722+
723+ <!-- Check if has discount -->
724+ <div data-next-show =" package.123.hasDiscount" >
725+ <span class =" badge" >Discount Applied!</span >
726+ </div >
727+ ```
728+
729+ | Variable | Description | Type | Notes |
730+ | ----------| -------------| ------| -------|
731+ | ` package.[id].discountedPrice ` | Unit price after discounts | Currency | Requires cart context |
732+ | ` package.[id].discountedPriceTotal ` | Total price after discounts | Currency | Requires cart context |
733+ | ` package.[id].discountAmount ` | Discount amount applied | Currency | Requires cart context |
734+ | ` package.[id].hasDiscount ` | Whether package has discount | Boolean | Requires cart context |
735+ | ` package.[id].finalPrice ` | Final unit price (same as ` discountedPrice ` ) | Currency | Requires cart context |
736+ | ` package.[id].finalPriceTotal ` | Final total price (same as ` discountedPriceTotal ` ) | Currency | Requires cart context |
737+
738+ ### Total Savings (Retail + Discounts)
739+
740+ Combines retail savings with cart discounts:
580741
581742``` html
582- <!-- Package reference ID -->
583- <span data-next-display =" package.123.ref_id" >Internal ID</span >
743+ <!-- Total savings including discounts -->
744+ <span data-next-display =" package.123.totalSavingsAmount" >$35.00</span >
745+ <span data-next-display =" package.123.totalSavingsPercentage" >30</span >%
746+
747+ <!-- Aliases -->
748+ <span data-next-display =" package.123.totalSavingsWithDiscounts" >$35.00</span >
749+ <span data-next-display =" package.123.totalSavingsPercentageWithDiscounts" >30</span >%
584750
585- <!-- External package ID -->
586- <span data-next-display =" package.123.external_id" >External ID</span >
751+ <!-- Check if has any savings -->
752+ <div data-next-show =" package.123.hasTotalSavings" >
753+ <span >You're saving money!</span >
754+ </div >
587755```
588756
589- | Property | Description | Type |
757+ | Variable | Description | Type | Notes |
758+ | ----------| -------------| ------| -------|
759+ | ` package.[id].totalSavingsAmount ` | Total savings (retail + discounts) | Currency | Requires cart context |
760+ | ` package.[id].totalSavingsPercentage ` | Total savings percentage | Percentage | Requires cart context |
761+ | ` package.[id].totalSavingsWithDiscounts ` | Alias for ` totalSavingsAmount ` | Currency | Requires cart context |
762+ | ` package.[id].totalSavingsPercentageWithDiscounts ` | Alias for ` totalSavingsPercentage ` | Percentage | Requires cart context |
763+ | ` package.[id].hasTotalSavings ` | Whether package has any savings | Boolean | Requires cart context |
764+
765+ ### Quantity & Bundle Properties
766+
767+ ``` html
768+ <!-- Units in package -->
769+ <span data-next-display =" package.123.qty" >3</span > units
770+ <span data-next-display =" package.123.unitsInPackage" >3</span > units
771+
772+ <!-- Check if bundle -->
773+ <div data-next-show =" package.123.isBundle" >
774+ <span class =" badge" >Multi-Pack Deal</span >
775+ </div >
776+ ```
777+
778+ | Variable | Description | Type |
590779| ----------| -------------| ------|
591- | ` package.ref_id ` | Internal reference ID | Number |
592- | ` package.external_id ` | External system ID | Number |
780+ | ` package.[id].qty ` | Number of units in package | Number |
781+ | ` package.[id].unitsInPackage ` | Alias for ` qty ` | Number |
782+ | ` package.[id].isBundle ` | Whether package is a bundle (qty > 1) | Boolean |
593783
594- ### Recurring Properties
784+ ### Subscription & Recurring Properties
785+
786+ Display subscription and recurring billing information:
595787
596788``` html
597- <!-- Show subscription info -->
598- <div data-next-show =" package.123.is_recurring " >
789+ <!-- Check if subscription -->
790+ <div data-next-show =" package.123.isRecurring " >
599791 <p >Subscription Product</p >
600- <p >Delivered every <span data-next-display =" package.123.interval" >month</span ></p >
792+ <p >
793+ Billed every
794+ <span data-next-display =" package.123.interval_count" >1</span >
795+ <span data-next-display =" package.123.interval" >month</span >
796+ </p >
797+ <p class =" price" data-next-display =" package.123.price_recurring" >$29.99</p >
601798</div >
602799
603800<!-- One-time purchase -->
604801<div data-next-show =" package.123.isOneTime" >
605802 <p >One-time purchase</p >
803+ <p class =" price" data-next-display =" package.123.price" >$99.00</p >
606804</div >
607805```
608806
609- | Property | Description | Type | Values |
807+ | Variable | Description | Type | Values |
610808| ----------| -------------| ------| --------|
611- | ` package.is_recurring ` | Is subscription product | Boolean | true/false |
612- | ` package.interval ` | Billing interval | String | "day", "month", null |
613- | ` package.interval_count ` | Interval count | Number | 1, 2, 3, etc. |
614- | ` package.isRecurring ` | Is subscription (alias) | Boolean | true/false |
615- | ` package.isOneTime ` | Is one-time purchase | Boolean | true/false |
809+ | ` package.[id].is_recurring ` | Is subscription product | Boolean | true/false |
810+ | ` package.[id].isRecurring ` | Is subscription (alias) | Boolean | true/false |
811+ | ` package.[id].isOneTime ` | Is one-time purchase | Boolean | true/false |
812+ | ` package.[id].interval ` | Billing interval | String | "day", "month", null |
813+ | ` package.[id].interval_count ` | Interval count | Number | 1, 2, 3, etc. |
814+ | ` package.[id].price_recurring ` | Recurring price per billing cycle | Currency | "$29.99" |
815+ | ` package.[id].price_recurring_total ` | Total recurring price for all units | Currency | "$89.97" |
616816
617- ### Recurring Pricing
817+ ### Complete Product Card Example
618818
619819``` html
620- <!-- Recurring price -->
621- <span data-next-display =" package.123.price_recurring" >$29.99/month</span >
820+ <div class =" product-card" data-next-package-id =" 123" >
821+ <!-- Product info -->
822+ <h3 data-next-display =" package.name" >Product Name</h3 >
823+ <img data-next-display =" package.image" alt =" Product image" >
824+
825+ <!-- Pricing -->
826+ <div class =" pricing" >
827+ <!-- Regular price (no savings) -->
828+ <div data-next-hide =" package.hasSavings" >
829+ <p class =" price" data-next-display =" package.price" >$99.00</p >
830+ </div >
622831
623- <!-- Total recurring price -->
624- <span data-next-display =" package.123.price_recurring_total" >$89.97</span >
625- ```
832+ <!-- Sale price with savings -->
833+ <div data-next-show =" package.hasSavings" >
834+ <s data-next-display =" package.price_retail" >$149.00</s >
835+ <p class =" price" data-next-display =" package.price" >$99.00</p >
836+ <span class =" savings" >
837+ Save <span data-next-display =" package.savingsAmount" >$50.00</span >
838+ (<span data-next-display =" package.savingsPercentage" >33</span >%)
839+ </span >
840+ </div >
626841
627- | Property | Description | Type |
628- | ---------- | ------------- | ------ |
629- | ` package.price_recurring ` | Recurring price per billing cycle | Currency |
630- | ` package.price_recurring_total ` | Total recurring price for all units | Currency |
842+ <!-- One-time price -->
843+ < div data-next-show = " package.isOneTime " >
844+ < p >One-time purchase</ p >
845+ </ div >
631846
632- ### Subscription Display Example
847+ <!-- Subscription price -->
848+ <div data-next-show =" package.isRecurring" >
849+ <p class =" price" data-next-display =" package.price_recurring" >$29.99</p >
850+ <p >
851+ Billed every
852+ <span data-next-display =" package.interval_count" >1</span >
853+ <span data-next-display =" package.interval" >month</span >
854+ </p >
855+ </div >
633856
634- ``` html
635- <div class =" product-card" data-package-id =" 123" >
636- <h3 data-next-display =" package.123.name" >Product Name</h3 >
857+ <!-- Bundle indicator -->
858+ <div data-next-show =" package.isBundle" >
859+ <span class =" badge" >
860+ <span data-next-display =" package.qty" >3</span > Pack Deal
861+ </span >
862+ </div >
863+ </div >
637864
638- <!-- One-time price -->
639- <div data-next-show =" package.123.isOneTime " >
640- <p class = " price " data-next-display =" package.123.price " >$99 .00</p >
641- <p >One-time purchase</ p >
865+ <!-- Discount info (if cart has coupons) -->
866+ <div data-next-show =" package.hasDiscount " class = " discount-badge " >
867+ <span >Extra Discount: < span data-next-display =" package.discountAmount " >$5 .00</span ></ span >
868+ <span >Final Price: < span data-next-display = " package.finalPriceTotal " >$94.00</ span ></ span >
642869 </div >
643870
644- <!-- Subscription price -->
645- <div data-next-show =" package.123.isRecurring" >
646- <p class =" price" data-next-display =" package.123.price_recurring" >$29.99</p >
647- <p >
648- Billed every
649- <span data-next-display =" package.123.interval_count" >1</span >
650- <span data-next-display =" package.123.interval" >month</span >
651- </p >
871+ <!-- Package identifiers (for debugging) -->
872+ <div class =" package-info" style =" display : none ;" >
873+ <small >
874+ ID: <span data-next-display =" package.ref_id" >123</span > |
875+ External: <span data-next-display =" package.external_id" >456</span >
876+ </small >
652877 </div >
653878</div >
654879```
655880
881+ ### Checking Cart Quantity
882+
883+ To check if a package is in the cart and get its quantity, use conditional attributes:
884+
885+ ``` html
886+ <!-- Check if package is in cart -->
887+ <div data-next-show =" cart.hasItem(123)" >
888+ <span >In Cart: <span data-next-display =" cart.items[123].quantity" >0</span ></span >
889+ </div >
890+ ```
891+
892+ Note: ` cart.hasItem(123) ` works in conditional attributes (` data-next-show ` /` data-next-hide ` ), not in display attributes.
893+
656894## Performance Tips
657895
658896### Efficient Selectors
0 commit comments