Conversation
Codencode
marked this pull request as draft
September 8, 2026 14:18
Codencode
force-pushed
the
feature/data-ps-fragment-esi
branch
from
September 9, 2026 07:17
9bebabb to
180aa55
Compare
Codencode
marked this pull request as ready for review
September 9, 2026 07:39
Codencode
force-pushed
the
feature/data-ps-fragment-esi
branch
from
September 14, 2026 10:28
180aa55 to
191be66
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
This PR adds support for dynamic ESI fragments identified through semantic
data-ps-fragmentattributes in the final HTML output.This implementation depends on the Hummingbird change proposed in PrestaShop/hummingbird#1101. Without that change, Hummingbird does not expose the required fragment markers and these blocks cannot be handled through this mechanism.
It currently supports:
notificationsproduct-add-to-cartThese blocks are isolated from the full-page cache and regenerated through ESI using the current request/cart context.
This avoids stale cart-dependent content on cached pages, including:
"Your cart contains..."notification;product-add-to-cartblock;Why?
This is an alternative to the approach proposed in:
Those PRs required dedicated:
displayDynamicFragmentBeforedisplayDynamicFragmentAfterhooks in the theme templates.
Instead, Hummingbird exposes semantic markers directly on the existing dynamic block containers:
and:
LiteSpeed Cache detects these elements from the final HTML output, identifies their complete boundaries and replaces them with ESI includes.
No additional wrapper elements, dedicated cache hooks or LiteSpeed-specific logic are required in the theme.
The related Hummingbird implementation is:
PrestaShop/hummingbird#1101
If this PR and the related Hummingbird PR are merged, #103 can be closed because the previous before/after hook approach is no longer required.
Notifications
The existing
hasNotification()safety behavior is preserved as a fallback.The no-cache decision is postponed until the final HTML is available:
data-ps-fragment="notifications"is successfully converted to ESI, the page itself may remain cacheable;Has private notificationbehavior is preserved.Notifications already generated during the initial cache MISS are preserved through ESI inline content.
The ESI request also uses the standard PrestaShop notification preparation mechanism when available and regenerates the product/cart notification from the current cart context.
Since Hummingbird now exposes the marker directly on the existing
#notificationscontainer, the ESI endpoint can render_partials/notifications.tpldirectly without introducing additional wrapper markup.Product add to cart
The complete
product-add-to-cartblock is regenerated through ESI rather than caching only the button state.This allows the fragment to reflect the current context, including:
displayProductActions.The original fragment is replaced as a whole, which also prevents nested ESI markers generated inside
product-add-to-cartfrom being stored in the full-page cache.Product presentation
The ESI endpoint rebuilds the subset of product data required by the
product-add-to-cartfragment.The ESI request cannot safely reuse
ProductController::getTemplateVarProduct(), and PrestaShop currently exposes no public reusable core API that gives a module exactly the same presented product prepared by the product page.The implementation therefore uses the existing PrestaShop product presentation components and reconstructs the product-page-specific data required by this fragment.
This code is explicitly documented as a maintenance point and should be reviewed if the PrestaShop product presentation flow changes in future versions, especially around:
id_product_attribute;add_to_cart_url;displayProductActions.If PrestaShop exposes a reusable public API for the product-page presentation in the future, it should be preferred over this manual reconstruction.
Fragment parsing
Dynamic fragments are detected directly from the final HTML without re-serializing the whole document through
DOMDocument, preserving the original response markup.The parser handles nested elements and text-content elements such as:
scriptstyletextareatitleso tag-like text inside their content cannot incorrectly terminate a dynamic fragment.
For example, a literal
</div>inside atextareais treated as text and cannot truncate the surroundingproduct-add-to-cartfragment.Safety / fallback
A block explicitly marked with
data-ps-fragmentis considered dynamic.If a supported fragment cannot be safely converted to ESI, the response is marked as non-cacheable instead of storing the original dynamic HTML in the public full-page cache.
The same fallback is applied for invalid/ambiguous fragment markup or when ESI injection is unavailable.
Themes without these markers keep the existing behavior.
Manual testing
The implementation has been manually tested on a real PrestaShop installation using LiteSpeed full-page cache, including both cache MISS and HIT responses.
The tested scenarios include:
MISS → HITproduct page caching;displayProductActions;textareacontent containing a literal</div>inside the dynamic fragment;First Page Only;In these tests, the main product page remained cacheable while the dynamic fragments correctly reflected the current cart/session context.