6

In Silex I am able to use Twig templates but I want to use the PHP engine of Twig, instead of the Twig syntax. For example this guide describes how to do it for Symfony but not Silex.

My Silex index.php looks like:

$app->register(new Silex\Provider\TwigServiceProvider(), array(
    'twig.path' => __DIR__.'/views',
));

$app->get('/', function() use ($app) {
    return $app['twig']->render('index.html.php', array(
        'name' => 'Bob',
    ));
});

My index.html.php looks like:

<p>Welcome to the index <?php echo $view->name; ?></p>

When I run the app in the browser and view the source, I see the literal string <?php echo $view->name; ?> which hasn't been executed.

I suspect there may be a Twig config setting to tell it I want to use the PHP style templates. To clarify, if I use the Twig syntax instead, e.g.:

<p>Welcome to the index {{ name }} </p>

Then it works and I see the name Bob, therefore I know this is not a web server or PHP config problem.

1 Answer 1

7

If you want to mimic this behaviour in Silex, you would need to install the TwigBridge via Composer. Then build the templating service the same way Symfony does.

This solution works as I have tested it successfully.

<?php

require __DIR__.'/vendor/autoload.php';

use Silex\Application;
use Symfony\Component\Templating\PhpEngine;
use Symfony\Component\Templating\TemplateNameParser;
use Symfony\Component\Templating\Loader\FilesystemLoader;
use Symfony\Component\Templating\DelegatingEngine;
use Symfony\Bridge\Twig\TwigEngine;

$app = new Application();

$app['debug'] = true;

// Register Twig

$app->register(new Silex\Provider\TwigServiceProvider(), array(
    'twig.path' => __DIR__.'/views',
));


// Build the templating service

$app['templating.engines'] = $app->share(function() {
    return array(
        'twig',
        'php'
    );
});

$app['templating.loader'] = $app->share(function() {
    return new FilesystemLoader(__DIR__.'/views/%name%');
});

$app['templating.template_name_parser'] = $app->share(function() {
    return new TemplateNameParser();
});

$app['templating.engine.php'] = $app->share(function() use ($app) {
    return new PhpEngine($app['templating.template_name_parser'], $app['templating.loader']);
});

$app['templating.engine.twig'] = $app->share(function() use ($app) {
    return new TwigEngine($app['twig'], $app['templating.template_name_parser']);
});

$app['templating'] = $app->share(function() use ($app) {
    $engines = array();

    foreach ($app['templating.engines'] as $i => $engine) {
        if (is_string($engine)) {
            $engines[$i] = $app[sprintf('templating.engine.%s', $engine)];
        }
    }

    return new DelegatingEngine($engines);
});


// Render controllers

$app->get('/', function () use ($app) {
    return $app['templating']->render('hello.html.twig', array('name' => 'Fabien'));
});

$app->get('/hello/{name}', function ($name) use ($app) {
    return $app['templating']->render('hello.html.php', array('name' => $name));
});

$app->run();

You would need at least these dependencies to achieve this in your composer.json

"require": {
    "silex/silex": "~1.0",
    "symfony/twig-bridge": "~2.0",
    "symfony/templating": "~2.0",
    "twig/twig": "~1.0"
},
Sign up to request clarification or add additional context in comments.

4 Comments

+1 Thanks for the detailed answer. Is it possible to manually copy the necessary files instead of using Composer?
@ServerBloke np, Composer will do it for you. I've added what you would need in your composer.json to the answer.
Thanks, accepted your answer. Will Composer just pull the files I need into the project? I'm not familiar with it but will look into it if it's better than manually copying the files.
Thank you, this helped a lot! I wrapped it in it's own ServiceProvider and set an $app['root.views'] path to globally configure where the templates are.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.