Like said in the title, I looking to rendering twig template in controller using Slim 4 framework.
I searched on the Internet, but I didn’t find a solution that works for me and well-explained.
If someone can explains me how can I make this to work.
Here the code a my files:
index.php
<?php
use App\Controllers\HomeController;
use DI\Container;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
Answer:
Container Answer:
$container = new Container();
Answer:
Slim Answer:
AppFactory::setContainer($container);
$app = AppFactory::create();
Answer:
Twig Answer:
$container = $app->getContainer();
$container['view'] = function ($c) {
return $c;
};
$container['HomeController'] = function ($c) {
return new HomeController($c['view']);
};
Answer:
Routes Answer:
$app->get('/',HomeController::class . ":home");
$app->get('/home', HomeController::class . ":home");
Answer:
Run Answer:
$app->run();
HomeController.php
<?php
namespace App\Controllers;
use Psr\Container\ContainerInterface;
use Slim\Psr7\Request;
use Slim\Psr7\Response;
class HomeController
{
private $app;
public function __construct(ContainerInterface $app)
{
$this->app = $app;
}
public function home(Request $request, Response $response)
{
$this->app->get('view')->render($response, 'home.twig');
}
}
composer.json
{
"require": {
"slim/slim": "4.*",
"slim/psr7": "^1.0",
"slim/twig-view": "^3.0",
"php-di/php-di": "^6.0"
},
"autoload": {
"psr-4": {
"App\": "app/"
}
}
}
project structure
And when I start the server, the console gives me:
PHP 7.3.11-0ubuntu0.19.10.2 Development Server started at Tue Feb 18 16:33:41 2020
Listening on http://localhost:8080
Document root is /home/thomas/Code/2020/S4/prog_web/homelogin/public
Press Ctrl-C to quit.
[Tue Feb 18 16:33:44 2020] PHP Fatal error: Uncaught Error: Cannot use object of type DI\Container as array in /home/thomas/Code/2020/S4/prog_web/homelogin/public/index.php:17
Stack trace:
#0 {main}
thrown in /home/thomas/Code/2020/S4/prog_web/homelogin/public/index.php on line 17
Thank in advance.
You cannot use DI\Container object as an array. You should use set()
method to add a service to the container instead.
Replace these lines:
$container['view'] = function ($c) {
return $c;
};
$container['HomeController'] = function ($c) {
return new HomeController($c['view']);
};
with these:
$container->set('view', function () {
return \Slim\Views\Twig::create('../resources/views', ['cache' => false]);
});
$container->set('HomeController', function () use ($container) {
return new HomeController($container);
});
And then you should return a response (ResponseInterface) in the home() method of your HomeController class:
public function home(Request $request, Response $response)
{
return $this->app->get('view')->render($response, 'templates/home.twig');
}
Note that your home.twig
file is located in the templates directory.
Read more about Dependency Container and Twig in Slim.