Implement simple PHP based view renderer

This commit is contained in:
Tim 2023-08-15 03:02:55 +02:00
parent 9b8985640c
commit c80dcd2860
9 changed files with 83 additions and 9 deletions

View File

@ -4,3 +4,4 @@ Current features:
- Routing with method dependency injection - Routing with method dependency injection
- Controller configuration with annotations - Controller configuration with annotations
- Dependency injection application configuration - Dependency injection application configuration
- Simple renderer based on PHP

View File

@ -7,6 +7,8 @@ use Ardent\Undercurrent\Http\GenericResponse;
use Ardent\Undercurrent\Http\ResponseInterface; use Ardent\Undercurrent\Http\ResponseInterface;
use Ardent\Undercurrent\Http\RouterConfig; use Ardent\Undercurrent\Http\RouterConfig;
use Ardent\Undercurrent\Http\StatusEnum; use Ardent\Undercurrent\Http\StatusEnum;
use Ardent\Undercurrent\View\BaseView;
use Ardent\Undercurrent\View\ViewInterface;
class HelloWorldController class HelloWorldController
{ {
@ -28,6 +30,12 @@ class HelloWorldController
return new GenericResponse('Hello World!'); return new GenericResponse('Hello World!');
} }
#[Route('/view')]
public function view(): ViewInterface
{
return new BaseView('/Template/home.php', ['message' => 'Hello World!']);
}
#[Route('/routes/{word}')] #[Route('/routes/{word}')]
public function routes(RouterConfig $config, string $word): ResponseInterface public function routes(RouterConfig $config, string $word): ResponseInterface
{ {

10
app/Template/base.php Normal file
View File

@ -0,0 +1,10 @@
<?php /** @var $this \Ardent\Undercurrent\View\BaseView */ ?>
<html>
<head>
<title>TOSTI MAN KOMT JE HALEN</title>
</head>
<body>
<?= $this->data['slot'] ?>
</body>
</html>

4
app/Template/home.php Normal file
View File

@ -0,0 +1,4 @@
<?php /** @var $this \Ardent\Undercurrent\View\BaseView */ ?>
<?php $this->extends = '/Template/base.php' ?>
<?= $this->data['message'] ?>

View File

@ -2,11 +2,10 @@
namespace Ardent\Undercurrent\Http; namespace Ardent\Undercurrent\Http;
use Ardent\Undercurrent\Container\ClassNotFoundException; use Ardent\Undercurrent\AppConfig;
use Ardent\Undercurrent\Container\ContainerInterface; use Ardent\Undercurrent\Container\ContainerInterface;
use Ardent\Undercurrent\Logger\LoggerInterface; use Ardent\Undercurrent\Logger\LoggerInterface;
use Exception; use Ardent\Undercurrent\View\ViewInterface;
use ReflectionMethod;
class GenericRouter implements RouterInterface class GenericRouter implements RouterInterface
{ {
@ -32,11 +31,17 @@ class GenericRouter implements RouterInterface
$this->logger->add(sprintf('Matched route %s', $route->getRoute()->path)); $this->logger->add(sprintf('Matched route %s', $route->getRoute()->path));
return $this->container->call( $response = $this->container->call(
$route->getController(), $route->getController(),
$route->getMethod(), $route->getMethod(),
$params, $params,
); );
if ($response instanceof ViewInterface) {
return new GenericResponse($response->render($this->container->get(AppConfig::class)));
}
return $response;
} }
throw new RouteNotFoundException($request); throw new RouteNotFoundException($request);

View File

@ -2,6 +2,8 @@
namespace Ardent\Undercurrent\Http; namespace Ardent\Undercurrent\Http;
use Ardent\Undercurrent\View\ViewInterface;
interface RouterInterface interface RouterInterface
{ {
public function dispatch(RequestInterface $request): ResponseInterface; public function dispatch(RequestInterface $request): ResponseInterface;

View File

@ -14,6 +14,7 @@ use Ardent\Undercurrent\Http\RouterInterface;
use Ardent\Undercurrent\Http\StatusEnum; use Ardent\Undercurrent\Http\StatusEnum;
use Ardent\Undercurrent\Logger\LogContainer; use Ardent\Undercurrent\Logger\LogContainer;
use Ardent\Undercurrent\Logger\LoggerInterface; use Ardent\Undercurrent\Logger\LoggerInterface;
use Ardent\Undercurrent\View\ViewInterface;
class BaseKernel class BaseKernel
{ {
@ -61,10 +62,6 @@ class BaseKernel
//$response = $container->get(RouterConfig::class)->getExceptionRoute()->getController()::exception($e); //$response = $container->get(RouterConfig::class)->getExceptionRoute()->getController()::exception($e);
} }
foreach ($log->getLogs() as $log) {
echo sprintf('<p>%s</p>', $log);
}
http_response_code($response->getStatus()->value); http_response_code($response->getStatus()->value);
foreach ($response->getHeaders() as $header) { foreach ($response->getHeaders() as $header) {
@ -72,6 +69,10 @@ class BaseKernel
} }
echo $response->getBody(); echo $response->getBody();
foreach ($log->getLogs() as $log) {
echo sprintf('<p>%s</p>', $log);
}
} }
protected function addControllers(ContainerInterface $container, array $controllers): void protected function addControllers(ContainerInterface $container, array $controllers): void

32
src/View/BaseView.php Normal file
View File

@ -0,0 +1,32 @@
<?php
namespace Ardent\Undercurrent\View;
use Ardent\Undercurrent\AppConfig;
use Ardent\Undercurrent\Http\GenericResponse;
use Ardent\Undercurrent\Http\ResponseInterface;
class BaseView implements ViewInterface
{
public function __construct(
private readonly string $path,
private readonly array $data = [],
private ?string $extends = null,
)
{
}
public function render(AppConfig $config): string
{
$path = $config->getRootPath() . $this->path;
ob_start();
include $path;
$output = ob_get_clean();
if ($this->extends) {
$output = (new BaseView($this->extends, $this->data + ['slot' => $output]))->render($config);
}
return $output;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Ardent\Undercurrent\View;
use Ardent\Undercurrent\AppConfig;
use Ardent\Undercurrent\Http\ResponseInterface;
interface ViewInterface
{
public function render(AppConfig $config): string;
}