Render the order product line hook on every order product line - #1105
Conversation
An order product line had no extension point in the front office, only the page level displayOrderDetail hook, so a module could not show information next to one product of an order. Call displayOrderDetailProductLine at the end of the product cell of every line, where the reference, the virtual product note and the carrier note already are. It receives identifiers only - the order, the order detail row and the product - all of which the presented product already carries, so the partials stay self contained. The theme renders a product line from four places: the two single shipment templates hold the row inline and the two line partials are used by the multishipment ones, so the call goes in all four.
|
✅ QA: approved. Tested on PrestaShop 9.3.0, PHP 8.1.33, Hummingbird 2.1.0, front office. A throwaway module registered on
Which template rendered was confirmed on the page and against the Smarty compile cache, not assumed from the fixture. The listener output appears under the product name on every line, and no line received it twice. Order history, order detail and merchandise returns still answer and render; no console or network errors during the pass. Not covered: the merge base was not measured, so nothing here is a before and after comparison; the hook is not yet declared in core, so it was created by |




displayOrderDetailProductLinehook on every product line of the order detail page, so a module can show information next to one product of an order.Why
The order detail page has one hook,
displayOrderDetail, and it is executed once for the whole pagewith the order as its only parameter. Nothing receives a single product line, so a module cannot show
information next to one product.
What it does
One
{hook h='displayOrderDetailProductLine' ...}at the end oforder-product__content, where thereference, the virtual product note and the carrier note already are. It passes identifiers only -
$product.id_order,$product.id_order_detail,$product.id_product- all three of which thepresented product row already carries (
Order::getProductsDetail()selectsod.*), so the partialsstay self contained and nothing new has to be threaded through the includes.
Four call sites, because the theme renders a product line from four places. The two line
partials,
order-detail-product-line-no-return.tplandorder-detail-product-line-return.tpl, areused only by the two multishipment templates;
order-detail-no-return.tplandorder-detail-return.tplhold the row inline instead. Adding the call to the partials alone wouldhave given a hook that fires only on a multishipment order.
Each line still renders from exactly one of those four sites, so a listener fires once per order
line here. On classic it fires twice, because that theme renders every line in both a
hidden-sm-downand a
hidden-md-upblock. A listener therefore has to be idempotent and must not emit fixedidornameattributes - stated on the classic branch as well, and worth carrying into the devdocs entry.How to test
Register a module on
displayOrderDetailProductLinethat returns some markup fromhookDisplayOrderDetailProductLine($params), then open an order under Your account > Order history >Details. The markup appears under the product name of every line and
$paramscarries the threeidentifiers of that line. It should appear whether or not the order is returnable and whether or not
it has shipments.
Measured on a running 9.2 shop
A probe module returning
<!--PROBE-FO id_order=... id_order_detail=... id_product=...-->wasinstalled and registered on the hook, this theme's four templates were deployed with a per-site
marker, and the order detail page was fetched over HTTP as a logged in customer owning a two product
order:
inline-no-returnis the one the real selection reaches on that order(
$order.details.is_returnablefalse, no shipments). The other three were forced by temporarilyincluding them from
order-detail.tpl, which proves each template compiles and emits the hook withthe right identifiers, but not that the selection reaches them - that needs a returnable order and a
shipment fixture.
Everything was put back afterwards: the five deployed templates restored and checked by md5, the
probe module uninstalled and deleted with its hook rows, the probe customer and its
ps_customer_group/ps_customer_session/ps_guest/ps_cart/ps_psgdpr_logrows deleted,ps_orders.id_customerfor the test order set back, andPS_ORDER_RETURNset back to 0.Notes for publishing
order-detail-return.tpl. Both were hunk-checked: Emit only the srcset candidates whose image type exists #1103 touches the licence header and the two<picture>blocks (hunks ending around lines 71 to 100), Adopt the data-ps-* convention across the theme #1096 touches line 3, and the four linesadded here are at 116, 118, 125 and 128. Nothing overlaps, so either order merges.
order-detail-no-return.tplis a copy oforder-detail-product-line-no-return.tpl: 121 duplicatedlines, and the copy has drifted - the partial renders the "Virtual product(s): No delivery service"
note and the inline row does not, so that note appears on a multishipment order's detail page and
not on a single shipment one. Replacing the inline rows with an
{include}of the partials wouldremove the duplication, fix the drift, and reduce this hook to two call sites - but it is a 121 line
structural change to files that Emit only the srcset candidates whose image type exists #1103 and Adopt the data-ps-* convention across the theme #1096 are both editing, so it does not belong in the same
PR as a one line hook call.