Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/slimphp/PHP-View into tex…
Browse files Browse the repository at this point in the history
…tual-change

# Conflicts:
#	README.md
  • Loading branch information
l0gicgate committed Apr 15, 2019
2 parents 1d81787 + 8401136 commit dbf7327
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 16 deletions.
18 changes: 12 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
language: php

php:
- 5.5
- 5.6
- 7.0
- hhvm
dist: trusty

matrix:
include:
- php: 7.1
env: ANALYSIS='true'
- php: 7.2
- php: 7.3
- php: nightly
allow_failures:
- php: nightly

before_script: composer install

script: phpunit --coverage-text --configuration phpunit.xml.dist
script: vendor/bin/phpunit --coverage-text --configuration phpunit.xml.dist
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,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();
Expand All @@ -41,11 +41,10 @@ $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

You can now add variables to your renderer that will be available to all templates you render.

```php
Expand Down Expand Up @@ -80,6 +79,37 @@ $phpView->render($response, $template, [
## Sub-templates
Inside your templates you may use `$this` to refer to the PhpRenderer object to render sub-templates.

## 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
<html><head><title><?=$title?></title></head><body><?=$content?></body></html>
```

Create your view template `./path/to/templates/hello.php`.
```phtml
Hello <?=$name?>!
```

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
<html><head><title>Hello - My App</title></head><body>Hello John!</body></html>
```

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
Expand Down
16 changes: 10 additions & 6 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.7/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutChangesToGlobalState="true"
beStrictAboutOutputDuringTests="true"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="tests/bootstrap.php"
>
<testsuites>
<testsuite name="Renderer Tests">
<directory>tests/</directory>
<testsuite name="PHP-View Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>

<filter>
<whitelist>
<directory>src/</directory>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory>./src/</directory>
</whitelist>
</filter>
</phpunit>
44 changes: 43 additions & 1 deletion src/PhpRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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
*
Expand Down Expand Up @@ -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;
Expand Down
88 changes: 88 additions & 0 deletions tests/PhpRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,92 @@ public function testTemplateNotFound() {

$renderer->render($response, "adfadftestTemplate.php", []);
}

public function testLayout() {
$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("title" => "Hello - My App", "hello" => "Hi"));

$newResponse->getBody()->rewind();

$this->assertEquals("<html><head><title>Hello - My App</title></head><body>Hi</body></html>", $newResponse->getBody()->getContents());
}

public function testLayoutConstructor() {
$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("title" => "Hello - My App", "hello" => "Hi"));

$newResponse->getBody()->rewind();

$this->assertEquals("<html><head><title>Hello - My App</title></head><body>Hi</body></html>", $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("title" => "Hello - My App", "hello" => "Hi", "content" => "Ho"));

$newResponse->getBody()->rewind();

$this->assertEquals("<html><head><title>Hello - My App</title></head><body>Hi</body></html>", $newResponse->getBody()->getContents());
}
}
1 change: 1 addition & 0 deletions tests/testLayout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<html><head><title><?=$title?></title></head><body><?=$content?></body></html>

0 comments on commit dbf7327

Please sign in to comment.