From f86c3c779b97cf106f09185641004182e09592c0 Mon Sep 17 00:00:00 2001 From: tsu1980 Date: Wed, 16 Jan 2019 09:52:08 +0900 Subject: [PATCH 1/5] Add layout support --- src/PhpRenderer.php | 44 +++++++++++++++++++- tests/PhpRendererTest.php | 88 +++++++++++++++++++++++++++++++++++++++ tests/testLayout.php | 1 + 3 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 tests/testLayout.php diff --git a/src/PhpRenderer.php b/src/PhpRenderer.php index 2057849..5c38379 100644 --- a/src/PhpRenderer.php +++ b/src/PhpRenderer.php @@ -29,16 +29,23 @@ class PhpRenderer */ protected $attributes; + /** + * @var string + */ + protected $layout; + /** * SlimRenderer constructor. * * @param string $templatePath * @param array $attributes + * @param string $layout */ - public function __construct($templatePath = "", $attributes = []) + public function __construct($templatePath = "", $attributes = [], $layout = "") { $this->templatePath = rtrim($templatePath, '/\\') . '/'; $this->attributes = $attributes; + $this->setLayout($layout); } /** @@ -66,6 +73,34 @@ public function render(ResponseInterface $response, $template, array $data = []) return $response; } + /** + * Get layout template + * + * @return string + */ + public function getLayout() + { + return $this->layout; + } + + /** + * Set layout template + * + * @param string $layout + */ + public function setLayout($layout) + { + if ($layout === "" || $layout === null) { + $this->layout = null; + } else { + $layoutPath = $this->templatePath . $layout; + if (!is_file($layoutPath)) { + throw new \RuntimeException("Layout template `$layout` does not exist"); + } + $this->layout = $layoutPath; + } + } + /** * Get the attributes for the renderer * @@ -168,6 +203,13 @@ public function fetch($template, array $data = []) { ob_start(); $this->protectedIncludeScope($this->templatePath . $template, $data); $output = ob_get_clean(); + + if ($this->layout !== null) { + ob_start(); + $data['content'] = $output; + $this->protectedIncludeScope($this->layout, $data); + $output = ob_get_clean(); + } } catch(\Throwable $e) { // PHP 7+ ob_end_clean(); throw $e; diff --git a/tests/PhpRendererTest.php b/tests/PhpRendererTest.php index 575c638..e52aabd 100644 --- a/tests/PhpRendererTest.php +++ b/tests/PhpRendererTest.php @@ -112,4 +112,92 @@ public function testTemplateNotFound() { $renderer->render($response, "adfadftestTemplate.php", []); } + + public function testLayout() { + $renderer = new \Slim\Views\PhpRenderer("tests/"); + $renderer->setLayout("testLayout.php"); + + $headers = new Headers(); + $body = new Body(fopen('php://temp', 'r+')); + $response = new Response(200, $headers, $body); + + $newResponse = $renderer->render($response, "testTemplate.php", array("hello" => "Hi")); + + $newResponse->getBody()->rewind(); + + $this->assertEquals("Hi", $newResponse->getBody()->getContents()); + } + + public function testLayoutConstructor() { + $renderer = new \Slim\Views\PhpRenderer("tests", [], "testLayout.php"); + + $headers = new Headers(); + $body = new Body(fopen('php://temp', 'r+')); + $response = new Response(200, $headers, $body); + + $newResponse = $renderer->render($response, "testTemplate.php", array("hello" => "Hi")); + + $newResponse->getBody()->rewind(); + + $this->assertEquals("Hi", $newResponse->getBody()->getContents()); + } + + public function testExceptionInLayout() { + $renderer = new \Slim\Views\PhpRenderer("tests/"); + $renderer->setLayout("testException.php"); + + $headers = new Headers(); + $body = new Body(fopen('php://temp', 'r+')); + $response = new Response(200, $headers, $body); + + try { + $newResponse = $renderer->render($response, "testTemplate.php"); + } catch (Throwable $t) { // PHP 7+ + // Simulates an error template + $renderer->setLayout(null); + $newResponse = $renderer->render($response, "testTemplate.php", [ + "hello" => "Hi" + ]); + } catch (Exception $e) { // PHP < 7 + // Simulates an error template + $renderer->setLayout(null); + $newResponse = $renderer->render($response, "testTemplate.php", [ + "hello" => "Hi" + ]); + } + + $newResponse->getBody()->rewind(); + + $this->assertEquals("Hi", $newResponse->getBody()->getContents()); + } + + /** + * @expectedException RuntimeException + */ + public function testLayoutNotFound() { + + $renderer = new \Slim\Views\PhpRenderer("tests/"); + $renderer->setLayout("adfadftestLayout.php"); + + $headers = new Headers(); + $body = new Body(fopen('php://temp', 'r+')); + $response = new Response(200, $headers, $body); + + $renderer->render($response, "testTemplate.php", []); + } + + public function testContentDataKeyShouldBeIgnored() { + $renderer = new \Slim\Views\PhpRenderer("tests/"); + $renderer->setLayout("testLayout.php"); + + $headers = new Headers(); + $body = new Body(fopen('php://temp', 'r+')); + $response = new Response(200, $headers, $body); + + $newResponse = $renderer->render($response, "testTemplate.php", array("hello" => "Hi", "content" => "Ho")); + + $newResponse->getBody()->rewind(); + + $this->assertEquals("Hi", $newResponse->getBody()->getContents()); + } } diff --git a/tests/testLayout.php b/tests/testLayout.php new file mode 100644 index 0000000..2322447 --- /dev/null +++ b/tests/testLayout.php @@ -0,0 +1 @@ + \ No newline at end of file From 7cc110183546f855549e01873aadcd006d637582 Mon Sep 17 00:00:00 2001 From: tsu1980 Date: Wed, 16 Jan 2019 11:41:57 +0900 Subject: [PATCH 2/5] Update README.md --- README.md | 36 ++++++++++++++++++++++++++++++++++-- tests/PhpRendererTest.php | 16 ++++++++-------- tests/testLayout.php | 2 +- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 09a18af..0e16471 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ $container = $app->getContainer(); $container['renderer'] = new PhpRenderer("./templates"); $app->get('/hello/{name}', function ($request, $response, $args) { - return $this->renderer->render($response, "/hello.php", $args); + return $this->renderer->render($response, "hello.php", $args); }); $app->run(); @@ -45,7 +45,7 @@ $app->run(); $phpView = new PhpRenderer("./path/to/templates"); //Render a Template -$response = $phpView->render(new Response(), "/path/to/template.php", $yourData); +$response = $phpView->render(new Response(), "hello.php", $yourData); ``` ## Template Variables @@ -81,6 +81,38 @@ $phpView->render($response, $template, [ // In the view above, the $title will be "My Title" and not "Title" ``` +## Rendering in Layouts +You can now render view in another views called layouts, this allows you to compose modular view templates +and help keep your views DRY. + +Create your layout `./path/to/templates/layout.php`. +```phtml +<?=$title?> +``` + +Create your view template `./path/to/templates/hello.php`. +```phtml +Hello ! +``` + +Rendering in your code. +```php +$phpView = new PhpRenderer("./path/to/templates", ["title" => "My App"]); +$phpView->setLayout("layout.php"); + +//... + +$phpview->render($response, "hello.php", ["title" => "Hello - My App", "name" => "John"]); +``` + +Response will be +```html +Hello - My AppHello John! +``` + +Please note, the $content is special variable used inside layouts to render the wrapped view and should not be set +in your view paramaters. + ## Exceptions `\RuntimeException` - if template does not exist diff --git a/tests/PhpRendererTest.php b/tests/PhpRendererTest.php index e52aabd..d574136 100644 --- a/tests/PhpRendererTest.php +++ b/tests/PhpRendererTest.php @@ -114,32 +114,32 @@ public function testTemplateNotFound() { } public function testLayout() { - $renderer = new \Slim\Views\PhpRenderer("tests/"); + $renderer = new \Slim\Views\PhpRenderer("tests/", ["title" => "My App"]); $renderer->setLayout("testLayout.php"); $headers = new Headers(); $body = new Body(fopen('php://temp', 'r+')); $response = new Response(200, $headers, $body); - $newResponse = $renderer->render($response, "testTemplate.php", array("hello" => "Hi")); + $newResponse = $renderer->render($response, "testTemplate.php", array("title" => "Hello - My App", "hello" => "Hi")); $newResponse->getBody()->rewind(); - $this->assertEquals("Hi", $newResponse->getBody()->getContents()); + $this->assertEquals("Hello - My AppHi", $newResponse->getBody()->getContents()); } public function testLayoutConstructor() { - $renderer = new \Slim\Views\PhpRenderer("tests", [], "testLayout.php"); + $renderer = new \Slim\Views\PhpRenderer("tests", ["title" => "My App"], "testLayout.php"); $headers = new Headers(); $body = new Body(fopen('php://temp', 'r+')); $response = new Response(200, $headers, $body); - $newResponse = $renderer->render($response, "testTemplate.php", array("hello" => "Hi")); + $newResponse = $renderer->render($response, "testTemplate.php", array("title" => "Hello - My App", "hello" => "Hi")); $newResponse->getBody()->rewind(); - $this->assertEquals("Hi", $newResponse->getBody()->getContents()); + $this->assertEquals("Hello - My AppHi", $newResponse->getBody()->getContents()); } public function testExceptionInLayout() { @@ -194,10 +194,10 @@ public function testContentDataKeyShouldBeIgnored() { $body = new Body(fopen('php://temp', 'r+')); $response = new Response(200, $headers, $body); - $newResponse = $renderer->render($response, "testTemplate.php", array("hello" => "Hi", "content" => "Ho")); + $newResponse = $renderer->render($response, "testTemplate.php", array("title" => "Hello - My App", "hello" => "Hi", "content" => "Ho")); $newResponse->getBody()->rewind(); - $this->assertEquals("Hi", $newResponse->getBody()->getContents()); + $this->assertEquals("Hello - My AppHi", $newResponse->getBody()->getContents()); } } diff --git a/tests/testLayout.php b/tests/testLayout.php index 2322447..66fe48f 100644 --- a/tests/testLayout.php +++ b/tests/testLayout.php @@ -1 +1 @@ - \ No newline at end of file +<?=$title?> \ No newline at end of file From 6b0ca28efb3d81a6552af8c6db0ff5b5726060fe Mon Sep 17 00:00:00 2001 From: Glenn Eggleton Date: Thu, 24 Jan 2019 16:40:49 -0500 Subject: [PATCH 3/5] Update .travis.yml --- .travis.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2b00b8f..58fff81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,9 @@ language: php php: - - 5.5 - - 5.6 - - 7.0 - - hhvm + - 7.1 + - 7.2 before_script: composer install -script: phpunit --coverage-text --configuration phpunit.xml.dist \ No newline at end of file +script: phpunit --coverage-text --configuration phpunit.xml.dist From 04a02905cbe0dcb54b1194952dfb492a41964315 Mon Sep 17 00:00:00 2001 From: Glenn Eggleton Date: Fri, 25 Jan 2019 14:51:20 -0500 Subject: [PATCH 4/5] Update .travis.yml --- .travis.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 58fff81..a14cecd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,14 @@ language: php -php: - - 7.1 - - 7.2 +matrix: + include: + - php: 7.1 + env: ANALYSIS='true' + - php: 7.2 + - php: 7.3 + - php: nightly + allow_failures: + - php: nightly before_script: composer install From c615c7433e67f4512070c101e12dc662988258c8 Mon Sep 17 00:00:00 2001 From: l0gicgate Date: Mon, 15 Apr 2019 14:26:06 -0600 Subject: [PATCH 5/5] fix travis and phpunit configs --- .travis.yml | 4 +++- phpunit.xml.dist | 16 ++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index a14cecd..7392af2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ language: php +dist: trusty + matrix: include: - php: 7.1 @@ -12,4 +14,4 @@ matrix: before_script: composer install -script: phpunit --coverage-text --configuration phpunit.xml.dist +script: vendor/bin/phpunit --coverage-text --configuration phpunit.xml.dist diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3f730d7..07cf2d2 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,25 +1,29 @@ - - - tests/ + + ./tests/ - - src/ + + ./src/ \ No newline at end of file