diff --git a/Attributes/NFor.php b/Attributes/NFor.php index 661ad30..05eafdd 100644 --- a/Attributes/NFor.php +++ b/Attributes/NFor.php @@ -55,16 +55,11 @@ private function generateCurrentContext(int $iterator):void } private function sequentialContext(string $key, array $value): void { - $finalInner = []; - foreach ($value as $existingKey => $existingValue){ - $finalInner = [ - $existingKey => $existingValue - ]; - if(count($this->currentDeclaration)>1){ - $finalInner[$this->currentDeclaration[0]] = $key; - } + + if(count($this->currentDeclaration)>1){ + $this->contextData[$this->currentDeclaration[0]] = $key; } - $this->contextData[end($this->currentDeclaration)] = $finalInner; + $this->contextData[end($this->currentDeclaration)] = $value; } private function assocContext(string $key, mixed $value):void { @@ -88,7 +83,6 @@ function __invoke(\DOMAttr &$attr, $contextData = []): void for ($i = 0; $i < $iterations; $i++) { $this->generateCurrentContext($i); - $newDoc = new Interpreter($attr->ownerDocument->saveHTML($clone), $this->contextData, true); $html = $newDoc->asHtml(); if(!empty(trim($html))){ diff --git a/Interpreter.php b/Interpreter.php index 48beb6d..fdb553f 100644 --- a/Interpreter.php +++ b/Interpreter.php @@ -80,7 +80,7 @@ private function getFragmentCompletions(): array */ private function ensureEncoding(string $html): string { - if(!$this->skipEncoding && !strpos($html, '')){ + if(!$this->skipEncoding && !str_contains($html, '')){ $partial = $this->getFragmentCompletions(); $this->isFragment = true; $html = $partial[0] .$html . $partial[1]; @@ -115,17 +115,24 @@ function stepThrough(DOMNodeList $nodes): void // attributes? if($child->hasAttributes()){ $this->handleAttributes($child); - // attribute functions? } // IS delimiter? - if(Constants::delimiterIsTag() && $child->tagName === substr(Constants::getDelimiter()[0],1,-1) && isset($this->flatData[trim($child->textContent)])){ - $child->nodeValue = $this->flatData[trim($child->textContent)]; - } + $this->handleDelimiterIsTag($child); + } if($child instanceof DOMText && trim($child->nodeValue) !== ''){ $this->handleTextNode($child); } - $this->stepThrough($child->childNodes); + if($child->hasChildNodes()){ + $this->stepThrough($child->childNodes); + } + } + } + + function handleDelimiterIsTag(DOMElement $node): void + { + if(Constants::delimiterIsTag() && $node->tagName === substr(Constants::getDelimiter()[0],1,-1) && isset($this->flatData[trim($node->textContent)])){ + $node->nodeValue = $this->flatData[trim($node->textContent)]; } } @@ -136,9 +143,24 @@ function stepThrough(DOMNodeList $nodes): void function handleTextNode(DOMText $node): void { // readDelimiter - $node->nodeValue = $this->readDelimiter($node->nodeValue); - // handle functions - $this->handleFunctions($node); + $givenValue = $this->readDelimiter($node->nodeValue); + if($givenValue !== strip_tags($givenValue)){ + $this->appendAsFragment($node, $givenValue); + } else { + $node->nodeValue = $this->readDelimiter($node->nodeValue); + // handle functions + $this->handleFunctions($node); + } + + } + + private function appendAsFragment(DOMText $parentNode, string $htmlPartial): void + { + $subDoc = new Interpreter($htmlPartial, $this->contextData); + $fragment = $this->doc->createDocumentFragment(); + $fragment->appendXML($subDoc->asHtml()); + $parentNode->nodeValue = ''; + $parentNode->parentNode->appendChild($fragment); } /** @@ -152,14 +174,18 @@ function handleFunctions(DOMText $element): void $pattern = "/({$delimiter[0]}.*)*$function\(([^)]*)\)(.*{$delimiter[1]})*/"; $hit = preg_match_all($pattern, $element->nodeValue, $matches, PREG_SET_ORDER); if($hit){ - foreach($matches as $match){ - if(!empty($match[2]) && array_key_exists($match[2],$this->flatData)){ - $element->nodeValue = str_replace($match[0], $closure($this->flatData[$match[2]]), $element->nodeValue); - } elseif (empty($match[2])){ - $element->nodeValue = str_replace($match[0], $closure(), $element->nodeValue); - } - } + $this->executeFunction($closure, $matches, $element); + } + } + } + private function executeFunction(callable $callable, $matches, $element): void + { + foreach($matches as $match){ + if(!empty($match[2]) && array_key_exists($match[2],$this->flatData)){ + $element->nodeValue = str_replace($match[0], $callable($this->flatData[$match[2]]), $element->nodeValue); + } elseif (empty($match[2])){ + $element->nodeValue = str_replace($match[0], $callable(), $element->nodeValue); } } } @@ -206,6 +232,7 @@ function readDelimiter(string $string): string if($found){ $string = $this->replaceVariables($matches, $string); + } return $string; } @@ -218,7 +245,7 @@ function readDelimiter(string $string): string private function replaceVariables(array $matches, string $content): string { foreach ($matches as $pair){ - if(isset($this->flatData[trim($pair[1])])){ + if(array_key_exists(trim($pair[1]), $this->flatData)){ $content = str_replace($pair[0], $this->flatData[trim($pair[1])], $content); } } diff --git a/README.md b/README.md index 7b88e38..2aff348 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ echo Template::embrace('
{{item}} {{name}}
+{{name}}
+{{name}}
+one John
+two John
+{{item}} {{name}}
+{{name}}
+{{items}}
+{{items.0}}
+{{items.length}}
+{{deepAssoc.name}}
+``` +output: +```html +Array
+one
+2
+Tim
+``` +If needed, you can use this in logic: +```html +{{umlaut}}
-{{some}}
-{{umlaut}}
+{{some}}
+