Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## 2.1.1 under development

- Chg #61: Rename `ViewRenderer` to more understandable `TemplateRenderer` (@rustamwin)
- Chg #61: Remove `YiiTwigExtension` (@rustamwin)
- Chg #77, #86: Update version of `yiisoft/view` to `^11|^12` (@rustamwin, @vjik)
- Chg #86: Raise the minimum PHP version to `^8.1` (@rustamwin)
- Chg #86: Change PHP constraint in `composer.json` to `8.1 - 8.4` (@rustamwin)
Expand Down
71 changes: 27 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
[![type-coverage](https://shepherd.dev/github/yiisoft/view-twig/coverage.svg)](https://shepherd.dev/github/yiisoft/view-twig)

The package is an extension of the [Yii View Rendering Library](https://github.com/yiisoft/view/). This extension
provides a `ViewRender` that would allow you to use [Twig](https://twig.symfony.com/) view template engine.
provides a `TemplateRenderer` that would allow you to use [Twig](https://twig.symfony.com/) view template engine.

## Requirements

Expand All @@ -41,58 +41,48 @@ In your application, you should specify the configuration for `Twig`
use Psr\Container\ContainerInterface;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Twig\Loader\LoaderInterface;
use Yiisoft\Aliases\Aliases;
use Yiisoft\View\Twig\Extensions\YiiTwigExtension;

return [
Environment::class => static function (ContainerInterface $container): Environment {
$loader = new FilesystemLoader($container
->get(Aliases::class)
->get('@views'));

$twig = new Environment($loader, [
'cache' => $container
->get(Aliases::class)
->get('@runtime/cache/twig'),
'charset' => 'utf-8',
]);

$twig->addExtension(new YiiTwigExtension($container));
return $twig;
},
/** @var array $params */

return [
LoaderInterface::class => static fn (Aliases $aliases) => new FilesystemLoader($aliases->get('@views'))
Environment::class => [
'__construct()' => ['options' => $params['yiisoft/view-twig']['options']]
],
];
```

And also override the configuration for `WebView` (by default, this is `config/packages/yiisoft/view/web.php`):
And also add the parameters for `WebView` and `Environment` in `params.php`:

```php
use Psr\Container\ContainerInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use Twig\Environment;
use Yiisoft\Aliases\Aliases;
use Yiisoft\Definitions\DynamicReference;
use Yiisoft\Definitions\Reference;
use Yiisoft\View\WebView;
use Yiisoft\View\Twig\ViewRenderer;

/** @var array $params */
use Yiisoft\View\Twig\TemplateRenderer;

return [
//...
WebView::class => static function (ContainerInterface $container) use ($params): WebView {
$webView = new WebView(
$container
->get(Aliases::class)
->get('@views'),
$container->get(EventDispatcherInterface::class),
);

$webView = $webView
->withDefaultExtension('twig')
->withRenderers(['twig' => new ViewRenderer($container->get(Environment::class))])
;

$webView->setCommonParameters($params['yiisoft/view']['commonParameters']);
return $webView;
},
'yiisoft/view' => [
'defaultExtension' => 'twig',
'renderers' => [
'twig' => Reference::to(TemplateRenderer::class),
],
],
'yiisoft/view-twig' => [
'options' => [
'cache' => DynamicReference::to(static fn (Aliases $aliases) => $aliases->get('@runtime/twig')),
'charset' => 'utf-8',
'debug' => $_ENV['YII_DEBUG'],
//...
],
],
//...
];
```
Expand All @@ -101,13 +91,6 @@ return [

All variables that were in the regular template are also available in the twig template.

The `get(string $id);` function allows you to get the definition that was set by the container,
this function is available in all view templates and layouts:

```twig
{{ get('App\\Widget\\PerformanceMetrics').widget()|raw }}
```

The default main layout of the [application template](https://github.com/yiisoft/app) will look like this:

```twig
Expand Down
52 changes: 52 additions & 0 deletions src/TemplateRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace Yiisoft\View\Twig;

use Throwable;
use Twig\Environment;
use Yiisoft\View\TemplateRendererInterface;

use Yiisoft\View\ViewInterface;

use function array_merge;
use function ob_end_clean;
use function ob_get_clean;
use function ob_get_level;
use function ob_implicit_flush;
use function ob_start;
use function str_replace;

/**
* TemplateRenderer allows using Twig with a View service.
*/
final class TemplateRenderer implements TemplateRendererInterface
{
public function __construct(private readonly Environment $environment)
{
}

public function render(ViewInterface $view, string $template, array $parameters): string

Check failure on line 30 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.4-ubuntu-latest

InvalidFalsableReturnType

src/TemplateRenderer.php:30:87: InvalidFalsableReturnType: The declared return type 'string' for Yiisoft\View\Twig\TemplateRenderer::render does not allow false, but 'false|string' contains false (see https://psalm.dev/143)

Check failure on line 30 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

InvalidFalsableReturnType

src/TemplateRenderer.php:30:87: InvalidFalsableReturnType: The declared return type 'string' for Yiisoft\View\Twig\TemplateRenderer::render does not allow false, but 'false|string' contains false (see https://psalm.dev/143)

Check failure on line 30 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

InvalidFalsableReturnType

src/TemplateRenderer.php:30:87: InvalidFalsableReturnType: The declared return type 'string' for Yiisoft\View\Twig\TemplateRenderer::render does not allow false, but 'false|string' contains false (see https://psalm.dev/143)
{
$templateFile = str_replace(
$view->getBasePath(),
'',
$template
);

$obInitialLevel = ob_get_level();
ob_start();
ob_implicit_flush(false);

Check warning on line 40 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "FunctionCallRemoval": --- Original +++ New @@ @@ $templateFile = str_replace($view->getBasePath(), '', $template); $obInitialLevel = ob_get_level(); ob_start(); - ob_implicit_flush(false); + try { $this->environment->display($templateFile, array_merge($parameters, ['this' => $view])); return ob_get_clean();

Check warning on line 40 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "FalseValue": --- Original +++ New @@ @@ $templateFile = str_replace($view->getBasePath(), '', $template); $obInitialLevel = ob_get_level(); ob_start(); - ob_implicit_flush(false); + ob_implicit_flush(true); try { $this->environment->display($templateFile, array_merge($parameters, ['this' => $view])); return ob_get_clean();

Check warning on line 40 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "FalseValue": --- Original +++ New @@ @@ $templateFile = str_replace($view->getBasePath(), '', $template); $obInitialLevel = ob_get_level(); ob_start(); - ob_implicit_flush(false); + ob_implicit_flush(true); try { $this->environment->display($templateFile, array_merge($parameters, ['this' => $view])); return ob_get_clean();

Check warning on line 40 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "FunctionCallRemoval": --- Original +++ New @@ @@ $templateFile = str_replace($view->getBasePath(), '', $template); $obInitialLevel = ob_get_level(); ob_start(); - ob_implicit_flush(false); + try { $this->environment->display($templateFile, array_merge($parameters, ['this' => $view])); return ob_get_clean();

try {
$this->environment->display($templateFile, array_merge($parameters, ['this' => $view]));

Check warning on line 43 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayMerge": --- Original +++ New @@ @@ ob_start(); ob_implicit_flush(false); try { - $this->environment->display($templateFile, array_merge($parameters, ['this' => $view])); + $this->environment->display($templateFile, $parameters); return ob_get_clean(); } catch (Throwable $e) { while (ob_get_level() > $obInitialLevel) {

Check warning on line 43 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": --- Original +++ New @@ @@ ob_start(); ob_implicit_flush(false); try { - $this->environment->display($templateFile, array_merge($parameters, ['this' => $view])); + $this->environment->display($templateFile, array_merge($parameters, [])); return ob_get_clean(); } catch (Throwable $e) { while (ob_get_level() > $obInitialLevel) {

Check warning on line 43 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayMerge": --- Original +++ New @@ @@ ob_start(); ob_implicit_flush(false); try { - $this->environment->display($templateFile, array_merge($parameters, ['this' => $view])); + $this->environment->display($templateFile, $parameters); return ob_get_clean(); } catch (Throwable $e) { while (ob_get_level() > $obInitialLevel) {

Check warning on line 43 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": --- Original +++ New @@ @@ ob_start(); ob_implicit_flush(false); try { - $this->environment->display($templateFile, array_merge($parameters, ['this' => $view])); + $this->environment->display($templateFile, array_merge($parameters, [])); return ob_get_clean(); } catch (Throwable $e) { while (ob_get_level() > $obInitialLevel) {
return ob_get_clean();

Check failure on line 44 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.4-ubuntu-latest

FalsableReturnStatement

src/TemplateRenderer.php:44:20: FalsableReturnStatement: The declared return type 'string' for Yiisoft\View\Twig\TemplateRenderer::render does not allow false, but the function returns 'false|string' (see https://psalm.dev/137)

Check failure on line 44 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

FalsableReturnStatement

src/TemplateRenderer.php:44:20: FalsableReturnStatement: The declared return type 'string' for Yiisoft\View\Twig\TemplateRenderer::render does not allow false, but the function returns 'false|string' (see https://psalm.dev/137)

Check failure on line 44 in src/TemplateRenderer.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

FalsableReturnStatement

src/TemplateRenderer.php:44:20: FalsableReturnStatement: The declared return type 'string' for Yiisoft\View\Twig\TemplateRenderer::render does not allow false, but the function returns 'false|string' (see https://psalm.dev/137)
} catch (Throwable $e) {
while (ob_get_level() > $obInitialLevel) {
ob_end_clean();
}
throw $e;
}
}
}
59 changes: 0 additions & 59 deletions src/ViewRenderer.php

This file was deleted.

4 changes: 2 additions & 2 deletions src/Extensions/YiiTwigExtension.php → tests/Support/SimpleExtension.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Yiisoft\View\Twig\Extensions;
namespace Yiisoft\View\Twig\Tests\Support;

use Psr\Container\ContainerInterface;
use Twig\Extension\AbstractExtension;
Expand All @@ -11,7 +11,7 @@
/**
* YiiTwigExtension adds additional functionality to the Twig engine.
*/
final class YiiTwigExtension extends AbstractExtension
final class SimpleExtension extends AbstractExtension
{
public function __construct(private ContainerInterface $container)
{
Expand Down
33 changes: 10 additions & 23 deletions tests/ViewTest.php → tests/TemplateRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
use Yiisoft\Aliases\Aliases;
use Yiisoft\Files\FileHelper;
use Yiisoft\Test\Support\Container\SimpleContainer;
use Yiisoft\View\TemplateRendererInterface;
use Yiisoft\View\WebView;
use Yiisoft\View\Twig\Extensions\YiiTwigExtension;
use Yiisoft\View\Template;
use Yiisoft\View\Twig\TemplateRenderer;
use Yiisoft\View\Twig\Tests\Support\BeginBody;
use Yiisoft\View\Twig\Tests\Support\EndBody;
use Yiisoft\View\Twig\Tests\Support\ErrorContent;
use Yiisoft\View\Twig\ViewRenderer;
use Yiisoft\View\Twig\Tests\Support\SimpleExtension;
use Yiisoft\View\WebView;

final class ViewTest extends TestCase
final class TemplateRendererTest extends TestCase
{
private string $layoutPath;
private string $tempDirectory;
Expand Down Expand Up @@ -54,29 +54,16 @@ public function testLayout(): void
$this->assertStringContainsString('End Body', $result);
}

public function testExtension(): void
{
$container = $this->getContainer();
$extension = new YiiTwigExtension($container);
$functionGet = $extension->getFunctions()[0];

$this->assertSame($container->get(Aliases::class), ($functionGet->getCallable())(Aliases::class));
$this->assertSame($container->get(BeginBody::class), ($functionGet->getCallable())(BeginBody::class));
$this->assertSame($container->get(EndBody::class), ($functionGet->getCallable())(EndBody::class));
$this->assertSame($container->get(ErrorContent::class), ($functionGet->getCallable())(ErrorContent::class));
$this->assertSame($container->get(Environment::class), ($functionGet->getCallable())(Environment::class));
}

public function testExceptionDuringRendering(): void
{
$container = $this->getContainer();
$view = $this->getView($container);
$renderer = $container->get(TemplateRendererInterface::class);
$renderer = $container->get(TemplateRenderer::class);

$obInitialLevel = ob_get_level();

try {
$renderer->render($view, __DIR__ . '/public/views/error.twig', []);
$renderer->render($view, 'error.twig', []);
} catch (RuntimeError) {
}

Expand All @@ -101,10 +88,10 @@ private function getContainer(): SimpleContainer
EndBody::class => new EndBody(),
ErrorContent::class => new ErrorContent(),
Environment::class => $twig,
TemplateRendererInterface::class => new ViewRenderer($twig),
TemplateRenderer::class => new TemplateRenderer($twig),
]);

$twig->addExtension(new YiiTwigExtension($container));
$twig->addExtension(new SimpleExtension($container));

return $container;
}
Expand All @@ -114,7 +101,7 @@ private function getView(SimpleContainer|null $container = null): WebView
$container ??= $this->getContainer();

return (new WebView($container->get(Aliases::class)->get('@views')))
->withRenderers(['twig' => new ViewRenderer($container->get(Environment::class))])
->withRenderers(['twig' => new TemplateRenderer($container->get(Environment::class))])
->withFallbackExtension('twig');
}
}
Loading