如何在Silex中使用Twig的PHP模板引擎而不是Twig语法?

6
在Silex中,我可以使用Twig模板,但我想使用Twig的PHP引擎,而不是Twig语法。例如,这个指南说明了如何在Symfony中实现,但没有提到Silex。
我的Silex index.php如下:
$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',
    ));
});

我的 index.html.php 文件看起来像这样:

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

当我在浏览器中运行应用程序并查看源代码时,我看到了文字字符串<?php echo $view->name; ?>,它尚未被执行。
我怀疑可能有一个Twig配置设置,告诉它我想使用PHP风格的模板。为了澄清,如果我改用Twig语法,例如:
<p>Welcome to the index {{ name }} </p>

然后它起作用了,我看到了名字为 Bob,因此我知道这不是一个网络服务器或PHP配置问题。

1个回答

7

如果你想在Silex中模仿这种行为,你需要通过Composer安装TwigBridge。然后按照Symfony的方式构建templating服务。

我已经成功测试过这个解决方案。

<?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();

您需要在composer.json中至少添加以下依赖项才能实现此目标:

"require": {
    "silex/silex": "~1.0",
    "symfony/twig-bridge": "~2.0",
    "symfony/templating": "~2.0",
    "twig/twig": "~1.0"
},

+1 感谢详细的回答。是否可以手动复制所需文件,而不使用Composer? - ServerBloke
@ServerBloke 没问题,Composer 会自动帮你解决的。我已经在答案中添加了你需要在 composer.json 中的内容。 - Adam Elsodaney
谢谢,接受了你的答案。Composer会把我需要的文件拉到项目里吗?我不熟悉它,但如果它比手动复制文件更好,我会研究一下的。 - ServerBloke
1
谢谢,这非常有帮助!我将其包装在自己的ServiceProvider中,并设置了一个$app ['root.views']路径来全局配置模板的位置。 - dazz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接