diff options
| -rw-r--r-- | phpBB/includes/template/twig/environment.php | 40 | ||||
| -rw-r--r-- | phpBB/includes/template/twig/node/begin.php | 44 | ||||
| -rw-r--r-- | phpBB/includes/template/twig/twig.php | 8 |
3 files changed, 89 insertions, 3 deletions
diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php new file mode 100644 index 0000000000..1494b3ab28 --- /dev/null +++ b/phpBB/includes/template/twig/environment.php @@ -0,0 +1,40 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +class phpbb_template_twig_environment extends Twig_Environment +{ + /** + * recursive helper to set variables into $context so that Twig can properly fetch them for display + * + * @param array $data Data to set at the end of the chain + * @param array $blocks Array of blocks to loop into still + * @param mixed $current_location Current location in $context (recursive!) + */ + public function context_recursive_loop_builder($data, $blocks, &$current_location) + { + $block = array_shift($blocks); + + if (empty($blocks)) + { + $current_location[$block] = $data; + } + else + { + $this->context_recursive_loop_builder($data, $blocks, $current_location[$block]); + } + } +} diff --git a/phpBB/includes/template/twig/node/begin.php b/phpBB/includes/template/twig/node/begin.php index 3adb09f17e..34fd16dd73 100644 --- a/phpBB/includes/template/twig/node/begin.php +++ b/phpBB/includes/template/twig/node/begin.php @@ -30,6 +30,49 @@ class phpbb_template_twig_node_begin extends Twig_Node */ public function compile(Twig_Compiler $compiler) { + $compiler + ->write("if (!isset(\$phpbb_blocks)) {\n") + ->indent() + ->write("\$phpbb_blocks = array();\n") + ->write("\$parent = \$context['_phpbb_blocks'];\n") + ->outdent() + ->write("}\n") + ->write("\$phpbb_blocks[] = '" . $this->getAttribute('beginName') . "';\n") + ; + + $compiler + ->write("foreach (\$parent['" . $this->getAttribute('beginName') . "'] as \$" . $this->getAttribute('beginName') . ") {\n") + ->indent() + // Set up $context correctly so that Twig can get the correct data with $this->getAttribute + ->write("\$this->getEnvironment()->context_recursive_loop_builder(\$" . $this->getAttribute('beginName') . ", \$phpbb_blocks, \$context);\n") + + // We store the parent so that we can do this recursively + ->write("\$parent = \$" . $this->getAttribute('beginName') . ";\n") + ; + + $compiler->subcompile($this->getNode('body')); + + $compiler + ->outdent() + ->write("}\n") + + // Remove the last item from the blocks storage as we've completed iterating over them all + ->write("array_pop(\$phpbb_blocks);\n") + + // If we've gone through all of the blocks, we're back at the main level and have completed, so unset the var + ->write("if (empty(\$phpbb_blocks)) { unset(\$phpbb_blocks); }\n") + ; + } + + /** + * Compiles the node to PHP. + * + * Uses anonymous functions to compile the loops, which seems nicer to me, but requires PHP 5.4 (since subcompile uses $this, which is not available in 5.3) + * + * @param Twig_Compiler A Twig_Compiler instance + * + public function compile(Twig_Compiler $compiler) + { $compiler->addDebugInfo($this); $compiler @@ -85,4 +128,5 @@ class phpbb_template_twig_node_begin extends Twig_Node ->outdent() ->write("}\n"); } + */ } diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index a28905ca4e..358467d50d 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -118,7 +118,7 @@ class phpbb_template_twig implements phpbb_template // @todo use phpbb_admin path $loader->addPath($this->phpbb_root_path . 'adm/style/', 'admin'); - $this->twig = new Twig_Environment($loader, array( + $this->twig = new phpbb_template_twig_environment($loader, array( 'cache' => $this->cachepath, 'debug' => true, // @todo 'auto_reload' => true, // @todo @@ -422,11 +422,13 @@ class phpbb_template_twig implements phpbb_template $vars = array_merge( $vars, $this->context->get_rootref(), - $this->context->get_tpldata() + array( + '_phpbb_blocks' => $this->context->get_tpldata(), + ) ); // cleanup - unset($vars['.']); + unset($vars['_phpbb_blocks']['.']); return $vars; } |
