Added {% render object layout: 'default' with { variable: true } %} for Flex objects and collections

This commit is contained in:
Matias Griese
2018-12-12 00:02:38 +02:00
parent 34e6b6652a
commit 94a843429d
4 changed files with 147 additions and 0 deletions

View File

@@ -12,6 +12,7 @@
* Added `Grav\Framework\Form\FormFlashFile` class which implements `UploadedFileInterface` from PSR-7
* Added `Grav\Framework\Filesystem\Filesystem` class with methods to manipulate stream URLs
* Added new `$grav['filesystem']` service using an instance of the new `Filesystem` object
* Added `{% render object layout: 'default' with { variable: true } %}` for Flex objects and collections
* Grav 1.6: Flex: Added support for custom object index classes (API compatibility break)
1. [](#improved)
* Improved `Grav\Framework\File\Formatter` classes to have abstract parent class and some useful methods

View File

@@ -0,0 +1,73 @@
<?php
/**
* @package Grav.Common.Twig
*
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Twig\Node;
class TwigNodeRender extends \Twig_Node implements \Twig_NodeCaptureInterface
{
protected $tagName = 'render';
/**
* @param \Twig_Node|null $body
* @param \Twig_Node_Expression $object
* @param \Twig_Node_Expression|null $layout
* @param \Twig_Node_Expression|null $attributes
* @param int $lineno
* @param string|null $tag
*/
public function __construct(
\Twig_Node_Expression $object,
?\Twig_Node_Expression $layout,
?\Twig_Node_Expression $context,
$lineno,
$tag = null
)
{
parent::__construct(['object' => $object, 'layout' => $layout, 'context' => $context], [], $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param \Twig_Compiler $compiler A Twig_Compiler instance
* @throws \LogicException
*/
public function compile(\Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
$compiler->write('$object = ')->subcompile($this->getNode('object'))->raw(';' . PHP_EOL);
$layout = $this->getNode('layout');
if ($layout) {
$compiler->write('$layout = ')->subcompile($layout)->raw(';' . PHP_EOL);
} else {
$compiler->write('$layout = null;' . PHP_EOL);
}
$context = $this->getNode('context');
if ($context) {
$compiler->write('$attributes = ')->subcompile($context)->raw(';' . PHP_EOL);
} else {
$compiler->write('$attributes = null;' . PHP_EOL);
}
$compiler
->write('$html = $object->render($layout, $attributes ?? []);' . PHP_EOL)
->write('$block = $context[\'block\'] ?? null;' . PHP_EOL)
->write('if ($block instanceof \Grav\Framework\ContentBlock\ContentBlock && $html instanceof \Grav\Framework\ContentBlock\ContentBlock) {' . PHP_EOL)
->indent()
->write('$block->addBlock($html);' . PHP_EOL)
->write('echo $html->getToken();' . PHP_EOL)
->outdent()
->write('} else {' . PHP_EOL)
->indent()
->write('echo (string)$html;' . PHP_EOL)
->outdent()
->write('}' . PHP_EOL)
;
}
}

View File

@@ -0,0 +1,71 @@
<?php
/**
* @package Grav.Common.Twig
*
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Twig\TokenParser;
use Grav\Common\Twig\Node\TwigNodeRender;
/**
* Renders an object.
*
* {% render object layout: 'default' with { variable: true } %}
*/
class TwigTokenParserRender extends \Twig_TokenParser
{
/**
* Parses a token and returns a node.
*
* @param \Twig_Token $token A Twig_Token instance
*
* @return \Twig_Node A Twig_Node instance
*/
public function parse(\Twig_Token $token)
{
$lineno = $token->getLine();
[$object, $layout, $context] = $this->parseArguments($token);
return new TwigNodeRender($object, $layout, $context, $lineno, $this->getTag());
}
/**
* @param \Twig_Token $token
* @return array
*/
protected function parseArguments(\Twig_Token $token)
{
$stream = $this->parser->getStream();
$object = $this->parser->getExpressionParser()->parseExpression();
$layout = null;
if ($stream->nextIf(\Twig_Token::NAME_TYPE, 'layout')) {
$stream->expect(\Twig_Token::PUNCTUATION_TYPE, ':');
$layout = $this->parser->getExpressionParser()->parseExpression();
}
$context = null;
if ($stream->nextIf(\Twig_Token::NAME_TYPE, 'with')) {
$context = $this->parser->getExpressionParser()->parseExpression();
}
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
return [$object, $layout, $context];
}
/**
* Gets the tag name associated with this token parser.
*
* @return string The tag name
*/
public function getTag()
{
return 'render';
}
}

View File

@@ -14,6 +14,7 @@ use Grav\Common\Page\Collection;
use Grav\Common\Page\Media;
use Grav\Common\Scheduler\Cron;
use Grav\Common\Security;
use Grav\Common\Twig\TokenParser\TwigTokenParserRender;
use Grav\Common\Twig\TokenParser\TwigTokenParserScript;
use Grav\Common\Twig\TokenParser\TwigTokenParserStyle;
use Grav\Common\Twig\TokenParser\TwigTokenParserSwitch;
@@ -178,6 +179,7 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
public function getTokenParsers()
{
return [
new TwigTokenParserRender(),
new TwigTokenParserThrow(),
new TwigTokenParserTryCatch(),
new TwigTokenParserScript(),