Skip to content
Open
Show file tree
Hide file tree
Changes from all 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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create UPGRADE.md also with instructions to upgrade. These changes breaks BC.

- 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\TwigTemplateRenderer;

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(TwigTemplateRenderer::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
23 changes: 10 additions & 13 deletions src/ViewRenderer.php → src/TwigTemplateRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,29 @@
use function str_replace;

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

public function render(ViewInterface $view, string $template, array $parameters): string
{
$environment = $this->environment;
$renderer = function () use ($view, $template, $parameters, $environment): void {
$template = str_replace('\\', '/', $template);
$basePath = str_replace('\\', '/', $view->getBasePath());
$file = str_replace($basePath, '', $template);

echo $environment->render($file, array_merge($parameters, ['this' => $view]));
};
$templateFile = str_replace(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if $template placed not in base path?

$view->getBasePath(),
'',
$template
);

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

Check warning on line 39 in src/TwigTemplateRenderer.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])); /**

Check warning on line 39 in src/TwigTemplateRenderer.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])); /**

Check warning on line 39 in src/TwigTemplateRenderer.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])); /**

Check warning on line 39 in src/TwigTemplateRenderer.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])); /**

try {
/** @psalm-suppress PossiblyInvalidFunctionCall,PossiblyNullFunctionCall */
$renderer->bindTo($view)();
$this->environment->display($templateFile, array_merge($parameters, ['this' => $view]));

Check warning on line 42 in src/TwigTemplateRenderer.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); /** * @var string We assume that in this case active output buffer is always existed, so `ob_get_clean()` * returns a string.

Check warning on line 42 in src/TwigTemplateRenderer.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, [])); /** * @var string We assume that in this case active output buffer is always existed, so `ob_get_clean()` * returns a string.

Check warning on line 42 in src/TwigTemplateRenderer.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); /** * @var string We assume that in this case active output buffer is always existed, so `ob_get_clean()` * returns a string.

Check warning on line 42 in src/TwigTemplateRenderer.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, [])); /** * @var string We assume that in this case active output buffer is always existed, so `ob_get_clean()` * returns a string.

/**
* @var string We assume that in this case active output buffer is always existed, so `ob_get_clean()`
* returns a string.
Expand Down
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Why remove YiiTwigExtension ?

  2. If remove, why does it need in tests?

{
public function __construct(private ContainerInterface $container)
{
Expand Down
32 changes: 9 additions & 23 deletions tests/ViewTest.php → tests/TwigTemplateRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@
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\Twig\TwigTemplateRenderer;
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 TwigTemplateRendererTest extends TestCase
{
private string $layoutPath;
private string $tempDirectory;
Expand Down Expand Up @@ -54,29 +53,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(TwigTemplateRenderer::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 +87,10 @@ private function getContainer(): SimpleContainer
EndBody::class => new EndBody(),
ErrorContent::class => new ErrorContent(),
Environment::class => $twig,
TemplateRendererInterface::class => new ViewRenderer($twig),
TwigTemplateRenderer::class => new TwigTemplateRenderer($twig),
]);

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

return $container;
}
Expand All @@ -114,7 +100,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 TwigTemplateRenderer($container->get(Environment::class))])
->withFallbackExtension('twig');
}
}
Loading