From 3c15589fb80807017c326e6487ad97075533d1f1 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 17 Oct 2023 03:28:20 +0900 Subject: [PATCH] Allow loops and conditions to appear anywhere in a line --- .../parsers/template/TemplateParser_v2.php | 24 ++++++++++++++----- tests/_data/template/v2example.html | 6 ++--- tests/_data/template/v2result1.php | 8 +++---- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/common/framework/parsers/template/TemplateParser_v2.php b/common/framework/parsers/template/TemplateParser_v2.php index 9f00a3ac2..7d9745185 100644 --- a/common/framework/parsers/template/TemplateParser_v2.php +++ b/common/framework/parsers/template/TemplateParser_v2.php @@ -616,13 +616,12 @@ class TemplateParser_v2 * Convert loop and condition directives. * * Loops and conditions can be written inside HTML comments (XE-style) - * or without comments (Blade-style). If using the Blade-style syntax, - * each directive must appear in its own line. + * or without comments (Blade-style). * * It is highly recommended that ending directives match the starting * directive, e.g. @if ... @endif. However, for compatibility with legacy * templates, Rhymix will automatically find out which loop you are - * trying to end if you simply write @end. Either way, your loops must + * trying to close if you simply write @end. Either way, your loops must * balance out or you will see 'unexpected end of file' errors. * * XE-style syntax: @@ -638,13 +637,26 @@ class TemplateParser_v2 */ protected function _convertLoopDirectives(string $content): string { - // Convert block directives. - $regexp = '#(?:^[\x09\x20]*||[\x09\x20]*$)#sm'; + // Generate the list of directives to match. + foreach (self::$_loopdef as $directive => $def) + { + $directives[] = $directive; + if (count($def) > 1) + { + $directives[] = 'end' . $directive; + } + } + usort($directives, function($a, $b) { return strlen($b) - strlen($a); }); + $directives = implode('|', $directives) . '|end'; + + // Convert both XE-style and Blade-style directives. + $parentheses = self::_getRegexpForParentheses(2); + $regexp = '#(?:)?#'; $content = preg_replace_callback($regexp, function($match) { // Collect the necessary information. $directive = $match[1]; - $args = isset($match[2]) ? self::_convertVariableScope($match[2]) : ''; + $args = isset($match[2]) ? self::_convertVariableScope(substr($match[2], 1, strlen($match[2]) - 2)) : ''; $stack = null; $code = null; diff --git a/tests/_data/template/v2example.html b/tests/_data/template/v2example.html index c96d19c91..85a019ec0 100644 --- a/tests/_data/template/v2example.html +++ b/tests/_data/template/v2example.html @@ -23,7 +23,7 @@
@if ($foo || $bar) -

Hello {$foo|noescape}

+

Hello @if ($bar){$foo|noescape}@endif

{{ implode('|', array_map(function(\$i) { return strtoupper(\$i); }, $bar)) }}

@end
@@ -35,9 +35,7 @@ = 2)-->class="{$val}"> @endempty -@empty -
Nothing here...
-@end +@empty
Nothing here...
@end @each('incl/eachtest', $bar, 'var') @each('incl/eachtest', [], 'anything', 'incl/empty') diff --git a/tests/_data/template/v2result1.php b/tests/_data/template/v2result1.php index fcd62a626..f29218d01 100644 --- a/tests/_data/template/v2result1.php +++ b/tests/_data/template/v2result1.php @@ -23,21 +23,19 @@ baz))): ?> class="foobar"> foo || $__Context->bar): ?> -

Hello foo ?? ''; ?>

+

Hello bar): ?>foo ?? ''; ?>

bar)), \ENT_QUOTES, 'UTF-8', false); ?>

-k => $__Context->val): ?> +k => $__Context->val): ?>
nosuchvar)): ?> unit tests are cool k >= 2): ?>class="val ?? '', \ENT_QUOTES, 'UTF-8', false); ?>">
- -
Nothing here...
- +
Nothing here...
setVars([(string)$__varname => $__var]); echo $__tpl->compile(); endforeach; })($this->relative_dirname, 'incl/eachtest', $__Context->bar, 'var'); ?> setVars([(string)$__varname => $__var]); echo $__tpl->compile(); endforeach; })($this->relative_dirname, 'incl/eachtest', [], 'anything', 'incl/empty'); ?>