Skip to content

Commit

Permalink
Implemented {else} to {if} (#2)
Browse files Browse the repository at this point in the history
* Added Test for if/else

* Added else construction
  • Loading branch information
dermatthes authored Jul 26, 2017
1 parent 0ec1a10 commit 210c8e7
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/.idea
/vendor
/test/output
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ TextTemplate supports infinite-nested loops and sequences.

// 1. Define the Template
$tplStr = <<<EOT

Hello World {= name }
{if name == "Matthias"}
Hallo {= name | capitalize }
{else}
You are not Matthias
{/if}

EOT;

// 2. Define the Data for the Template
Expand Down Expand Up @@ -67,6 +71,7 @@ _TextTemplate uses Phing to build the phar-archives and gzip them. Just execute




## Value injection

Use the value Tag
Expand All @@ -82,7 +87,6 @@ To access array elements or objects use "." to access sub-elements:
```
{= users.0.name}
```



### Adding Filters
Expand Down Expand Up @@ -166,6 +170,14 @@ Hello World

Limitation: Logical connections like OR / AND are not possible at the moment. Maybe in the future.

## Conditions (else)
```
{if someVarName == "SomeValue"}
Hello World
{else}
Goodbye World
{/if}
```

## Debugging the Parameters

Expand Down Expand Up @@ -196,6 +208,14 @@ And we got quite good results:



## Contributing

If you want to contribute, please send your Merge-Request or open
a gitlab ticket.

- __Bugs & Feature-Request:__ [GitHub Tickets](https://github.com/dermatthes/text-template/issues)


## About
Text-Template was written by Matthias Leuffen <http://leuffen.de>

103 changes: 71 additions & 32 deletions src/TextTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,20 @@ public function addFilter ($filterName, callable $filterFn) {
}


public function _replaceElseIf ($input) {
$lines = explode("\n", $input);
for ($li=0; $li < count ($lines); $li++) {
$lines[$li] = preg_replace_callback('/\{else\}/im',
function ($matches) use (&$nestingIndex, &$indexCounter, &$li) {
return "{/if}{if ::NL_ELSE_FALSE}";
},
$lines[$li]
);

}
return implode ("\n", $lines);
}

/**
* Tag-Nesting is done by initially adding an index to both the opening and the
* closing tag. (By the way some cleanup is done)
Expand Down Expand Up @@ -266,58 +280,83 @@ private function _getItemValue ($compName, $context) {
}


private function _runIf ($context, $content, $cmdParam, $softFail=TRUE) {
private function _runIf ($context, $content, $cmdParam, $softFail=TRUE, &$ifConditionDidMatch) {
//echo $cmdParam;
if ( ! preg_match('/([\"\']?.*?[\"\']?)\s*(==|<|>|!=)\s*([\"\']?.*[\"\']?)/i', $cmdParam, $matches))
return "!! Invalid command sequence: '$cmdParam' !!";

//print_r ($matches);

$comp1 = $this->_getItemValue(trim ($matches[1]), $context);
$comp2 = $this->_getItemValue(trim ($matches[3]), $context);

//decho $comp1 . $comp2;

$doIf = FALSE;
switch ($matches[2]) {
case "==":
$doIf = ($comp1 == $comp2);
break;
case "!=":
$doIf = ($comp1 != $comp2);
break;
case "<":
$doIf = ($comp1 < $comp2);
break;
case ">":
$doIf = ($comp1 > $comp2);
break;
$doIf = false;

if (trim ($cmdParam) == "::NL_ELSE_FALSE") {
// This is the {else} path of a if construction
if ($ifConditionDidMatch == false)
$doIf = true; // Run the block if

} else {

if ( ! preg_match('/([\"\']?.*?[\"\']?)\s*(==|<|>|!=)\s*([\"\']?.*[\"\']?)/i', $cmdParam, $matches)) {
return "!! Invalid command sequence: '$cmdParam' !!";
}

//print_r ($matches);

$comp1 = $this->_getItemValue(trim($matches[1]), $context);
$comp2 = $this->_getItemValue(trim($matches[3]), $context);

//decho $comp1 . $comp2;


switch ($matches[2]) {
case "==":
$doIf = ($comp1 == $comp2);
break;
case "!=":
$doIf = ($comp1 != $comp2);
break;
case "<":
$doIf = ($comp1 < $comp2);
break;
case ">":
$doIf = ($comp1 > $comp2);
break;
}
}

if ( ! $doIf)
return "";

$ifConditionDidMatch = true; // Skip further else / elseif execution
$content = $this->_parseBlock($context, $content, $softFail);
$content = $this->_parseValueOfTags($context, $content, $softFail);
return $content;

}

public function _runIfElse ($context, $content, $softFail=TRUE, &$ifConditionDidMatch) {
if ($ifConditionDidMatch == true)
return "";
$ifConditionDidMatch = true; // Skip further else / elseif execution
$content = $this->_parseBlock($context, $content, $softFail);
$content = $this->_parseValueOfTags($context, $content, $softFail);
return $content;
}


private function _parseBlock ($context, $block, $softFail=TRUE) {
// (?!\{): Lookahead Regex: Don't touch double {{
$result = preg_replace_callback('/\n?\{(?!=)(([a-z]+)[0-9]+)(.*?)\}(.*?)\n?\{\/\1\}/ism',
function ($matches) use ($context, $softFail) {
$command = $matches[2];
$cmdParam = $matches[3];
$content = $matches[4];
$ifConditionDidMatch = []; // Array with nesting-Levels
$result = preg_replace_callback('/\n?\{(?!=)((?<command>[a-z]+)(?<nestingLevel>[0-9]+))(?<cmdParam>.*?)\}(?<content>.*?)\n?\{\/\1\}/ism',
function ($matches) use ($context, $softFail, &$ifConditionDidMatch) {
$command = $matches["command"];
$cmdParam = $matches["cmdParam"];
$content = $matches["content"];
$nestingLevel = $matches["nestingLevel"];

switch ($command) {
case "for":
return $this->_runFor($context, $content, $cmdParam, $softFail);

case "if":
return $this->_runIf ($context, $content, $cmdParam, $softFail);
$ifConditionDidMatch[$nestingLevel] = false;
return $this->_runIf ($context, $content, $cmdParam, $softFail, $ifConditionDidMatch[$nestingLevel]);


default:
return "!! Invalid command: '$command' !!";
Expand Down Expand Up @@ -350,7 +389,7 @@ public function apply ($params, $softFail=TRUE) {
$text = $this->mTemplateText;

$context = $params;

$text = $this->_replaceElseIf($text);
$text = $this->_replaceNestingLevels($text);

$text = $this->_parseBlock($context, $text, $softFail);
Expand Down
4 changes: 4 additions & 0 deletions test/templates.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ use Tester\Assert;
\Tester\Environment::setup();


$in = "{ if xyz}{ if zzz}{=value}{ /if}{else}{/if}";
$tt = new TextTemplate();
$out = $tt->_replaceElseIf($in);
Assert::equal("{ if xyz}{ if zzz}{=value}{ /if}{/if}{if ::NL_ELSE_FALSE}{/if}", $out);

$in = "{ if xyz}{ if zzz}{=value}{ /if}{/if}";
$tt = new TextTemplate();
Expand Down
5 changes: 5 additions & 0 deletions test/unit/tpls/07_if_else/_in.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [
"boolVal" => TRUE
];
12 changes: 12 additions & 0 deletions test/unit/tpls/07_if_else/_in.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
1: Start
{if boolVal == TRUE}
2: Boolean is true
{else}
3: Some Line of Code
{/if}
{if boolVal == FALSE}
4: Boolean is true
{else}
5: Some Line of Code
{/if}
6: Some other text
5 changes: 5 additions & 0 deletions test/unit/tpls/07_if_else/out.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
1: Start
2: Boolean is true
3: Some Line of Code
5: Some Line of Code
6: Some other text

0 comments on commit 210c8e7

Please sign in to comment.