mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-04 17:21:39 +09:00
Convert include code into a method of Template class
This commit is contained in:
parent
012dbb9ab7
commit
e044e11c5f
4 changed files with 77 additions and 114 deletions
|
|
@ -457,6 +457,63 @@ class Template
|
|||
* =================== HELPER FUNCTIONS FOR TEMPLATE v2 ===================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Include another template from v2 @include directive.
|
||||
*
|
||||
* Blade has several variations of the @include directive, and we need
|
||||
* access to the actual PHP args in order to process them accurately.
|
||||
* So we do this in the Template class, not in the converter.
|
||||
*
|
||||
* @param ...$args
|
||||
* @return string
|
||||
*/
|
||||
protected function _v2_include(...$args): string
|
||||
{
|
||||
// Set some basic information.
|
||||
$directive = $args[0];
|
||||
$extension = $this->extension === 'blade.php' ? 'blade.php' : null;
|
||||
$isConditional = in_array($directive, ['includeWhen', 'includeUnless']);
|
||||
$basedir = $this->relative_dirname;
|
||||
$cond = $isConditional ? $args[1] : null;
|
||||
$path = $isConditional ? $args[2] : $args[1];
|
||||
$vars = $isConditional ? ($args[3] ?? null) : ($args[2] ?? null);
|
||||
|
||||
// Handle paths relative to the Rhymix installation directory.
|
||||
if (preg_match('#^\^/?(\w.+)$#s', $path, $match))
|
||||
{
|
||||
$basedir = str_contains($match[1], '/') ? dirname($match[1]) : \RX_BASEDIR;
|
||||
$path = basename($match[1]);
|
||||
}
|
||||
|
||||
// If the conditions are not met, return.
|
||||
if ($isConditional && $directive === 'includeWhen' && !$cond)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
if ($isConditional && $directive === 'includeUnless' && $cond)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
// Create a new instance of TemplateHandler.
|
||||
$template = new self($basedir, $path, $extension);
|
||||
|
||||
// If the directive is @includeIf and the template file does not exist, return.
|
||||
if ($directive === 'includeIf' && !$template->exists())
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
// Set variables.
|
||||
if ($vars !== null)
|
||||
{
|
||||
$template->setVars($vars);
|
||||
}
|
||||
|
||||
// Compile and return.
|
||||
return $template->compile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a resource from v2 @load directive.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -374,58 +374,9 @@ class TemplateParser_v2
|
|||
$parentheses = self::_getRegexpForParentheses(2);
|
||||
$regexp = '#(?<!@)@(include(?:If|When|Unless)?)\x20?(' . $parentheses . ')#';
|
||||
$content = preg_replace_callback($regexp, function($match) {
|
||||
|
||||
// Convert the path if necessary.
|
||||
$match[2] = self::_convertVariableScope(substr($match[2], 1, strlen($match[2]) - 2));
|
||||
$extension = $this->template->extension === 'blade.php' ? 'blade.php' : 'html';
|
||||
$dir = '$this->relative_dirname';
|
||||
if ($match[1] === 'include' || $match[1] === 'includeIf')
|
||||
{
|
||||
$path = preg_match('#^([\'"])([^\'"]+)\1#', $match[2], $m) ? $m[2] : '';
|
||||
if (preg_match('#^\^/?(\w.+)$#s', $path, $mm))
|
||||
{
|
||||
$dir = '"' . escape_dqstr(str_contains($mm[1], '/') ? dirname($mm[1]) : '') . '"';
|
||||
$filename = basename($mm[1]);
|
||||
$match[2] = preg_replace('#^([\'"])([^\'"]+)\1#', '$1' . $filename . '$1', $match[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$path = preg_match('#^([^,]+,\s*)([\'"])([^\'"]+)\2#', $match[2], $m) ? $m[3] : '';
|
||||
if (preg_match('#^\^/?(\w.+)$#s', $path, $mm))
|
||||
{
|
||||
$dir = '"' . escape_dqstr(str_contains($mm[1], '/') ? dirname($mm[1]) : '') . '"';
|
||||
$filename = basename($mm[1]);
|
||||
$match[2] = preg_replace('#^([^,]+,\s*)([\'"])([^\'"]+)\2#', '$1$2' . $filename . '$2', $match[2]);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate an IIFE to create a new Template object and compile it.
|
||||
if ($match[1] === 'include')
|
||||
{
|
||||
$tpl = '<?php (function($__dir, $__path, $__vars = null) { ';
|
||||
$tpl .= '$__tpl = new \Rhymix\Framework\Template($__dir, $__path, "' . $extension . '"); ';
|
||||
$tpl .= 'if ($__vars) $__tpl->setVars($__vars); ' ;
|
||||
$tpl .= 'echo $__tpl->compile(); })(' . $dir . ', ' . $match[2] . '); ?>';
|
||||
}
|
||||
elseif ($match[1] === 'includeIf')
|
||||
{
|
||||
$tpl = '<?php (function($__dir, $__path, $__vars = null) { ';
|
||||
$tpl .= '$__tpl = new \Rhymix\Framework\Template($__dir, $__path, "' . $extension . '"); ';
|
||||
$tpl .= 'if (!$__tpl->exists()) return; ';
|
||||
$tpl .= 'if ($__vars) $__tpl->setVars($__vars); ' ;
|
||||
$tpl .= 'echo $__tpl->compile(); })(' . $dir . ', ' . $match[2] . '); ?>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$tpl = '<?php (function($__type, $__dir, $__cond, $__path, $__vars = null) { ';
|
||||
$tpl .= 'if ($__type === "includeWhen" && !$__cond) return; ';
|
||||
$tpl .= 'if ($__type === "includeUnless" && $__cond) return; ';
|
||||
$tpl .= '$__tpl = new \Rhymix\Framework\Template($__dir, $__path, "' . $extension . '"); ';
|
||||
$tpl .= 'if ($__vars) $__tpl->setVars($__vars); ' ;
|
||||
$tpl .= 'echo $__tpl->compile(); })("' . $match[1] . '", ' . $dir . ', ' . $match[2] . '); ?>';
|
||||
}
|
||||
return self::_escapeVars($tpl);
|
||||
$directive = trim($match[1]);
|
||||
$args = self::_convertVariableScope(substr($match[2], 1, strlen($match[2]) - 2));
|
||||
return sprintf("<?php echo \$this->_v2_include('%s', %s); ?>", $directive, $args);
|
||||
}, $content);
|
||||
|
||||
// Handle the @each directive.
|
||||
|
|
@ -435,23 +386,13 @@ class TemplateParser_v2
|
|||
|
||||
// Convert the path if necessary.
|
||||
$args = self::_convertVariableScope(substr($match[1], 1, strlen($match[1]) - 2));
|
||||
$extension = $this->template->extension === 'blade.php' ? 'blade.php' : 'html';
|
||||
$dir = '$this->relative_dirname';
|
||||
$path = preg_match('#^([\'"])([^\'"]+)\1#', $args, $m) ? $m[2] : '';
|
||||
if (preg_match('#^\^/?(\w.+)$#s', $path, $mm))
|
||||
{
|
||||
$dir = '"' . escape_dqstr(str_contains($mm[1], '/') ? dirname($mm[1]) : '') . '"';
|
||||
$filename = basename($mm[1]);
|
||||
$args = preg_replace('#^([\'"])([^\'"]+)\1#', '$1' . $filename . '$1', $args);
|
||||
}
|
||||
|
||||
// Generate the IIFE code.
|
||||
$tpl = '<?php (function($__dir, $__path, $__vars, $__varname, $__empty = null) { ';
|
||||
$tpl .= 'if (!$__vars): $__vars = []; if ($__empty): $__path = $__empty; $__vars[] = \'\'; endif; endif; ';
|
||||
// Generate the loop code.
|
||||
$tpl = '<?php (function($__filename, $__vars, $__varname, $__empty = null) { ';
|
||||
$tpl .= 'if (!$__vars): $__vars = []; if ($__empty): $__filename = $__empty; $__vars[] = \'\'; endif; endif; ';
|
||||
$tpl .= 'foreach ($__vars as $__var): ';
|
||||
$tpl .= '$__tpl = new \Rhymix\Framework\Template($__dir, $__path, "' . $extension . '"); ';
|
||||
$tpl .= '$__tpl->setVars([(string)$__varname => $__var]); ' ;
|
||||
$tpl .= 'echo $__tpl->compile(); endforeach; })(' . $dir . ', ' . $args . '); ?>';
|
||||
$tpl .= 'echo $this->_v2_include("include", $__filename, [(string)$__varname => $__var]); ';
|
||||
$tpl .= 'endforeach; })(' . $args . '); ?>';
|
||||
return self::_escapeVars($tpl);
|
||||
}, $content);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php if (!defined("RX_VERSION")) exit(); ?><?php $this->config->version = 2; ?>
|
||||
|
||||
|
||||
<div><?php (function($__dir, $__path, $__vars = null) { $__tpl = new \Rhymix\Framework\Template($__dir, $__path, "html"); if ($__vars) $__tpl->setVars($__vars); echo $__tpl->compile(); })("common/tpl", 'refresh.html'); ?></div>
|
||||
<div><?php echo $this->_v2_include('include', '^/common/tpl/refresh.html'); ?></div>
|
||||
<div><?php $this->_v2_loadResource('^/common/js/plugins/ckeditor/'); ?></div>
|
||||
<?php $this->_v2_loadResource('css/style.scss', 'print', '', []); ?>
|
||||
|
||||
|
|
@ -29,18 +29,18 @@
|
|||
</div>
|
||||
|
||||
<?php ob_start(); $__last_fragment_name = 'rhymix'; ?>
|
||||
<?php $__tmp_64b3371f38fea1 = Context::get('bar') ?? []; if($__tmp_64b3371f38fea1): $__loop_64b3371f38fea1 = $this->_v2_initLoopVar("64b3371f38fea1", $__tmp_64b3371f38fea1); foreach ($__tmp_64b3371f38fea1 as $__Context->k => $__Context->val): ?>
|
||||
<?php $__tmp_RANDOM_LOOP_ID = Context::get('bar') ?? []; if($__tmp_RANDOM_LOOP_ID): $__loop_RANDOM_LOOP_ID = $this->_v2_initLoopVar("RANDOM_LOOP_ID", $__tmp_RANDOM_LOOP_ID); foreach ($__tmp_RANDOM_LOOP_ID as $__Context->k => $__Context->val): ?>
|
||||
<div>
|
||||
<?php if (empty($__Context->nosuchvar)): ?>
|
||||
<img src="/rhymix/tests/_data/template/bar/rhymix.svg" alt="unit tests are cool" />
|
||||
<span <?php if ($__Context->k >= 2): ?>class="<?php echo htmlspecialchars($__Context->val ?? '', \ENT_QUOTES, 'UTF-8', false); ?>"<?php endif; ?>></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $this->_v2_incrLoopVar($__loop_64b3371f38fea1); endforeach; $this->_v2_removeLoopVar($__loop_64b3371f38fea1); unset($__loop_64b3371f38fea1); else: ?><div>Nothing here...</div><?php endif; ?>
|
||||
<?php $this->_v2_incrLoopVar($__loop_RANDOM_LOOP_ID); endforeach; $this->_v2_removeLoopVar($__loop_RANDOM_LOOP_ID); unset($__loop_RANDOM_LOOP_ID); else: ?><div>Nothing here...</div><?php endif; ?>
|
||||
<?php $this->_fragments[$__last_fragment_name] = ob_get_flush(); ?>
|
||||
|
||||
<?php (function($__dir, $__path, $__vars, $__varname, $__empty = null) { if (!$__vars): $__vars = []; if ($__empty): $__path = $__empty; $__vars[] = ''; endif; endif; foreach ($__vars as $__var): $__tpl = new \Rhymix\Framework\Template($__dir, $__path, "html"); $__tpl->setVars([(string)$__varname => $__var]); echo $__tpl->compile(); endforeach; })($this->relative_dirname, 'incl/eachtest', $__Context->bar, 'var'); ?>
|
||||
<?php (function($__dir, $__path, $__vars, $__varname, $__empty = null) { if (!$__vars): $__vars = []; if ($__empty): $__path = $__empty; $__vars[] = ''; endif; endif; foreach ($__vars as $__var): $__tpl = new \Rhymix\Framework\Template($__dir, $__path, "html"); $__tpl->setVars([(string)$__varname => $__var]); echo $__tpl->compile(); endforeach; })($this->relative_dirname, 'incl/eachtest', [], 'anything', 'incl/empty'); ?>
|
||||
<?php (function($__filename, $__vars, $__varname, $__empty = null) { if (!$__vars): $__vars = []; if ($__empty): $__filename = $__empty; $__vars[] = ''; endif; endif; foreach ($__vars as $__var): echo $this->_v2_include("include", $__filename, [(string)$__varname => $__var]); endforeach; })('incl/eachtest', $__Context->bar, 'var'); ?>
|
||||
<?php (function($__filename, $__vars, $__varname, $__empty = null) { if (!$__vars): $__vars = []; if ($__empty): $__filename = $__empty; $__vars[] = ''; endif; endif; foreach ($__vars as $__var): echo $this->_v2_include("include", $__filename, [(string)$__varname => $__var]); endforeach; })('incl/eachtest', [], 'anything', 'incl/empty'); ?>
|
||||
|
||||
<?php if (!$__Context->m): ?>
|
||||
<p>The full class name is <?php echo htmlspecialchars(get_class(new Rhymix\Framework\Push), \ENT_QUOTES, 'UTF-8', true); ?>, <?php echo htmlspecialchars(Rhymix\Framework\Push::class, \ENT_QUOTES, 'UTF-8', false); ?> really.</p>
|
||||
|
|
|
|||
|
|
@ -90,67 +90,32 @@ class TemplateParserV2Test extends \Codeception\Test\Unit
|
|||
|
||||
// Blade-style @include
|
||||
$source = "@include ('foobar')";
|
||||
$target = implode(' ', [
|
||||
'<?php (function($__dir, $__path, $__vars = null) {',
|
||||
'$__tpl = new \Rhymix\Framework\Template($__dir, $__path, "html");',
|
||||
'if ($__vars) $__tpl->setVars($__vars);',
|
||||
'echo $__tpl->compile(); })($this->relative_dirname, \'foobar\'); ?>'
|
||||
]);
|
||||
$target = "<?php echo \$this->_v2_include('include', 'foobar'); ?>";
|
||||
$this->assertEquals($target, $this->_parse($source));
|
||||
|
||||
// Blade-style @include with variable in filename
|
||||
$source = "@include(\$var)";
|
||||
$target = implode(' ', [
|
||||
'<?php (function($__dir, $__path, $__vars = null) {',
|
||||
'$__tpl = new \Rhymix\Framework\Template($__dir, $__path, "html");',
|
||||
'if ($__vars) $__tpl->setVars($__vars);',
|
||||
'echo $__tpl->compile(); })($this->relative_dirname, $__Context->var); ?>'
|
||||
]);
|
||||
$target = "<?php echo \$this->_v2_include('include', \$__Context->var); ?>";
|
||||
$this->assertEquals($target, $this->_parse($source));
|
||||
|
||||
// Blade-style @include with path relative to Rhymix installation directory
|
||||
$source = '@include ("^/common/js/plugins/foobar/baz.blade.php")';
|
||||
$target = implode(' ', [
|
||||
'<?php (function($__dir, $__path, $__vars = null) {',
|
||||
'$__tpl = new \Rhymix\Framework\Template($__dir, $__path, "html");',
|
||||
'if ($__vars) $__tpl->setVars($__vars);',
|
||||
'echo $__tpl->compile(); })("common/js/plugins/foobar", "baz.blade.php"); ?>'
|
||||
]);
|
||||
$target = '<?php echo $this->_v2_include(\'include\', "^/common/js/plugins/foobar/baz.blade.php"); ?>';
|
||||
$this->assertEquals($target, $this->_parse($source));
|
||||
|
||||
// Blade-style @includeIf with variables
|
||||
$source = "@includeIf('dir/foobar', \$vars)";
|
||||
$target = implode(' ', [
|
||||
'<?php (function($__dir, $__path, $__vars = null) {',
|
||||
'$__tpl = new \Rhymix\Framework\Template($__dir, $__path, "html");',
|
||||
'if (!$__tpl->exists()) return;',
|
||||
'if ($__vars) $__tpl->setVars($__vars);',
|
||||
'echo $__tpl->compile(); })($this->relative_dirname, \'dir/foobar\', $__Context->vars); ?>'
|
||||
]);
|
||||
$target = "<?php echo \$this->_v2_include('includeIf', 'dir/foobar', \$__Context->vars); ?>";
|
||||
$this->assertEquals($target, $this->_parse($source));
|
||||
|
||||
// Blade-style @includeWhen
|
||||
$source = "@includeWhen(\$foo->isBar(), '../../foobar.html', \$vars)";
|
||||
$target = implode(' ', [
|
||||
'<?php (function($__type, $__dir, $__cond, $__path, $__vars = null) {',
|
||||
'if ($__type === "includeWhen" && !$__cond) return;',
|
||||
'if ($__type === "includeUnless" && $__cond) return;',
|
||||
'$__tpl = new \Rhymix\Framework\Template($__dir, $__path, "html");',
|
||||
'if ($__vars) $__tpl->setVars($__vars);',
|
||||
'echo $__tpl->compile(); })("includeWhen", $this->relative_dirname, $__Context->foo->isBar(), \'../../foobar.html\', $__Context->vars); ?>'
|
||||
]);
|
||||
$target = "<?php echo \$this->_v2_include('includeWhen', \$__Context->foo->isBar(), '../../foobar.html', \$__Context->vars); ?>";
|
||||
$this->assertEquals($target, $this->_parse($source));
|
||||
|
||||
// Blade-style @includeUnless with path relative to Rhymix installation directory
|
||||
$source = "@includeUnless (false, '^common/tpl/foobar.html', \$vars)";
|
||||
$target = implode(' ', [
|
||||
'<?php (function($__type, $__dir, $__cond, $__path, $__vars = null) {',
|
||||
'if ($__type === "includeWhen" && !$__cond) return;',
|
||||
'if ($__type === "includeUnless" && $__cond) return;',
|
||||
'$__tpl = new \Rhymix\Framework\Template($__dir, $__path, "html");',
|
||||
'if ($__vars) $__tpl->setVars($__vars);',
|
||||
'echo $__tpl->compile(); })("includeUnless", "common/tpl", false, \'foobar.html\', $__Context->vars); ?>'
|
||||
]);
|
||||
$target = "<?php echo \$this->_v2_include('includeUnless', false, '^common/tpl/foobar.html', \$__Context->vars); ?>";
|
||||
$this->assertEquals($target, $this->_parse($source));
|
||||
|
||||
// Blade-style @each
|
||||
|
|
@ -160,7 +125,7 @@ class TemplateParserV2Test extends \Codeception\Test\Unit
|
|||
|
||||
// Blade-style @each with fallback template
|
||||
$source = "@each('incl/eachtest', \$jobs, 'job', 'incl/empty')";
|
||||
$target = 'if ($__empty): $__path = $__empty;';
|
||||
$target = 'echo $this->_v2_include("include"';
|
||||
$this->assertStringContainsString($target, $this->_parse($source));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue