Added full support and documentation for ternary operator.

Fixes #881
This commit is contained in:
Simon Wisselink
2023-05-01 23:25:42 +02:00
parent cea303d0ad
commit 81cda9e363
8 changed files with 808 additions and 708 deletions

View File

@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added support for PHP8.2
- Added a new way to extend Smarty functionality using `Smarty::addExtension()`
- Full support for ternary `{$test ? $a : $b}` and `{$var ?: $alternative}` [#881](https://github.com/smarty-php/smarty/issues/881)
### Changed
- All Smarty code is now in the \Smarty namespace. For simple use-cases, you only need to add

View File

@@ -26,8 +26,8 @@ The basis components of the Smarty syntax are:
- [Comments](language-syntax-comments.md)
- [Variables](language-syntax-variables.md)
- [Operators](language-syntax-operators.md)
- [Functions](language-syntax-functions.md)
- [Attributes](language-syntax-attributes.md)
- [Quotes](language-syntax-quotes.md)
- [Math](language-math.md)
- [Escaping](language-escaping.md)

View File

@@ -1,28 +0,0 @@
# Math
Math can be applied directly to variable values.
## Examples
```smarty
{$foo+1}
{$foo*$bar}
{* some more complicated examples *}
{$foo->bar-$bar[1]*$baz->foo->bar()-3*7}
{if ($foo+$bar.test%$baz*134232+10+$b+10)}
{$foo|truncate:"`$fooTruncCount/$barTruncFactor-1`"}
{assign var="foo" value="`$foo+$bar`"}
```
> **Note**
>
> Although Smarty can handle some very complex expressions and syntax,
> it is a good rule of thumb to keep the template syntax minimal and
> focused on presentation. If you find your template syntax getting too
> complex, it may be a good idea to move the bits that do not deal
> explicitly with presentation to PHP by way of plugins or modifiers.

View File

@@ -0,0 +1,50 @@
# Operators
## Basic
Various basic operators can be applied directly to variable values.
## Examples
```smarty
{$foo + 1}
{$foo * $bar}
{$foo->bar - $bar[1] * $baz->foo->bar() -3 * 7}
{if ($foo + $bar.test % $baz * 134232 + 10 + $b + 10)}
...
{/if}
{$foo = $foo + $bar}
```
> **Note**
>
> Although Smarty can handle some very complex expressions and syntax,
> it is a good rule of thumb to keep the template syntax minimal and
> focused on presentation. If you find your template syntax getting too
> complex, it may be a good idea to move the bits that do not deal
> explicitly with presentation to PHP by way of plugins or modifiers.
## Ternary
You can use the `?:` (or ternary) operator to test one expression and present the value
of the second or third expression, based on the result of te test.
In other words:
```smarty
{$test ? "OK" : "FAIL"}
```
will result in OK if `$test` is set to true, and in FAIL otherwise.
There is also a shorthand `?:` operator:
```smarty
{$myVar ?: "empty"}
```
will result in 'empty' if `$myVar` is not set or set to something that evaluates to false, such as an empty string.
If `$myVar` is set to something that evaluates to true, the value of `$myVar` is returned. So, the following will
return 'hello':
```smarty
{$myVar="hello"}
{$myVar ?: "empty"}
```

File diff suppressed because it is too large Load Diff

View File

@@ -672,14 +672,23 @@ expr(res) ::= expr(e1) ISIN value(v). {
//
// ternary
//
ternary(res) ::= OPENP expr(v) CLOSEP QMARK DOLLARID(e1) COLON expr(e2). {
ternary(res) ::= expr(v) QMARK DOLLARID(e1) COLON expr(e2). {
res = v.' ? '. $this->compiler->compileVariable('\''.substr(e1,1).'\'') . ' : '.e2;
}
ternary(res) ::= OPENP expr(v) CLOSEP QMARK expr(e1) COLON expr(e2). {
ternary(res) ::= expr(v) QMARK value(e1) COLON expr(e2). {
res = v.' ? '.e1.' : '.e2;
}
ternary(res) ::= expr(v) QMARK expr(e1) COLON expr(e2). {
res = v.' ? '.e1.' : '.e2;
}
// shorthand ternary
ternary(res) ::= expr(v) QMARK COLON expr(e2). {
res = v.' ?: '.e2;
}
// value
value(res) ::= variable(v). {
res = v;

View File

@@ -100,7 +100,7 @@ class PHPUnit_Smarty extends PHPUnit\Framework\TestCase
*
* @param null $dir working directory
*/
public function setUpSmarty($dir = null)
public function setUpSmarty($dir)
{
static $s_dir;
// set up current working directory

View File

@@ -0,0 +1,41 @@
<?php
class TernaryTest extends PHPUnit_Smarty {
public function setUp(): void
{
$this->setUpSmarty('/tmp');
$this->cleanDirs();
}
public function testTernaryTrue() {
$tpl = $this->smarty->createTemplate('string:{$a ? $b : $c}');
$tpl->assign('a', true);
$tpl->assign('b', 'B');
$tpl->assign('c', 'C');
$this->assertEquals('B', $this->smarty->fetch($tpl));
}
public function testTernaryFalse() {
$tpl = $this->smarty->createTemplate('string:{$a ? $b : $c}');
$tpl->assign('a', false);
$tpl->assign('b', 'B');
$tpl->assign('c', 'C');
$this->assertEquals('C', $this->smarty->fetch($tpl));
}
public function testShorthandTernaryTrue() {
$tpl = $this->smarty->createTemplate('string:{$a ?: $c}');
$tpl->assign('a', true);
$tpl->assign('c', 'C');
$this->assertEquals(true, $this->smarty->fetch($tpl));
}
public function testShorthandTernaryFalse() {
$tpl = $this->smarty->createTemplate('string:{$a ? $b : $c}');
$tpl->assign('a', false);
$tpl->assign('c', 'C');
$this->assertEquals('C', $this->smarty->fetch($tpl));
}
}