在Symfony 2中使用Moustache作为模板语言

11

我开始使用Symfony 2,但我想使用Moustache作为模板语言,而不是Twig或PHP。我想使用Moustache是因为它完全没有逻辑,如果我决定在客户端处理模板渲染,我也可以在JavaScript中使用它。

怎样才能实现这个目标呢?


我一直想完成这个项目已经有一段时间了... https://github.com/bobthecow/BobthecowMustacheBundle 欢迎 fork 并提供帮助。 - bobthecow
@bobthecow 我fork了它,我对Symfony2相当新,我认为我需要一些时间来理解一切,尤其是因为这是我在业余时间完成的,无论如何感谢你! :) - Nicola Peluchetti
截至最新的提交,我的包与Symfony2 v2.1.0-DEV兼容 :) - bobthecow
你也可以尝试使用这个捆绑包:https://github.com/BeSimple/BeSimpleMustacheBundle - Marius Balčytis
2个回答

29

补充@m2mdas的答案:

如果您还不熟悉Symfony模板系统和Bundle配置,请在开始编码之前查看以下内容:

现在,这里有一个快速的入门方式。以下内容仅供松散参考,可以自己选择命名。

1. 创建一个Resources/config/mustache.xml文件,定义您的服务并标识模板引擎服务(将其标记为"templating.engine")。

您可以使用Yaml和PHP代替XML,但后者更适合“公共”Bundle。

<service id="mustache" class="Mustache">
    <file>Mustache.php</file>
</service>

<service id="templating.engine.mustache" class="MustacheBundle\MustacheEngine" public="false">
        <argument type="service" id="mustache" />
        <argument type="service" id="templating.name_parser"/>
        <argument type="service" id="templating.loader" />
        <tag name="templating.engine" />
</service>

示例:

2. 创建一个扩展类来处理您的捆绑语义配置。

<?php

namespace MustacheBundle;

use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;

class MustacheExtension extends Extension
{
    $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
    $loader->load('mustache.xml');

    // you may parse the $configs array here
    // see: http://symfony.com/doc/current/cookbook/bundles/extension.html#parsing-the-configs-array
}

之前的类存在意味着您现在可以在任何配置文件中定义一个mustache配置命名空间。

示例:

3. [可选] 创建一个Configuration类来验证和合并配置。

<?php

namespace Mustache\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('mustache');

        // see: http://symfony.com/doc/current/cookbook/bundles/extension.html#validation-and-merging-with-a-configuration-class
    }
}

示例:

4. 创建一个实现EngineInterfaceMustacheEngine

<?php

namespace MustacheBundle;

use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Component\Templating\TemplateNameParserInterface;
use Symfony\Component\Templating\Loader\LoaderInterface;

use Symfony\Component\HttpFoundation\Response;

class MustacheBundle implements EngineInterface
{
    public function __construct(\Mustache $mustache, TemplateNameParserInterface $parser, LoaderInterface $loader)
    {
        $this->mustache = $mustache;
        $this->parser = $parser;
    }

    public function render($name, array $parameters = array())
    {
        $template = $this->load($name);

        return $this->mustache->render($template);
    }

    // Renders a view and returns a Response.
    public function renderResponse($view, array $parameters = array(), Response $response = null)
    {
        if (null === $response) {
            $response = new Response();
        }

        $response->setContent($this->render($view, $parameters));

        return $response;
    }

    // Returns true if the template exists.
    public function exists($name)
    {
        try {
            $this->load($name);
        } catch (\InvalidArgumentException $e) {
            return false;
        }

        return true;
    }

    // Returns true if this class is able to render the given template.
    public function supports($name)
    {
        $template = $this->parser->parse($name);

        return 'mustache' === $template->get('engine');
    }

    // Loads the given template.
    // Should return the template name or a Mustache template object
    protected function load($name)
    {
        $template = $this->parser->parse($name);
        $template = $this->loader->load($template);

        return (string) $template;
    }

5. 在应用程序的配置文件中启用新的模板引擎:

# app/config/config.yml
templating:    { engines: ['twig', 'mustache'] }

6. 尝试一下

<?php
// src/Acme/HelloBundle/Controller/HelloController.php

public function indexAction($name)
{
    return $this->render('AcmeHelloBundle:Hello:index.html.mustache', array('name' => $name));
}

您可以分享您的bundle存储库链接,以便我们跟踪进度,并在需要时提供帮助。祝你好运。


谢谢,这是一个非常好的答案,我一写完代码就会发布(我在我的个人项目中使用Symfony2!) :) - Nicola Peluchetti
1
noisebleed:写得非常好。它帮了我很多的忙 :) — https://github.com/bobthecow/BobthecowMustacheBundle - bobthecow

5

您需要创建一个类来实现 EngineInterface,并创建名为 templating.engine.mustache 的 DIC 服务以引用该类。然后在 app/config.yml 中,您可以设置默认引擎。

#app/config.yml
framework:
  #.....
  templating:
      engines: ['mustache'] //mustache is the last portion of the service id 

作为参考,您可以查看PhpEngine类及其服务定义


1
这个。我有一个完成了80%的...如果你想玩一下,我可以发布它 :) - bobthecow

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