Skip to content

Commit

Permalink
feat: easy template support layout rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Jan 8, 2023
1 parent b3cb0ff commit 385d887
Show file tree
Hide file tree
Showing 14 changed files with 75 additions and 23 deletions.
5 changes: 3 additions & 2 deletions src/Contract/CompilerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ public function setOpenCloseTag(string $open, string $close): static;
public function disableEchoFilter(): static;

/**
* @param string $name
* @param string $name Directive name.
* @param callable $handler
* @param bool $unwrap Dont wrap PHP tag after handled result.
*
* @return static
*/
public function addDirective(string $name, callable $handler): static;
public function addDirective(string $name, callable $handler, bool $unwrap = false): static;

/**
* compile template contents to raw PHP template codes
Expand Down
43 changes: 30 additions & 13 deletions src/EasyTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PhpPkg\EasyTpl\Concern\CompiledTemplateTrait;
use PhpPkg\EasyTpl\Contract\CompilerInterface;
use PhpPkg\EasyTpl\Contract\EasyTemplateInterface;
use RuntimeException;
use function str_replace;

/**
Expand Down Expand Up @@ -70,7 +71,10 @@ class EasyTemplate extends PhpTemplate implements EasyTemplateInterface
{
use CompiledTemplateTrait;

public const MAIN_CONTENT_MARK = '{_MAIN_CONTENT_}';
/**
* content mark on layout file.
*/
public const CONTENT_MARK = '{__CONTENT__}';

/**
* @var string[]
Expand Down Expand Up @@ -148,15 +152,17 @@ protected function initDirectives(CompilerInterface $compiler): void
})
// use layout file. syntax: {{ layout('layouts/main.tpl', ['name' => 'inhere']) }}
->addDirective('layout', function (string $body) {
/** will call {@see useLayout()} */
return '$this->useLayout' . $body;
/** will call {@see renderLayout()} */
return '$this->renderLayout' . $body;
})
// use on layout file. syntax: {{ contents }}
->addDirective('contents', fn() => self::MAIN_CONTENT_MARK);
->addDirective('contents', fn() => self::CONTENT_MARK, true);
}

/**
* Render template file, support `layout()` and $this->defaultLayout.
* Render template file and returns result.
*
* - support `layout()` and $this->defaultLayout.
*
* @param string $tplFile
* @param array $tplVars
Expand All @@ -173,12 +179,12 @@ public function render(string $tplFile, array $tplVars = []): string
$useLayout = true;
} elseif ($this->defaultLayout) {
$useLayout = true;
$this->useLayout($this->defaultLayout);
$this->renderLayout($this->defaultLayout);
}

// use layout
if ($useLayout) {
$contents = str_replace(self::MAIN_CONTENT_MARK, $contents, $this->layoutContent);
$contents = str_replace(self::CONTENT_MARK, $contents, $this->layoutContent);

// reset context
$this->currentLayout = $this->layoutContent = '';
Expand All @@ -188,7 +194,9 @@ public function render(string $tplFile, array $tplVars = []): string
}

/**
* Render view file, support layout(), but not apply $this->defaultLayout.
* Render template file and returns result.
*
* - support layout(), but not apply $this->defaultLayout.
*
* @param string $tplFile
* @param array $tplVars
Expand All @@ -202,8 +210,7 @@ public function renderFile(string $tplFile, array $tplVars = []): string

// use layout
if ($this->currentLayout) {
$contents = str_replace(self::MAIN_CONTENT_MARK, $contents, $this->layoutContent);

$contents = str_replace(self::CONTENT_MARK, $contents, $this->layoutContent);
// reset context
$this->currentLayout = $this->layoutContent = '';
}
Expand Down Expand Up @@ -239,17 +246,27 @@ protected function include(string $tplFile, array $tplVars = []): void
}

/**
* use and render layout file
* Use and render layout file.
*
* Usage: {{ layout('layouts/main.tpl') }}
*
* @param string $layoutFile
* @param array $tplVars
*
* @return void
*/
protected function useLayout(string $layoutFile, array $tplVars = []): void
protected function renderLayout(string $layoutFile, array $tplVars = []): void
{
// dont allow cycle use layout()
if ($this->currentLayout) {
throw new RuntimeException("cannot repeat use 'layout()' on template");
}

$phpFile = $this->compileFile($layoutFile);
$contents = $this->doRenderFile($phpFile, $tplVars);

$this->currentLayout = $layoutFile;
$this->layoutContent = $this->renderFile($layoutFile, $tplVars);
$this->layoutContent = $contents;
}

/**
Expand Down
30 changes: 24 additions & 6 deletions test/EasyTemplateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ private function newTemplate(): EasyTemplate
{
return new EasyTemplate([
'tmpDir' => $this->getTestdataPath('easy-caches'),
'tplDir' => __DIR__ . '/testdata/easy',
]);
}

Expand Down Expand Up @@ -184,7 +185,7 @@ public function testRender_define(): void

public function testRenderFile_ifElse(): void
{
$t = new EasyTemplate();
$t = $this->newTemplate();

$tplFile = $this->getTestTplFile('testdata/gen-go-funcs2.tpl');
$tplVars = ['vars' => ['Info', 'Error', 'Warn']];
Expand All @@ -197,7 +198,7 @@ public function testRenderFile_ifElse(): void

public function testRender_foreach(): void
{
$t = new EasyTemplate();
$t = $this->newTemplate();

$tplCode = <<<'CODE'
My name is {{ $name | strtoupper }},
Expand Down Expand Up @@ -234,9 +235,7 @@ public function testRender_foreach(): void

public function testRender_include_file(): void
{
$t = new EasyTemplate([
'tplDir' => __DIR__ . '/testdata/includes',
]);
$t = $this->newTemplate();

$result = $t->renderFile('home', ['name' => 'inhere']);
$this->assertNotEmpty($result);
Expand All @@ -246,7 +245,7 @@ public function testRender_include_file(): void
// vdump($result);
}

public function testCompileCode_noEchoFilter(): void
public function testEasy_textTemplate(): void
{
$t = EasyTemplate::textTemplate();

Expand All @@ -257,4 +256,23 @@ public function testCompileCode_noEchoFilter(): void
'name' => 'inhere',
]));
}

public function testEasy_useLayout01(): void
{
$tplFile = $this->getTestdataPath('easy/home01.tpl');

$t = $this->newTemplate();
$s = $t->render($tplFile);
vdump($s);
$this->assertNotEmpty($s);
}

public function testEasy_useLayout02(): void
{
$tplFile = $this->getTestdataPath('easy/home02.tpl');

$t = $this->newTemplate();
$s = $t->render($tplFile, $this->tplVars);
$this->assertNotEmpty($s);
}
}
10 changes: 8 additions & 2 deletions test/ExtendTemplateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ private function newTemplate(): ExtendTemplate

public function testExtend_renderFile(): void
{
$tplFile = $this->getTestdataPath('extends/home.tpl');
$tplFile = $this->getTestdataPath('extend/home.tpl');

$et = $this->newTemplate();
$str = $et->renderFile($tplFile);
Expand All @@ -30,7 +30,7 @@ public function testExtend_renderFile(): void
$this->assertStringContainsString('on home: block body;', $str);
$this->assertStringContainsString('on home: block footer;', $str);

$tplFile = $this->getTestdataPath('extends/home1.tpl');
$tplFile = $this->getTestdataPath('extend/home1.tpl');

$str = $et->renderFile($tplFile, $this->tplVars);
$this->assertStringContainsString('on layout: block header - name: inhere.', $str);
Expand Down Expand Up @@ -59,6 +59,12 @@ public function testExtend_renderString(): void

$str = $et->renderString($tplCode, $this->tplVars);
$this->assertEquals("my name is inhere1.\n", $str);

// inline
$tplCode = "{{ block 'first' }}my name is {{ name }}.{{ endblock }}";

$str = $et->renderString($tplCode, $this->tplVars);
$this->assertEquals("my name is inhere1.", $str);
}

public function testExtend_renderString_error(): void
Expand Down
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions test/testdata/easy/home02.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{ layout('layouts/layout01.tpl', ['info' => $info]) }}

on home: block body;
File renamed without changes.
7 changes: 7 additions & 0 deletions test/testdata/easy/layouts/layout02.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
this is an layout file.

on layout: block header - name: {{ info.name }}.

{{ contents() }}

on layout: block footer - - name: {{ info.city }}.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit 385d887

Please sign in to comment.