Skip to content

Instantly share code, notes, and snippets.

@maxgalbu
Last active December 31, 2019 16:03
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save maxgalbu/9409182 to your computer and use it in GitHub Desktop.
Save maxgalbu/9409182 to your computer and use it in GitHub Desktop.
Switch tag for Twig, updated from https://github.com/fabpot/Twig/pull/185 to work with Twig >= 1.12
<?
include_once("base/Twig/Autoloader.php");
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem('templates');
$twig = new Twig_Environment($loader, array());
//Add the Switch token parser
$twig->addTokenParser(new Twig_TokenParser_Switch());
?>
{% set test = 1 %}
{% set othervar = 2 %}
{% switch test %}
{% case 1 %}
test is 1
{% case 2 %}
{% if othervar == 2 %}
test is 2
{% else %}
test is 2
{% endif %}
{% case 0 %}
test is 2
{% endswitch %}
<?php
//To be added under Twig/Node/Switch.php
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Represents an if node.
*
* @package twig
* @author Dsls
* @author maxgalbu
*/
class Twig_Node_Switch extends Twig_Node
{
public function __construct(Twig_NodeInterface $value, Twig_NodeInterface $cases, Twig_NodeInterface $default = null, $lineno, $tag = null)
{
parent::__construct(array('value' => $value, 'cases' => $cases, 'default' => $default), array(), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
$compiler
->write("switch (")
->subcompile($this->getNode('value'))
->raw(") {\n")
->indent
;
for ($i = 0; $i < count($this->getNode('cases')); $i += 2) {
$compiler
->write('case ')
->subcompile($this->getNode('cases')->getNode($i))
->raw(":\n")
->indent()
->subcompile($this->getNode('cases')->getNode($i + 1))
->addIndentation()
->raw("break;\n")
;
}
if ($this->hasNode('default') && null !== $this->getNode('default')) {
$compiler
->write("default:\n")
->indent()
->subcompile($this->getNode('default'))
->addIndentation()
->raw("break;\n")
;
}
$compiler
->outdent()
->write("}\n");
}
}
<?php
//To be added under Twig/TokenParser/
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_TokenParser_Switch extends Twig_TokenParser
{
/**
* Parses a token and returns a node.
*
* @param Twig_Token $token A Twig_Token instance
*
* @return Twig_NodeInterface A Twig_NodeInterface instance
*/
public function parse(Twig_Token $token)
{
$parser = $this->parser;
$stream = $parser->getStream();
$default = null;
$cases = array();
$end = false;
$name = $parser->getExpressionParser()->parseExpression();
$stream->expect(Twig_Token::BLOCK_END_TYPE);
$stream->expect(Twig_Token::TEXT_TYPE);
$stream->expect(Twig_Token::BLOCK_START_TYPE);
while (!$end)
{
$v = $stream->next();
switch ($v->getValue()) {
case 'default':
$stream->expect(Twig_Token::BLOCK_END_TYPE);
$default = $parser->subparse(array($this, 'decideIfEnd'));
break;
case 'case':
$expr = $parser->getExpressionParser()->parseExpression();
$stream->expect(Twig_Token::BLOCK_END_TYPE);
$body = $parser->subparse(array($this, 'decideIfFork'));
$cases[] = $expr;
$cases[] = $body;
break;
case 'endswitch':
$end = true;
break;
default:
throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "case", "default", or "endswitch" to close the "switch" block started at line %d)', $lineno), -1);
}
}
$stream->expect(Twig_Token::BLOCK_END_TYPE);
return new Twig_Node_Switch($name,new Twig_Node($cases), $default, $token->getLine(), $this->getTag());
}
public function decideIfFork($token)
{
return $token->test(array('case', 'default', 'endswitch'));
}
public function decideIfEnd($token)
{
return $token->test(array('endswitch'));
}
/**
* Gets the tag name associated with this token parser.
*
* @param string The tag name
*/
public function getTag()
{
return 'switch';
}
}
@thaian2009
Copy link

public function compile(Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
$compiler
->write("switch (")
->subcompile($this->getNode('value'))
->raw(") {\n")
->indent
-------------------------------change to----------------------
public function compile(Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
$compiler
->write("switch (")
->subcompile($this->getNode('value'))
->raw(") {\n")
->indent()

@mnpenner
Copy link

Twig_Node_Switch is showing a lot of errors in the latest Twig... any update on this? e.g. the constructor is incompatible with Twig_Node and ->indent is undefined. $token->test() is not defined, $lineno is not defined...

@celtic34fr
Copy link

Hi,
I'm currently using your code to implement the switch tag in my template.
Now I try to adapt it to Twig 2.0, but I fail. I can not even make a trace with xDebug.
Could you help me make the code functional? And give me the elements to understand the implementation of tags, which remains to me mysterious.
i obtains an Error code 500 without anymore informations

Gilbert ARMENGAUD
(celtic34fr)
Béziers (Occitanie, France)

@Esty1
Copy link

Esty1 commented Nov 21, 2018

Hi
I try to use this node but I got an error:
Fatal error: Uncaught Error: Class 'Twig_TokenParser_Switch' not found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment