Issue #2426447 by mpdonadio, Berdir: Views no longer supports {{ something }} as twig placeholder for a path, only {{something}}

8.0.x
Alex Pott 2015-02-19 09:32:19 +00:00
parent 27f69c2df5
commit d6458cd8fa
4 changed files with 96 additions and 7 deletions

View File

@ -104,6 +104,12 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
*/ */
protected $usesOptions = FALSE; protected $usesOptions = FALSE;
/**
* Stores the render API renderer.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/** /**
* Constructs a PluginBase object. * Constructs a PluginBase object.
@ -364,14 +370,14 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
// Non-Twig tokens are a straight string replacement, Twig tokens get run // Non-Twig tokens are a straight string replacement, Twig tokens get run
// through an inline template for rendering and replacement. // through an inline template for rendering and replacement.
$text = strtr($text, $other_tokens); $text = strtr($text, $other_tokens);
if ($twig_tokens) { if ($twig_tokens && !empty($text)) {
$build = array( $build = array(
'#type' => 'inline_template', '#type' => 'inline_template',
'#template' => $text, '#template' => $text,
'#context' => $twig_tokens, '#context' => $twig_tokens,
); );
return drupal_render($build); return $this->getRenderer()->render($build);
} }
else { else {
return $text; return $text;
@ -576,4 +582,18 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
return $changes; return $changes;
} }
/**
* Returns the render API renderer.
*
* @return \Drupal\Core\Render\RendererInterface
*/
protected function getRenderer() {
if (!isset($this->renderer)) {
$this->renderer = \Drupal::service('renderer');
}
return $this->renderer;
}
} }

View File

@ -103,7 +103,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
/** /**
* Stores the render API renderer. * Stores the render API renderer.
* *
* @var \Drupal\Core\Render\Renderer * @var \Drupal\Core\Render\RendererInterface
*/ */
protected $renderer; protected $renderer;
@ -1332,7 +1332,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
// In that case the original path looks like // In that case the original path looks like
// user-path:/admin/content/files/usage/{{ fid }}, which will be escaped by // user-path:/admin/content/files/usage/{{ fid }}, which will be escaped by
// the toUriString() call above. // the toUriString() call above.
$path = str_replace(['%7B','%7D'], ['{','}'], $path); $path = preg_replace(['/(\%7B){2}(\%20)*/', '/(\%20)*(\%7D){2}/'], ['{{','}}'], $path);
// Use strip tags as there should never be HTML in the path. // Use strip tags as there should never be HTML in the path.
// However, we need to preserve special characters like " that // However, we need to preserve special characters like " that
@ -1730,7 +1730,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
/** /**
* Returns the render API renderer. * Returns the render API renderer.
* *
* @return \Drupal\Core\Render\Renderer * @return \Drupal\Core\Render\RendererInterface
*/ */
protected function getRenderer() { protected function getRenderer() {
if (!isset($this->renderer)) { if (!isset($this->renderer)) {

View File

@ -119,6 +119,13 @@ class FieldPluginBaseTest extends UnitTestCase {
*/ */
protected $pathProcessor; protected $pathProcessor;
/**
* The mocked path renderer.
*
* @var \Drupal\Core\Render\RendererInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $renderer;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -147,11 +154,14 @@ class FieldPluginBaseTest extends UnitTestCase {
$this->unroutedUrlAssembler = $this->getMock('Drupal\Core\Utility\UnroutedUrlAssemblerInterface'); $this->unroutedUrlAssembler = $this->getMock('Drupal\Core\Utility\UnroutedUrlAssemblerInterface');
$this->linkGenerator = $this->getMock('Drupal\Core\Utility\LinkGeneratorInterface'); $this->linkGenerator = $this->getMock('Drupal\Core\Utility\LinkGeneratorInterface');
$this->renderer = $this->getMock('Drupal\Core\Render\RendererInterface');
$container_builder = new ContainerBuilder(); $container_builder = new ContainerBuilder();
$container_builder->set('url_generator', $this->urlGenerator); $container_builder->set('url_generator', $this->urlGenerator);
$container_builder->set('path.validator', $this->pathValidator); $container_builder->set('path.validator', $this->pathValidator);
$container_builder->set('unrouted_url_assembler', $this->unroutedUrlAssembler); $container_builder->set('unrouted_url_assembler', $this->unroutedUrlAssembler);
$container_builder->set('request_stack', $this->requestStack); $container_builder->set('request_stack', $this->requestStack);
$container_builder->set('renderer', $this->renderer);
\Drupal::setContainer($container_builder); \Drupal::setContainer($container_builder);
} }
@ -421,6 +431,65 @@ class FieldPluginBaseTest extends UnitTestCase {
return $data; return $data;
} }
/**
* Test rendering of a link with a path and options.
*
* @dataProvider providerTestRenderAsLinkWithPathAndTokens
* @covers ::renderAsLink
*/
public function testRenderAsLinkWithPathAndTokens($path, $tokens, $link_html) {
$alter = [
'make_link' => TRUE,
'path' => $path,
];
$this->setUpUrlIntegrationServices();
$this->setupDisplayWithEmptyArgumentsAndFields();
$this->executable->build_info['substitutions'] = $tokens;
$field = $this->setupTestField(['alter' => $alter]);
$field->field_alias = 'key';
$row = new ResultRow(['key' => 'value']);
$build =[
'#type' => 'inline_template',
'#template' => 'base:test-path/' . explode('/', $path)[1],
'#context' => ['foo' => 123],
];
$this->renderer->expects($this->once())
->method('render')
->with($build, FALSE)
->willReturn('base:test-path/123');
$result = $field->advancedRender($row);
$this->assertEquals($link_html, $result);
}
/**
* Data provider for ::testRenderAsLinkWithPathAndTokens().
*
* @return array
* Test data.
*/
public function providerTestRenderAsLinkWithPathAndTokens() {
$tokens = ['{{ foo }}' => 123];
$link_html = '<a href="/test-path/123">value</a>';
$data = [];
$data[] = ['test-path/{{foo}}', $tokens, $link_html];
$data[] = ['test-path/{{ foo}}', $tokens, $link_html];
$data[] = ['test-path/{{ foo}}', $tokens, $link_html];
$data[] = ['test-path/{{foo }}', $tokens, $link_html];
$data[] = ['test-path/{{foo }}', $tokens, $link_html];
$data[] = ['test-path/{{ foo }}', $tokens, $link_html];
$data[] = ['test-path/{{ foo }}', $tokens, $link_html];
$data[] = ['test-path/{{ foo }}', $tokens, $link_html];
$data[] = ['test-path/{{ foo }}', $tokens, $link_html];
return $data;
}
/** /**
* Sets up a test field. * Sets up a test field.
* *