Using Slim Framework 2 you could set the template directory using this code:
// Views
$view = $app->view();
$view->setTemplateDirectory('../app/views');
How can I do this using Slim Framework 3?
Currently I'm getting this error:
Fatal error: Call to a member function setTemplateDirectory() on null
Does anybody know how to do this in Slim Framework 3?
You can do it using a \Slim\Container instance:
// Create container
$container = new \Slim\Container;
// Register component on container
$container['view'] = function ($c) {
$view = new \Slim\Views\Twig('your/path/to/templates');
$view->addExtension(new \Slim\Views\TwigExtension(
$c['router'],
$c['request']->getUri()
));
return $view;
};
Then you can use it:
$app = new \Slim\App($container);
// The route
$app->get('/foo', function (ServerRequestInterface $request, ResponseInterface $response) {
return $this->view->render($response, 'index.html', [
'name' => 'name'
]);
});
$app->run();
Check the official documentation (Mika Tuupola's suggestion).
Related
I'm trying to add twig-view in slim v4
In slim v3, we add twig-view in container
$container['view'] = function ($c) {
$view = new \Slim\Views\Twig('path/to/templates', [
'cache' => 'path/to/cache'
]);
// Instantiate and add Slim specific extension
$router = $c->get('router');
$uri = \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER));
$view->addExtension(new \Slim\Views\TwigExtension($router, $uri));
return $view;
};
but I can't add twig like that in slim v4
Update: Twig-View has reached a stable version and the docs are updated to address Slim 4 integration.
If you are still using an unstable version of Twig-View, please consider upgrading.
First, you need to add Twig-View package to your project:
composer require slim/twig-view
And assuming the following directory structure:
composer.json
cache/
public/
|--index.php
templates/
|--hello.twig
vendor/
|--autoload.php
The followings are two working examples:
If you use a container (which is optional according to Slim 4 docs), you can add Tiwg creation definition to the container and use it when required. (I'm using php-di/php-di in this example, but you can use any PSR compatible dependency container.)
index.php, using a container:
<?php
use DI\Container;
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
require __DIR__ . '/../vendor/autoload.php';
// Create Container
$container = new Container();
AppFactory::setContainer($container);
// Set view in Container
$container->set('view', function() {
return Twig::create(__DIR__ . '/../templates',
['cache' => __DIR__ . '/../cache']);
});
// Create App
$app = AppFactory::create();
// Add Twig-View Middleware
$app->add(TwigMiddleware::createFromContainer($app));
// Example route
$app->get('/hello/{name}', function ($request, $response, $args) {
return $this->get('view')->render($response, 'hello.twig', [
'name' => $args['name']
]);
});
// Run the app
$app->run();
You can also skip the container creation, but in that case you need to create the Twig instance before trying to render a template.
index.php, without a container:
<?php
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
require __DIR__ . '/../vendor/autoload.php';
// Create App
$app = AppFactory::create();
// Create Twig
$twig = Twig::create(__DIR__ . '/../templates',
['cache' => __DIR__ . '/../cache']);
// Add Twig-View Middleware
$app->add(TwigMiddleware::create($app, $twig));
// Example route
// Please note how $view is created from the request
$app->get('/hello/{name}', function ($request, $response, $args) {
$view = Twig::fromRequest($request);
return $view->render($response, 'hello.twig', [
'name' => $args['name']
]);
});
// Run the app
$app->run();
hello.twig:
Hello {{ name }}
Now try visiting /hello/slim4 in your browser and the output will be:
Hello slim4
SlimTwigView is at 3.0.0 beta (at least as of October 12, 2019), and some things have changed. The few online tutorials I've seen, as well as the official documentation no longer work.
TwigMiddleware no longer takes an instance of the $container as an argument, so you must first put Twig on the Container manually such as:
$container->set('view', function() {
// Of course put correct path to your views here
return new Twig('../views', ['cache' => false]);
});
You then you can add TwigMiddleware to your Slim App using the class' new createFromContainer method, like so:
$app->add(TwigMiddleware::createFromContainer($app));
// which is equivalent to:
// $app->add(TwigMiddleware::createFromContainer($app, 'view'));
At that point, you can render a Twig view like so:
$app->get('/', function (Request $request, Response $response, $args) {
return $this->get('view')->render($response, 'home.twig');
});
When using the Slim specific middleware, you now have access to the additional Twig extensions:
url_for
full_url_for
is_current_url
current_url
get_uri
Well! In my case I was using Slim 4.0 and Twig ^2.5. All I added to my code was
$container->set('view', function () use ($container) {
$view = new \Slim\Views\Twig(
__DIR__ .'/Templates'
, [ 'cache' => false ] //you can turn on caching by providing string path to cache or set to false
);
return $view;
});
What does Container->get('route') method returns and why
It is used in twig extension with slim
The Slim Twig extension requires the router (not the route) instance for the custom template functions like path_for() and base_url().
Example:
// Register Twig View helper
$container['view'] = function ($c) {
$view = new \Slim\Views\Twig('path/to/templates', [
'cache' => 'path/to/cache'
]);
// Instantiate and add Slim specific extension
$router = $c->get('router');
$uri = \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER));
$view->addExtension(new \Slim\Views\TwigExtension($router, $uri));
return $view;
};
Please read the slimphp/Twig-View documentation.
I'm working thru a tutorial on the Slim framework. The author uses Twig, and I'd prefer to use the Plates template engine. I've been able to modify all lessons to use the Plates template, until the author started using baseUrl and pathFor extensions.
I see that Plates has an extension called URI, which I think is synonymous with Twig's pathFor.
Unfortunately, I can't for the life of me figure out how to get it enabled. Reading the documentation, I thought the following code would do it, but so far no luck.
require 'vendor/autoload.php';
$app = new Slim\App([
'settings' => [
'displayErrorDetails' => true
]
]);
$container = $app->getContainer();
$container['view'] = function ($container) {
$plates = new League\Plates\Engine(__DIR__ . '/templates');
$plates->loadExtension(new League\Plates\Extension\URI($_SERVER['PATH_INFO']));
return $plates;
};
$app->get('/contact', function($request, $response) {
return $this->view->render('contact');
});
$app->post('/contact', function($request, $response) {
return $response->withRedirect('http://slim-local.com/contact/confirm');
})->setName('contact');
$app->get('/contact/confirm', function($request, $response) {
return $this->view->render('contact_confirm');
});
$app->run();
And then in the template, the author used the pathFor extension to populate a form's action parameter. I am trying to use Plates' URI extention to do the same like so:
<form action="<?=$this->uri('contact')?>" method="post">
Has anybody used this template engine and the URI extension with Slim specifically? Am I mistaken that it is basically synonymous with Twig's pathFor extension? Should I give up and just use Twig? thanks for your advice.
You can use the URI from the environment.
Slim 3 example:
$container['view'] = function ($container) {
$plates = new \League\Plates\Engine(__DIR__ . '/templates');
$uri = \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER));
$plates->loadExtension(new \League\Plates\Extension\URI($uri->__toString()));
return $plates;
};
http://www.slimframework.com/docs/tutorial/first-app.html shows using "plain old PHP" (Composer package is php-view and class is PhpRenderer) for templates as follows:
<?php
// Create app
$app = new \Slim\App();
// Get container
$container = $app->getContainer();
$container['view'] = new \Slim\Views\PhpRenderer("../templates/");
$app->get('/tickets', function (Request $request, Response $response) {
$this->logger->addInfo("Ticket list");
$mapper = new TicketMapper($this->db);
$tickets = $mapper->getTickets();
$response = $this->view->render($response, "tickets.phtml", ["tickets" => $tickets]);
return $response;
});
// Run app
$app->run();
The above page states using Twig for templates is basically the same, but http://www.slimframework.com/docs/features/templates.html shows a very different approach. Which is the correct way to use templates, and specifically how should I use Twig for templates?
<?php
// Create app
$app = new \Slim\App();
// Get container
$container = $app->getContainer();
// Register component on container
$container['view'] = function ($container) {
$view = new \Slim\Views\Twig('path/to/templates', [
'cache' => 'path/to/cache'
]);
$view->addExtension(new \Slim\Views\TwigExtension(
$container['router'],
$container['request']->getUri()
));
return $view;
};
// Render Twig template in route
$app->get('/hello/{name}', function ($request, $response, $args) {
return $this->view->render($response, 'profile.html', [
'name' => $args['name']
]);
})->setName('profile');
// Run app
$app->run();
I have installed slim framework 3 and twig template following the composer.
When i call function http://localhost/elec/helloo/sandesh it displays Hello, Sandesh as followed on slim 3 documentation.
But when i try to call view page(inside templates folder).
It displays an error page Slim Application Error The application could not run because of the following error Error Description
Code Worked ( displays hello , {name} from function)
$app = new \Slim\App;
$app->get('/hello/{name}', function (Request $request, Response $response) {
$name = $request->getAttribute('name');
$response->getBody()->write("Hello, $name");
return $response;
});
Code error ( displays error when called view page from function)
$settings = [
'settings' => [
'displayErrorDetails' => true,
],
];
$app = new Slim\App($settings);
// Get container
$container = $app->getContainer();
// Register component on container
$container['view'] = function ($container) {
return new \Slim\Views\PhpRenderer("templates/");
};
// Render Twig template in route
$app->get('/helloo/{name}', function ($request, $response, $args) {
return $this->view->render($response, 'view1.html', [
'name' => $args['name']
]);
})->setName('profile');
Path Detail
elec>
>>cache
>>templates
>>>view1.html
>>vender
>>.htaccess
>>composer.json
>>composer.lock
>>index.php
When passing the templates location, you have to provide a full path, (starting from the location of the running index.php file:
<?php
$container['view'] = function ($container) {
return new \Slim\Views\PhpRenderer(__DIR__ . "/../path/to/templates/");
};
try it out, and good luck.
Note: I'm using the same line but with Twig render:
<?php
$container['view'] = function ($container) {
return new \Slim\Views\Twig(__DIR__ . "/../path/to/templates/");
};
$app = new \Slim\App([
'settings' => [
'displayErrorDetails' => true,
]
]);
// Calling twigview from controller
$container = $app->getContainer();
// Register component on container
$container['view'] = function ($container) {
$view = new \Slim\Views\Twig('templates/views',[
'cache' => false,
]);
$view->addExtension(new \Slim\Views\TwigExtension(
$container->router,
$container->request->getUri()
));
return $view;
};
$app->get('/home', function ($request, $response) {
return $this->view->render($response, 'home.twig');
});