8

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

Nima
  • 3,309
  • 6
  • 27
  • 44
mk990
  • 103
  • 1
  • 1
  • 9

3 Answers3

16

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

Nima
  • 3,309
  • 6
  • 27
  • 44
  • 1
    Slim 4 is not alpha. Stable version was released two weeks ago at the time of writing. – Álvaro González Aug 14 '19 at 15:26
  • I had some problems because of composer version. Using v 2.0.12 it doesn't correctly handle autoloading. Upgrading composer to v 2.2.9 solved such problems. – CapelliC Mar 25 '22 at 19:39
5

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
ConleeC
  • 337
  • 6
  • 13
  • If anyone is stuck here and doesn't get ```TwigMiddleware```, and if you have installed the latest Slim, you need to ensure you're installing ```"slim/twig-view": "3.0.0-beta"``` to get ```TwigMiddleware```, then for me I had to ```new Twig('../views'``` to ```new Twig(__DIR__ . '/../resources/views'``` – Michael Millar Dec 04 '19 at 21:56
0

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;
});
halfer
  • 19,824
  • 17
  • 99
  • 186
Talha
  • 1,546
  • 17
  • 15
  • 1
    Hi there. I was not sure whether this was an answer with an additional question, or whether it was just a question. I order for it not to be removed by the Review Queue, I have opted for the former. If you still want to ask your question, it is in [the edit history](https://stackoverflow.com/posts/59351485/revisions). That part would be better added as a new question. – halfer Feb 16 '20 at 18:48