Commit d6458cd8 authored by alexpott's avatar alexpott

Issue #2426447 by mpdonadio, Berdir: Views no longer supports {{ something }}...

Issue #2426447 by mpdonadio, Berdir: Views no longer supports {{ something }} as twig placeholder for a path, only {{something}}
parent 27f69c2d
......@@ -489,7 +489,7 @@ display:
alter_text: false
text: ''
make_link: true
path: 'admin/content/files/usage/{{fid}}'
path: 'admin/content/files/usage/{{ fid }}'
absolute: false
external: false
replace_spaces: false
......
......@@ -104,6 +104,12 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
*/
protected $usesOptions = FALSE;
/**
* Stores the render API renderer.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* Constructs a PluginBase object.
......@@ -364,14 +370,14 @@ protected function viewsTokenReplace($text, $tokens) {
// Non-Twig tokens are a straight string replacement, Twig tokens get run
// through an inline template for rendering and replacement.
$text = strtr($text, $other_tokens);
if ($twig_tokens) {
if ($twig_tokens && !empty($text)) {
$build = array(
'#type' => 'inline_template',
'#template' => $text,
'#context' => $twig_tokens,
);
return drupal_render($build);
return $this->getRenderer()->render($build);
}
else {
return $text;
......@@ -576,4 +582,18 @@ public static function queryLanguageSubstitutions() {
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;
}
}
......@@ -103,7 +103,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
/**
* Stores the render API renderer.
*
* @var \Drupal\Core\Render\Renderer
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
......@@ -1330,9 +1330,9 @@ protected function renderAsLink($alter, $text, $tokens) {
// Url::toUriString() call above, because we support twig tokens in
// rewrite settings of views fields.
// 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.
$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.
// However, we need to preserve special characters like " that
......@@ -1730,7 +1730,7 @@ protected function linkGenerator() {
/**
* Returns the render API renderer.
*
* @return \Drupal\Core\Render\Renderer
* @return \Drupal\Core\Render\RendererInterface
*/
protected function getRenderer() {
if (!isset($this->renderer)) {
......
......@@ -119,6 +119,13 @@ class FieldPluginBaseTest extends UnitTestCase {
*/
protected $pathProcessor;
/**
* The mocked path renderer.
*
* @var \Drupal\Core\Render\RendererInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $renderer;
/**
* {@inheritdoc}
*/
......@@ -147,11 +154,14 @@ protected function setUp() {
$this->unroutedUrlAssembler = $this->getMock('Drupal\Core\Utility\UnroutedUrlAssemblerInterface');
$this->linkGenerator = $this->getMock('Drupal\Core\Utility\LinkGeneratorInterface');
$this->renderer = $this->getMock('Drupal\Core\Render\RendererInterface');
$container_builder = new ContainerBuilder();
$container_builder->set('url_generator', $this->urlGenerator);
$container_builder->set('path.validator', $this->pathValidator);
$container_builder->set('unrouted_url_assembler', $this->unroutedUrlAssembler);
$container_builder->set('request_stack', $this->requestStack);
$container_builder->set('renderer', $this->renderer);
\Drupal::setContainer($container_builder);
}
......@@ -421,6 +431,65 @@ public function providerTestRenderAsLinkWithUrlAndOptions() {
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.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment