# Шаблонизация

По умолчанию шаблон приложения настроен на работу с JSON и шаблонизатор не предоставляется. Однако предоставляется абстракция для создания механизма шаблонов через реализацию интерфейса HttpSoft\Basis\TemplateRendererInterface.

interface TemplateRendererInterface
{
    /**
     * Возвращает экземпляр оригинального используемого шаблонизатора.
     *
     * @return object
     */
    public function getEngine(): object;

    /**
     * Рендерит файл шаблона/представления, передавая ему параметры.
     *
     * @param string $view
     * @param array $params
     * @return string
     */
    public function render(string $view, array $params = []): string;
}

# Простейший пример реализации

Для примера используем devanych/view-renderer. Это небольшая и простая в использовании PHP-библиотека, предназначенная для рендеринга нативных PHP-представлений. Точно также можно использовать любой шаблонизатор: Plates, Twig и т.д.

Устанавливаем пакет.

composer require devanych/view-renderer

Создаем директорию views для шаблонов/представлений в корне проекта и добавляем путь к этой директории в config/config.php.

return [
    // ...
    'view_path' => __DIR__ . '/../views',
    // ...
];

Создаем класс, реализующий интерфейс HttpSoft\Basis\TemplateRendererInterface.

namespace App\Infrastructure\Template;

use Devanych\View\Renderer;
use HttpSoft\Basis\TemplateRendererInterface;

class TemplateRenderer implements TemplateRendererInterface
{
    private Renderer $render;

    public function __construct(string $viewPath)
    {
        $this->render = new Renderer($viewPath));
    }

    public function getEngine(): Renderer
    {
        return $this->render;
    }

    public function render(string $view, array $params = []): string
    {
        return $this->render->render($view, $params);
    }
}

Добавляем необходимую зависимость в config/container.php.

// ...
use App\Infrastructure\Template\TemplateRendererFactor;
use HttpSoft\Basis\TemplateRendererInterface;
use Psr\Container\ContainerInterface;
// ...

return new Container([
    // ...
    TemplateRendererInterface::class => function (ContainerInterface $container) {
        return new TemplateRenderer($container->get('config')['view_path']);
    },
    // ...
]);

Создаем тестовый экшен.

namespace App\Http\Action;

use HttpSoft\Basis\TemplateRendererInterface;
use HttpSoft\Response\HtmlResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

final class TestAction implements RequestHandlerInterface
{
    private TemplateRendererInterface $renderer;

    public function __construct(TemplateRendererInterface $renderer)
    {
        $this->renderer = $renderer;
    }

    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        return new HtmlResponse($this->renderer->render('test', [
            'pageTitle' => 'Test Page',
        ]));
    }
}

Создаем файл представления views/test.php с каким-нибудь содержимым.

<?php

declare(strict_types=1);

/** @var Devanych\View\Renderer $this */
/** @var string $pageTitle */
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title><?=$this->esc($pageTitle);?></title>
</head>
<body>
    <h1><?=$this->esc($pageTitle);?></h1>
</body>
</html>

Осталось добавить тестовый маршрут и сделать запрос к этому маршруту.