@@ -166,7 +166,6 @@ public static function createContext(mixed $context, array $options, array $comp
166166 partials: $ parentCx ->partials ,
167167 depths: $ parentCx ->depths ,
168168 data: $ root ,
169- partialId: $ parentCx ->partialId ,
170169 frame: $ parentCx ->frame ,
171170 );
172171 }
@@ -366,17 +365,33 @@ public static function merge(mixed $a, mixed $b): mixed
366365 * @param array<string, mixed> $hash named hash overrides merged into the context
367366 * @param string $indent whitespace to prepend to each line of the partial's output
368367 */
369- public static function p (RuntimeContext $ cx , string $ name , mixed $ context , array $ hash , int $ pid , string $ indent ): string
368+ public static function p (RuntimeContext $ cx , string $ name , mixed $ context , array $ hash , ? \ Closure $ partialBlock , string $ indent ): string
370369 {
371- $ pp = ($ name === '@partial-block ' ) ? $ name . ($ pid > 0 ? $ pid : $ cx ->partialId ) : $ name ;
372-
373- $ fn = $ cx ->partials [$ pp ] ?? null ;
370+ $ fn = $ cx ->partials [$ name ] ?? null ;
374371 if ($ fn === null ) {
375372 throw new \Exception ("The partial $ name could not be found " );
376373 }
377374
378- $ savedPartialId = $ cx ->partialId ;
379- $ cx ->partialId = ($ name === '@partial-block ' ) ? ($ pid > 0 ? $ pid : ($ cx ->partialId > 0 ? $ cx ->partialId - 1 : 0 )) : $ pid ;
375+ if ($ partialBlock !== null ) {
376+ $ currentBlock = $ cx ->partials ['@partial-block ' ] ?? null ;
377+ $ cx ->partials ['@partial-block ' ] = static function (mixed $ blockContext = null ) use ($ partialBlock , $ currentBlock ): string {
378+ $ callingCx = self ::$ partialContext ;
379+ assert ($ callingCx !== null );
380+ $ saved = $ callingCx ->partials ['@partial-block ' ] ?? null ;
381+ if ($ currentBlock !== null ) {
382+ $ callingCx ->partials ['@partial-block ' ] = $ currentBlock ;
383+ } else {
384+ unset($ callingCx ->partials ['@partial-block ' ]);
385+ }
386+ $ result = $ partialBlock ($ blockContext );
387+ if ($ saved !== null ) {
388+ $ callingCx ->partials ['@partial-block ' ] = $ saved ;
389+ } else {
390+ unset($ callingCx ->partials ['@partial-block ' ]);
391+ }
392+ return $ result ;
393+ };
394+ }
380395
381396 $ context = $ hash ? static ::merge ($ context , $ hash ) : $ context ;
382397 $ prev = self ::$ partialContext ;
@@ -385,8 +400,14 @@ public static function p(RuntimeContext $cx, string $name, mixed $context, array
385400 $ result = $ fn ($ context );
386401 } finally {
387402 self ::$ partialContext = $ prev ;
403+ if ($ partialBlock !== null ) {
404+ if ($ currentBlock !== null ) {
405+ $ cx ->partials ['@partial-block ' ] = $ currentBlock ;
406+ } else {
407+ unset($ cx ->partials ['@partial-block ' ]);
408+ }
409+ }
388410 }
389- $ cx ->partialId = $ savedPartialId ;
390411
391412 if ($ indent !== '' ) {
392413 $ lines = explode ("\n" , $ result );
@@ -425,23 +446,7 @@ public static function inFallback(RuntimeContext $cx, string $name, \Closure $pa
425446 */
426447 public static function in (RuntimeContext $ cx , string $ name , \Closure $ partial ): string
427448 {
428- if (str_starts_with ($ name , '@partial-block ' )) {
429- // Capture the outer partialId at registration time so that when this
430- // block closure runs, any {{>@partial-block}} inside it resolves to
431- // the correct outer partial block rather than following the pid-decrement chain.
432- $ outerPartialId = $ cx ->partialId ;
433- $ cx ->partials [$ name ] = function (mixed $ context = null , array $ options = []) use ($ partial , $ outerPartialId ): string {
434- $ callingCx = self ::$ partialContext ;
435- assert ($ callingCx !== null );
436- $ savedId = $ callingCx ->partialId ;
437- $ callingCx ->partialId = $ outerPartialId ;
438- $ result = $ partial ($ context , $ options );
439- $ callingCx ->partialId = $ savedId ;
440- return $ result ;
441- };
442- } else {
443- $ cx ->partials [$ name ] = $ partial ;
444- }
449+ $ cx ->partials [$ name ] = $ partial ;
445450 return '' ;
446451 }
447452
0 commit comments