- Fixed a bug that appeared deeper when rendering a block inside the slot of another block
This commit is contained in:
		
							parent
							
								
									934643214e
								
							
						
					
					
						commit
						d22d26c9c8
					
				| @ -8,17 +8,22 @@ class BlockToken implements ControlStructure { | ||||
| 
 | ||||
|     public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token, array $options = []) : string | ||||
|     { | ||||
|         static $depth = 0; | ||||
|         static $slotDefinitions = []; | ||||
| 
 | ||||
|         # dump($depth, $token, $arguments, $slotDefinitions);
 | ||||
| 
 | ||||
|         switch($token) { | ||||
|             case "block": | ||||
|                 $slotDefinitions[] = $this->slotDefinitions(); | ||||
|                  | ||||
|                 $depth++; | ||||
| 
 | ||||
|                 return "<?php \$___block = \Picea\ControlStructure\BlockToken::instanciateBlock($arguments); ?>"; | ||||
|              | ||||
| 
 | ||||
|             case "endblock": | ||||
|                 $depth--; | ||||
|                 return "<?php echo \$___block->render(\$___class__template); unset(\$___block); ?>"; | ||||
|              | ||||
| 
 | ||||
|             case "arguments": | ||||
|                 $class = static::class; | ||||
| 
 | ||||
| @ -36,19 +41,19 @@ class BlockToken implements ControlStructure { | ||||
|                         } | ||||
|                     /*%EXCEPTION_LINE_BASE%*/?>
 | ||||
|                 PHP; | ||||
|              | ||||
| 
 | ||||
|             case "define": | ||||
|                 list($name, $definition) = array_pad(explode(',', $arguments, 2), 2, ""); | ||||
|                  | ||||
|                 end($slotDefinitions)->setDefinition(eval("return $name;"), $definition); | ||||
|                  | ||||
| 
 | ||||
|                 ( $slotDefinitions[$depth] ?? end($slotDefinitions) )->setDefinition(eval("return $name;"), $definition); | ||||
| 
 | ||||
|                 return <<<PHP | ||||
|                 <?php \$this->defineSlot($name, function($definition) {}); ?>
 | ||||
|                 PHP; | ||||
|                      | ||||
| 
 | ||||
|             case "slot": | ||||
|                 $def = end($slotDefinitions); | ||||
|                  | ||||
|                 $def = ( $slotDefinitions[$depth] ?? end($slotDefinitions) ); | ||||
| 
 | ||||
|                 list($name, $definition) = array_pad(explode(',', $arguments, 2), 2, ""); | ||||
| 
 | ||||
|                 $loops = count($context->iterationStack ?? []) ? ",". implode(', ', array_filter(array_column($context->iterationStack, 'uid'), fn($e) => strpos($e, '[') === false)) : null; | ||||
| @ -57,7 +62,7 @@ class BlockToken implements ControlStructure { | ||||
|                     $slotName = eval("return $name;"); | ||||
|                     $def->currentSlot = $slotName; | ||||
|                     $def->setDefinitionVars($slotName, $definition); | ||||
|                      | ||||
| 
 | ||||
|                     $definition = $def->printDefinition($slotName); | ||||
| 
 | ||||
|                     if ($definition) { | ||||
| @ -72,18 +77,18 @@ class BlockToken implements ControlStructure { | ||||
|                     if ($definition) { | ||||
|                         $definition .= ","; | ||||
|                     } | ||||
|                      | ||||
| 
 | ||||
|                     return <<<PHP | ||||
|                     <?php (\$___block ?? \$this)->slotIsSet($name) || \$___block->setSlot($name, function($definition array \$___using = []) use (\$picea $loops) { extract(\$___using, \EXTR_SKIP); ?>
 | ||||
|                     <?php (\$___block ?? \$this)->slotIsSet($name) || (\$___block ?? \$this)->setSlot($name, function($definition array \$___using = []) use (\$picea $loops) { extract(\$___using, \EXTR_SKIP); ?>
 | ||||
|                     PHP; | ||||
|                 } | ||||
|                      | ||||
| 
 | ||||
|             case "endslot": | ||||
|                 $def =end($slotDefinitions); | ||||
|                  | ||||
|                 $def = ( $slotDefinitions[$depth] ?? end($slotDefinitions) ); | ||||
| 
 | ||||
|                 if ($def->hasDefinitions() ) { | ||||
|                     $definition = $def->getCurrentSlotDefinitionVars(); | ||||
|                      | ||||
| 
 | ||||
|                     if ($definition) { | ||||
|                         $definition .= ","; | ||||
|                     } | ||||
| @ -95,23 +100,23 @@ class BlockToken implements ControlStructure { | ||||
|                 else { | ||||
|                     return "<?php }); ?>"; | ||||
|                 } | ||||
|                  | ||||
| 
 | ||||
|             case "using": | ||||
|                 return "<?php \$___block->setUsing($arguments); ?>"; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|      | ||||
| 
 | ||||
| 
 | ||||
|     public function inlineHtml(? object $proxy, string $viewPath, ... $variables) { | ||||
|         return $this->renderHtml($viewPath, [ 'inlineVariables' => $variables ], $proxy); | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     public static function parseSlotArguments(Callable $method) : array | ||||
|     { | ||||
|         #return 
 | ||||
|         #return
 | ||||
|     } | ||||
|          | ||||
|          | ||||
| 
 | ||||
| 
 | ||||
|     public static function parseArguments(Callable $method, array $arguments) : array | ||||
|     { | ||||
|         try{ | ||||
| @ -119,10 +124,10 @@ class BlockToken implements ControlStructure { | ||||
|         } | ||||
|         catch(\TypeError $ex) { | ||||
|             throw $ex; | ||||
|         }  | ||||
|          | ||||
|         } | ||||
| 
 | ||||
|         $parameters = []; | ||||
|          | ||||
| 
 | ||||
|         foreach((new \ReflectionFunction($method))->getParameters() as $key => $value) { | ||||
|             if ( isset($arguments[$key]) ) { | ||||
|                 $parameters[ $value->getName() ] = $arguments[$key]; | ||||
| @ -137,114 +142,114 @@ class BlockToken implements ControlStructure { | ||||
|                 $parameters[ $value->getName() ] = null; | ||||
|             } | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         return $parameters; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     public static function slotDefinitions() { | ||||
|         return new class() { | ||||
|              | ||||
| 
 | ||||
|             public array $definitions = []; | ||||
|              | ||||
| 
 | ||||
|             public array $variables = []; | ||||
|              | ||||
| 
 | ||||
|             public bool $rendering = false; | ||||
|              | ||||
| 
 | ||||
|             public string $currentSlot; | ||||
|              | ||||
|             public function setDefinition(string $name, string $definition) : self  | ||||
| 
 | ||||
|             public function setDefinition(string $name, string $definition) : self | ||||
|             { | ||||
|                 $this->definitions[$name] = $definition; | ||||
|                  | ||||
| 
 | ||||
|                 return $this; | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function setDefinitionVars(string $name, string $variables) : self | ||||
|             { | ||||
|                 $this->variables[$name] = $variables; | ||||
|                  | ||||
| 
 | ||||
|                 return $this; | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function getDefinitionVars(string $name) : string | ||||
|             { | ||||
|                 return $this->variables[$name] ?? ""; | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function getCurrentSlotDefinitionVars() : string | ||||
|             { | ||||
|                 return $this->getDefinitionVars($this->currentSlot); | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function hasDefinitions() : bool | ||||
|             { | ||||
|                 return count($this->definitions) > 0; | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function printDefinition(string $name) : string | ||||
|             { | ||||
|                 if ( ! isset($this->definitions[$name]) ) { | ||||
|                     throw new \Exception("Slot definition for `$name` was not found. Have you defined it in your block header using something like '{% define \"$name\", ...\$arguments %}' ?");
 | ||||
|                 } | ||||
|                  | ||||
| 
 | ||||
|                 return $this->definitions[$name]; | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function render() : void | ||||
|             { | ||||
|                 $this->rendering = true; | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|      | ||||
|     public static function instanciateBlock(string $viewPath, ... $arguments)  | ||||
| 
 | ||||
|     public static function instanciateBlock(string $viewPath, ... $arguments) | ||||
|     { | ||||
|         return new class($viewPath, ...$arguments) { | ||||
|              | ||||
| 
 | ||||
|             public bool $rendering = false; | ||||
|              | ||||
| 
 | ||||
|             public string $viewPath; | ||||
|              | ||||
| 
 | ||||
|             public array $using = []; | ||||
|              | ||||
| 
 | ||||
|             public array $arguments = []; | ||||
|              | ||||
| 
 | ||||
|             public array $slots = []; | ||||
|              | ||||
| 
 | ||||
|             public array $definition = []; | ||||
|              | ||||
| 
 | ||||
|             public function __construct(string $viewPath, ...$arguments) { | ||||
|                 $this->viewPath = $viewPath; | ||||
|                 $this->arguments = $arguments; | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function render(object $classTemplate) : string | ||||
|             { | ||||
|                 $this->rendering = true; | ||||
| 
 | ||||
|                 return $classTemplate->picea->inlineBlock($this, $this->viewPath, ...$this->arguments); | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function setSlot(string $name, Callable $method) : void | ||||
|             { | ||||
|                 $this->slots[$name] = $method; | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function defineSlot(string $name, Callable $method) : void | ||||
|             { | ||||
|                 $this->definition[$name] = $method; | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function slotIsSet(string $name) : bool | ||||
|             { | ||||
|                 return ! empty($this->slots[$name]); | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function printSlot(string $name, Callable $default) | ||||
|             { | ||||
|                 return $this->slotIsSet($name) ? $this->slots[$name] : $default; | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             public function setUsing(array $variables) { | ||||
|                 $this->using = $variables; | ||||
|             } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user