Configurable PDP Block System on the Palo Alto Theme
Merchandiser-orderable buy-box blocks on Three Ships' licensed theme, with the subscription app block captured and re-emitted inside the buy box, plus metafield-driven size charts, a product-family switcher and a sticky add-to-cart bar.
Shopify app blocks can only be positioned as top-level section blocks, so a subscription widget cannot sit between the variant picker and Add to Cart. We extended the store's paid premium theme, Palo Alto 5.8.0 by Presidio Creative, into a 25-block product section, capturing the Recharge app block's rendered HTML once and re-emitting it inside the buy box where the CSS grid needs it.
Fact Strip
- Client: Three Ships
- Surfaces: Product detail page, landing pages, home
- Templates served: 150
- Block types in the section: 25
- Complexity: High
- Attribution: Built on top of Palo Alto 5.8.0 by Presidio Creative, a paid premium theme the client licenses. This product page is our extension of that theme, not a product page we authored. The block loop and the base block set are the vendor's; what follows is what we added inside it.
- Status: Live, verified 2026-09-06
- Evidence: Moderate — see How we know
The Problem
Three Ships runs seasonal and per-product page layouts — serums, kits, gift-with-purchase items and subscription products all present differently — across roughly 133 product templates. Merchandisers have to reorder and reconfigure the buy box themselves, because a promotional calendar does not wait for a developer.
Position is the hard part, not presence. The subscription widget, the upsell, the size guide and the family switcher each need a specific point inside the buy box: a subscribe-or-one-time control below the add-to-cart button is not the same control, commercially, as one above it. Shopify app blocks are positioned as top-level section blocks, so an app widget lands where the section's block list puts it — never nested inside the form.
The Constraint
The store runs a paid vendor theme. Palo Alto 5.8.0 by Presidio Creative is licensed code with its own upgrade path, block architecture and theme-editor contract, so the product page had to be extended in place. Rebuilding it would have discarded both the settings surface merchandisers already know and every future vendor update.
The app-block rule is the second constraint, and it is a hard one. Rendering an app block issues a server-side call, so a block cannot simply be rendered twice to get a copy where you want it. There is also no local build tooling in this codebase — every change here is hand-edited Liquid, reviewed by reading it, with no compile step to catch a mistake.
What We Built
The vendor's product page, extended into a 25-block section rendered through product.liquid — product_title, form, product_meta_icons, product_upsell, icons, cutline, product_accordion, siblings, inventory_countdown, line_item_property, feature, complementary-products, custom_code, pickup, divider and an @app slot among them. A "Featured product" section reuses the same snippet with a featured section type on landing and collection templates, and a third quickview type renders the same form inside a modal.
The Recharge placement is the piece worth reading. Before the main block loop runs, a pre-pass walks section.blocks, captures each app block's rendered output once, checks it for the subscription widget's marker, and stores that HTML with the block id. The main loop skips the block it captured, and the form block re-emits the stored HTML inside itself. The buy box is laid out with CSS grid template areas — variants, quantity, subscription, add to cart — so the re-emitted widget lands in a fixed slot between the variant picker and the button. One render, placed where the merchant needs it.
Around that: metafield-driven buy-box toggles, including one that drops the quantity control on products where choosing a quantity makes no sense. A size-chart drawer with two sources — product tags of the form _size_<page-handle> and a theme.size_chart metafield — falling back to a global information page. A product-family switcher, product-siblings.liquid, keyed on a merchandiser-picked product list with theme.cutline supplying each swatch's label, so a shopper moves between members of a range without returning to the collection. A legacy-upsell bridge folding the older theme.upsell metafield into the newer block-level product list setting, so campaigns configured under the old convention keep working. And a sticky add-to-cart bar reading custom.sticky_bar_title, then custom.short_product_title, then the product title, suppressed entirely for gift-with-purchase products.
Why This Way
The reason for the Recharge pre-pass is written in the code as a comment, and it is the correct reason: rendering an app block triggers a server-side call, so the block is resolved once and echoed where it is needed rather than rendered twice.
Every other decision follows the same rule: keep the vendor's architecture, add capability inside it. New block types and metafields extend what the section can do while leaving the theme editor's contract intact, so merchandisers configure our additions where they configure the vendor's, and a theme update does not meet a forked section.
Three costs come with that. Every vendor update has to be reconciled by hand against these modifications, because they live inside vendor files rather than beside them. The capture-and-re-emit approach recognizes the subscription widget by a marker in its own output — a contract with a third party's markup that nobody signed. And with no build tooling, what keeps this maintainable is reading, convention and review; nothing here fails loudly at compile time.
Why Not an App
Buy-box composition, sibling switchers, size-chart drawers and sticky add-to-cart bars are all sold as apps. A store with one product template could reasonably buy all four.
At this scale the arithmetic changes. Four apps means four more scripts on every product page, and four more theme-editor surfaces that don't talk to each other. It also means four more widgets that land where the section's block list puts them — and not one of them can sit between the variant picker and the add-to-cart button. That's the problem you started with. Built as theme blocks, these configure alongside everything else your merchandising team already uses.
Implementation Notes
- The same product snippet serves three modes through a section-type parameter: the full product page, a featured-product block on landing pages, and a quick-view rendering, changing the close control, drawer classes and title linking between them.
- Recharge widget resolution runs as a pre-pass: capture each app block's render, test the captured output for the subscription widget's marker, store the HTML and the block id, then skip that id in the main block loop.
- The buy box uses CSS grid template areas declared with the product markup — variants, quantity, subscription, add to cart — so the injected widget occupies a named slot rather than a document position.
- The complementary-products block calls Shopify's product recommendations route with a complementary intent and a section id, so the recommendations come back as rendered section HTML rather than JSON to assemble on the client.
- The upsell block resolves a product handle held in a metafield, looks the product up in the theme's product lookup, and renders a second product form inside the PDP for a one-click add.
- The featured-product section is roughly 1,450 lines of schema for 19 block types against about 30 lines of markup. Almost all of it is merchandiser configuration surface, and on a section built for merchandisers that ratio is the right way round.
Edge Cases
- Gift cards force the recipient form on and disable the dynamic checkout button, so a gift card cannot be bought through an express wallet flow that has nowhere to put a recipient.
- The dynamic checkout button is force-disabled whenever the product has selling plans or cart terms are enabled, keeping subscription products out of express wallet purchase paths.
- Products carrying a hidden tag render no add-to-cart button at all, which is how the merchandising team parks a product without unpublishing it; sold-out variants add a wrapper class the buy box styles against.
- In theme-editor design mode the siblings block renders placeholder swatches, so a merchandiser can see and position the block before it has been configured.
- The sticky bar is suppressed for gift-with-purchase products, so a free gift cannot be added a second time from a bar that follows the shopper down the page.
Platform Primitives Used
- Liquid section schema and settings — the 25 block types and their settings are the merchandiser's whole interface to the buy box.
- Metafields — size charts, sticky-bar titles, sibling labels, upsell handles and buy-box toggles.
- Theme app extensions — the app block whose rendered output is captured and re-placed inside the form.
- Section Rendering API — returns complementary recommendations as rendered markup for the block to drop in.
- Selling plans — their presence changes the buy box and disables the dynamic checkout button.
- Shopify Markets — market-specific template contexts sit alongside the templates this section serves.
Integrations in Play
- Recharge — the subscription platform whose app block this section captures and re-emits inside the buy box.
- Firework — shoppable video that coexists on the product page.
- Yotpo and Stamped — review and loyalty surfaces that sit alongside the buy box rather than inside it.
Where It Runs
The product detail page first, and beyond it landing and collection pages through the featured-product section. 150 templates mount this work in one form or another, which is the real measure of the constraint: a change to the block loop is a change to every product, kit, bundle and campaign page on the storefront at once.
What This Demonstrates
- Metafield-driven PDP content blocks — size charts, sibling labels, sticky-bar copy and upsell targets all resolve from structured fields rather than from Liquid edits.
It is also a subscription purchase-options build and a quick-view build; the placement problem and the modal rendering are the same section's work.
How We Know
Seven files read from the live theme — two sections and five snippets — plus seven client-side records from a task register and a roadmap. Those records describe the template rollout and the interface polishing; they do not record the architecture. Documented from the code; no client-side record of the decision survives.
That is why the attribution above is stated so carefully. Which of the 25 block types shipped with Palo Alto and which we added is not separable from the code alone. The Recharge pre-pass, the sibling switcher, the sticky-bar fallbacks and the upsell bridge read as our work; the base block loop does not, and we do not claim it.
Related Builds
- Rebuilt 2026 PDP section with merchandiser-composable blocks — the same composition problem on LUS Brands, where a newer Dawn base made a Deploi-authored section the better answer.
- Metafield-driven PDP content system — Nudestix's version, where the constraint was legacy copy rather than a licensed theme.
The Buy-vs-Build Question
On a licensed theme the question is not buy or build — it is buy, extend, or replace. Extending kept the vendor's upgrade path and the merchandising team's familiarity, at the price of hand-reconciling future updates. Where we draw that line is set out in the metafields and metaobjects architecture decision.
Ready to Get More Out of the Palo Alto Theme You Already License?
Most premium themes have more room in them than they are given credit for. Contact us today to talk about extending yours instead of starting over.