# Templating

By default, the application template is configured to work with JSON, and the template engine is not provided. However, provide abstraction for templating via the implementation of the HttpSoft\Basis\TemplateRendererInterface interface.

interface TemplateRendererInterface
{
    /**
     * Gets an instance of the original rendering engine used.
     *
     * @return object
     */
    public function getEngine(): object;

    /**
     * Renders the template/view file by passing parameters to it.
     *
     * @param string $view
     * @param array $params
     * @return string
     */
    public function render(string $view, array $params = []): string;
}

# Simplest implementation example

For example, we use devanych/view-renderer. It is a small and easy-to-use PHP library designed for rendering native PHP views. Similarly, you can use any template engine: Plates, Twig, etc.

Package installation.

composer require devanych/view-renderer

Creating the views directory for templates/views in the project root and add the path to this directory in config/config.php.

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

Creating a class that implements the 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);
    }
}

Adding the necessary dependency in 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']);
    },
    // ...
]);

Create a test action.

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',
        ]));
    }
}

Creating a view file views/test.php with some content.

<?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>

It remains to add a test route and make a request to this route.