mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-28 06:08:52 +00:00
[feature/twig] Replace phpBB template code with Twig syntax, then parse w/Twig
Fixing begin token/node, adding includejs token/node PHPBB3-11598
This commit is contained in:
parent
b775f67128
commit
15114067e6
6 changed files with 146 additions and 67 deletions
|
@ -26,10 +26,11 @@ class phpbb_template_twig_extension extends Twig_Extension
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
new phpbb_template_twig_tokenparser_if,
|
new phpbb_template_twig_tokenparser_if,
|
||||||
new phpbb_template_twig_tokenparser_include,
|
|
||||||
new phpbb_template_twig_tokenparser_event,
|
|
||||||
new phpbb_template_twig_tokenparser_begin,
|
new phpbb_template_twig_tokenparser_begin,
|
||||||
new phpbb_template_twig_tokenparser_define,
|
new phpbb_template_twig_tokenparser_define,
|
||||||
|
new phpbb_template_twig_tokenparser_include,
|
||||||
|
new phpbb_template_twig_tokenparser_includejs,
|
||||||
|
new phpbb_template_twig_tokenparser_event,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +40,6 @@ class phpbb_template_twig_extension extends Twig_Extension
|
||||||
array(),
|
array(),
|
||||||
array(
|
array(
|
||||||
'eq' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'eq' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
//'and' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
|
||||||
'!==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'!==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -17,62 +17,41 @@ if (!defined('IN_PHPBB'))
|
||||||
|
|
||||||
class phpbb_template_twig_lexer extends Twig_Lexer
|
class phpbb_template_twig_lexer extends Twig_Lexer
|
||||||
{
|
{
|
||||||
protected function lexExpression()
|
public function tokenize($code, $filename = null)
|
||||||
{
|
{
|
||||||
var_dump(substr($this->code, $this->cursor, 40), $this->states);
|
$valid_starting_tokens = array(
|
||||||
parent::lexExpression();
|
'BEGIN',
|
||||||
|
'BEGINELSE',
|
||||||
|
'END',
|
||||||
|
'IF',
|
||||||
|
'ELSE',
|
||||||
|
'ELSEIF',
|
||||||
|
'ENDIF',
|
||||||
|
'DEFINE',
|
||||||
|
'DEFINE',
|
||||||
|
'UNDEFINE',
|
||||||
|
'ENDDEFINE',
|
||||||
|
/*'INCLUDE',
|
||||||
|
'INCLUDEPHP',
|
||||||
|
'INCLUDEJS',*/
|
||||||
|
'PHP',
|
||||||
|
'ENDPHP',
|
||||||
|
'EVENT',
|
||||||
|
);
|
||||||
|
|
||||||
// Last element parsed
|
// Replace <!-- INCLUDE blah.html --> with {% include 'blah.html' %}
|
||||||
$last_element = end($this->tokens);
|
$code = preg_replace('#<!-- INCLUDE(PHP|JS)? (.*?) -->#', "{% INCLUDE$1 '$2' %}", $code);
|
||||||
|
|
||||||
/**
|
// Replace all of our starting tokens, <!-- TOKEN --> with Twig style, {% TOKEN %}
|
||||||
* Check for old fashioned INCLUDE statements without enclosed quotes
|
// This also strips the $ inside of a tag directly after the token, which was used in <!-- DEFINE $NAME
|
||||||
*/
|
// This also strips the . inside of a tag directly after the token, which was used in <!-- IF .blah
|
||||||
if ($last_element->getValue() === 'INCLUDE')
|
// This also strips outer parenthesis, <!-- IF (blah) --> becomes <!-- IF blah -->
|
||||||
{
|
$code = preg_replace('#<!-- (' . implode('|', $valid_starting_tokens) . ') (not )?(\$|\.)?(?:(.*?) ?)?-->#', '{% $1 $2$4 %}', $code);
|
||||||
if (preg_match('#^\s*([a-zA-Z0-9_]+\.[a-zA-Z0-9]+)#', substr($this->code, $this->cursor), $match))
|
|
||||||
{
|
|
||||||
$this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1]));
|
|
||||||
$this->moveCursor($match[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// Replace all of our variables, {VARNAME} or {$VARNAME}, with Twig style, {{ VARNAME }}
|
||||||
* This is some compatibility code to continue supporting expressions such as:
|
$code = preg_replace('#{\$?([A-Z_][A-Z_0-9]+)}#', '{{ $1 }}', $code);
|
||||||
* <!-- IF .blah -->
|
//echo $code;
|
||||||
*/
|
//exit;
|
||||||
if ($last_element->getValue() === 'IF')
|
return parent::tokenize($code, $filename);
|
||||||
{
|
|
||||||
if (preg_match('#^\s*(not\s)?\.([a-zA-Z0-9_\.]+)#', substr($this->code, $this->cursor), $match))
|
|
||||||
{
|
|
||||||
$this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1]));
|
|
||||||
$this->moveCursor($match[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is some compatibility code to continue supporting expressions such as:
|
|
||||||
* <!-- DEFINE $VAR = 'foo' -->
|
|
||||||
*/
|
|
||||||
if ($last_element->getValue() === 'DEFINE')
|
|
||||||
{
|
|
||||||
if (preg_match('#^\s*\$([A-Z0-9]+)#', substr($this->code, $this->cursor), $match))
|
|
||||||
{
|
|
||||||
$this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1]));
|
|
||||||
$this->moveCursor($match[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check for old fashioned INCLUDE statements without enclosed quotes
|
|
||||||
*/
|
|
||||||
if ($last_element->getValue() === 'INCLUDE')
|
|
||||||
{
|
|
||||||
if (preg_match('#^\s*([a-zA-Z0-9_]+\.[a-zA-Z0-9]+)#', substr($this->code, $this->cursor), $match))
|
|
||||||
{
|
|
||||||
$this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1]));
|
|
||||||
$this->moveCursor($match[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,40 +31,41 @@ class phpbb_template_twig_node_begin extends Twig_Node
|
||||||
public function compile(Twig_Compiler $compiler)
|
public function compile(Twig_Compiler $compiler)
|
||||||
{
|
{
|
||||||
$compiler
|
$compiler
|
||||||
->write("if (!isset(\$blocks)) {\n")
|
->write("if (!isset(\$loops)) {\n")
|
||||||
->indent()
|
->indent()
|
||||||
->write("\$blocks = array();")
|
->write("\$loops = array();")
|
||||||
->write("\$nestingLevel = 0;")
|
->write("\$nestingLevel = 0;")
|
||||||
->outdent()
|
->outdent()
|
||||||
->write("}\n")
|
->write("}\n")
|
||||||
->write("\$blocks[\$nestingLevel] = array();\n")
|
->write("\$loops[\$nestingLevel] = array();\n")
|
||||||
;
|
;
|
||||||
|
|
||||||
if (null !== $this->getNode('else')) {
|
if (null !== $this->getNode('else')) {
|
||||||
$compiler->write("\$blocks[\$nestingLevel]['iterated'] = false;\n");
|
$compiler->write("\$loops[\$nestingLevel]['iterated'] = false;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
$compiler
|
$compiler
|
||||||
->write("foreach (\$context['_phpbb_blocks']['")
|
->write("if (isset(\$context['loop'])) {")
|
||||||
|
->write("foreach (\$context['loop']['")
|
||||||
->write($this->getAttribute('beginName'))
|
->write($this->getAttribute('beginName'))
|
||||||
->write("'] as \$blocks[\$nestingLevel]['i'] => \$blocks[\$nestingLevel]['values']) {")
|
->write("'] as \$loops[\$nestingLevel]['i'] => \$loops[\$nestingLevel]['values']) {")
|
||||||
->indent()
|
->indent()
|
||||||
;
|
;
|
||||||
|
|
||||||
$compiler->subcompile($this->getNode('body'));
|
$compiler->subcompile($this->getNode('body'));
|
||||||
|
|
||||||
if (null !== $this->getNode('else')) {
|
if (null !== $this->getNode('else')) {
|
||||||
$compiler->write("\$blocks[\$nestingLevel]['iterated'] = true;\n");
|
$compiler->write("\$loops[\$nestingLevel]['iterated'] = true;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
$compiler
|
$compiler
|
||||||
->outdent()
|
->outdent()
|
||||||
->write("}\n")
|
->write("}}\n")
|
||||||
;
|
;
|
||||||
|
|
||||||
if (null !== $this->getNode('else')) {
|
if (null !== $this->getNode('else')) {
|
||||||
$compiler
|
$compiler
|
||||||
->write("if (!\$blocks[\$nestingLevel]['iterated']) {\n")
|
->write("if (!\$loops[\$nestingLevel]['iterated']) {\n")
|
||||||
->indent()
|
->indent()
|
||||||
->subcompile($this->getNode('else'))
|
->subcompile($this->getNode('else'))
|
||||||
->outdent()
|
->outdent()
|
||||||
|
|
50
phpBB/includes/template/twig/node/includejs.php
Normal file
50
phpBB/includes/template/twig/node/includejs.php
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?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 include node.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class phpbb_template_twig_node_includejs extends Twig_Node_Include
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Compiles the node to PHP.
|
||||||
|
*
|
||||||
|
* @param Twig_Compiler A Twig_Compiler instance
|
||||||
|
*/
|
||||||
|
public function compile(Twig_Compiler $compiler)
|
||||||
|
{
|
||||||
|
$compiler->addDebugInfo($this);
|
||||||
|
|
||||||
|
$compiler
|
||||||
|
->write("try {\n")
|
||||||
|
->indent()
|
||||||
|
;
|
||||||
|
|
||||||
|
$this->addGetTemplate($compiler);
|
||||||
|
|
||||||
|
$compiler->raw('->display(');
|
||||||
|
|
||||||
|
$this->addTemplateArguments($compiler);
|
||||||
|
|
||||||
|
$compiler->raw(");\n");
|
||||||
|
|
||||||
|
$compiler
|
||||||
|
->write("} catch (Twig_Error_Loader \$e) {\n")
|
||||||
|
->indent()
|
||||||
|
->write("// ignore missing template\n")
|
||||||
|
->outdent()
|
||||||
|
->write("}\n\n")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ class phpbb_template_twig_tokenparser_begin extends Twig_TokenParser_For
|
||||||
|
|
||||||
$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
|
$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
|
||||||
$body = $this->parser->subparse(array($this, 'decideBeginFork'));
|
$body = $this->parser->subparse(array($this, 'decideBeginFork'));
|
||||||
if ($this->parser->getStream()->next()->getValue() == 'ELSE') {
|
if ($this->parser->getStream()->next()->getValue() == 'BEGINELSE') {
|
||||||
$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
|
$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
|
||||||
$else = $this->parser->subparse(array($this, 'decideBeginEnd'), true);
|
$else = $this->parser->subparse(array($this, 'decideBeginEnd'), true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -54,7 +54,7 @@ class phpbb_template_twig_tokenparser_begin extends Twig_TokenParser_For
|
||||||
return $token->test(array('BEGINELSE', 'END'));
|
return $token->test(array('BEGINELSE', 'END'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function decideForEnd(Twig_Token $token)
|
public function decideBeginEnd(Twig_Token $token)
|
||||||
{
|
{
|
||||||
return $token->test('END');
|
return $token->test('END');
|
||||||
}
|
}
|
||||||
|
|
49
phpBB/includes/template/twig/tokenparser/includejs.php
Normal file
49
phpBB/includes/template/twig/tokenparser/includejs.php
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<?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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes a template.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* {% include 'header.html' %}
|
||||||
|
* Body
|
||||||
|
* {% include 'footer.html' %}
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
class phpbb_template_twig_tokenparser_includejs extends Twig_TokenParser_Include
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
$expr = $this->parser->getExpressionParser()->parseExpression();
|
||||||
|
|
||||||
|
list($variables, $only, $ignoreMissing) = $this->parseArguments();
|
||||||
|
|
||||||
|
return new phpbb_template_twig_node_includejs($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the tag name associated with this token parser.
|
||||||
|
*
|
||||||
|
* @return string The tag name
|
||||||
|
*/
|
||||||
|
public function getTag()
|
||||||
|
{
|
||||||
|
return 'INCLUDEJS';
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue