Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Moustache as a templating language in Symfony 2

I'm starting to use symfony 2 but I'd like to use moustache as the templating language instead of Twig or PHP. I wan't to use moustache because it's totally logicless and because I can also use it in javascript if I decide to handle the rendering of the template clientside.

How to do that?

like image 813
Nicola Peluchetti Avatar asked Apr 01 '12 15:04

Nicola Peluchetti


2 Answers

Some extra info extending @m2mdas answer.

If you are not yet familiar with Symfony templating systems and bundle configuration take a look at these before you start coding:

  • How to expose a Semantic Configuration for a Bundle
  • Creating and using Templates
  • How to use PHP instead of Twig for Templates

And now a quick recipe to get you started. Take the following as loose examples, no need to stick with the names choosed.

1. Create a Resources/config/mustache.xml to define your services and to identify your template engine service (tag it as "templating.engine").

You could use Yaml and PHP instead of XML but the latter is prefered for "public" bundles.

<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>

Examples:

  • Twig
  • PHP
  • Smarty

2. Create an Extension class to handle the semantic configuration for your bundle.

<?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
}

The presence of the previous class means that you can now define a mustache configuration namespace in any configuration file.

Examples:

  • Twig
  • Smarty

3. [Optional] Create a Configuration class to validate and merge 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
    }
}

Examples:

  • Twig
  • Smarty

4. Create a MustacheEngine that implements EngineInterface

<?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;
    }

Examples:

  • Twig
  • PHP
  • Smarty

5. Enable your shiny new template engine in the application configuration file:

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

6. Try it

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

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

You may share a link to your bundle repository so we can track progress and help if needed. Good luck.

like image 61
noisebleed Avatar answered Sep 23 '22 13:09

noisebleed


You have to create a class that implements EngineInterface and create create a DIC service named templating.engine.mustache to reference the class. And then in app/config.yml you can set default engine.

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

For reference you can check PhpEngine class and its service definition.

like image 27
Mun Mun Das Avatar answered Sep 19 '22 13:09

Mun Mun Das