Problem/Motivation
#2404603: Add proper support for Url objects in FieldPluginBase::renderAsLink(), so we can remove EntityInterface::getSystemPath() caused that, because they get encoded, and it only decodes {/} back, but not the contained spaces. Nobody noticed that, because the current views in core with placeholders in paths did not use spaces.
I think that's bad because this is the common form that we use everywhere in actual twig templates, it also break existing views for no good reason (Which is why I found it, was using it in file_entity.module)
Proposed resolution
Also decode '{ ' and ' }', that should cover all variants. An alternative would be a preg_replace(), then we could support an arbitrary amount of spaces.
Remaining tasks
User interface changes
API changes
| Comment | File | Size | Author |
|---|---|---|---|
| #21 | interdiff-16-21.txt | 952 bytes | mpdonadio |
| #21 | views_no_longer-2426447-21.patch | 7.13 KB | mpdonadio |
| #16 | interdiff-11-16.txt | 6.19 KB | mpdonadio |
| #16 | views_no_longer-2426447-16.patch | 6.93 KB | mpdonadio |
| #11 | views_no_longer-2426447-11.patch | 1.61 KB | mpdonadio |
Comments
Comment #1
berdirHere is a patch. It's not pretty, but it seems to work for me.
Also updated one of the two relevant usages in core to use spaces, which should give us minimal test coverage of both cases.
Comment #3
berdirit is only broken when used in a path..
Also, wrong version, grml.
Comment #5
oriol_e9g--deleted-- wrong comment
Comment #6
berdirHere's a test only patch.
@oriol_e9g: You are not wrong, as written in the issue summary, using a preg_replace() to support the pattern and an arbitrary number of spaces might be a good idea, I was just too lazy.
Comment #7
berdirHm, why did this not fail?
Comment #8
berdirComment #9
mpdonadioFailing patch using the view/path that I found the problem with.
Comment #10
mpdonadioCoffee hasn't kicked in...
Comment #11
mpdonadioHere is a version using preg_replace that passes locally w/ the adjusted path from #10
Comment #13
mpdonadioDug into why #6 doesn't fail. It has to do with the logic in Url::toUriString().
'node/{{ nid }}' in views.view.test_dropbutton.yml is being parsed as an unrouted URL before token replacement, and since there are no query parameters, nothing is getting escaped, and Twig is happy. See #2426399: FieldPluginBase::renderAsLink() loses language prefix for tokenized paths for a related issue to this.
'admin/content/files/usage/{{ fid }}' in views.view.files.yml is being parsed as a routed URL before token replacement; so the route parameters are being escaped by UrlHelper::buildQuery(), including the spaces (and the escaped spaces are what are causing Twig grief).
Comment #14
berdir+ means at least once, wouldn't * be better, to support both both placeholders with spaces and those without?
Comment #15
mpdonadioYup. Wasn't thinking there. Fixed locally, but I am going to see if I can add some proper unit test coverage for this.
Comment #16
mpdonadioYikes. Not sure if I went too far (ie, did I make out of scope changes) to get the test coverage to actually work...
Comment #17
dawehnerI'm curios whether we should instead introduce a RendererTrait ? Would that be helpful for other places as well?
Nice coverage!
Comment #18
mpdonadioRe #17-1, I had to do this for test mocking purposes, and there are one or two other places in core that do this (and a bunch that wrap drupal_render_root). drupal_render() and drupal_render_root() are marked as deprecated, but I am not finding an issue to actually remove them. How about we leave this here, and I open a followup? That way we have an in-scope issue to swap out the duplicate methods / direct calls with the trait. That would put likely put a big dent into the drupal_render() and drupal_render_root() calls in classes where the service isn't injected.
Comment #19
mpdonadioShould probably be RendererInterface instead. Also in FieldPluginBase.
Comment #20
dawehnerFair, let's go with the follow up.
And yes, we do have an interface for that, so let's use it.
Comment #21
mpdonadioUpdated type hints. This should be good to go.
Comment #22
berdirinterfaces have no constructor, just getMock('interface...') is enough. not a big issue.
Awesome test coverage!
I think there's nothing left from my original patch, it was been reviewed by @dawehner, so I feel ok with RTBCing this. Thanks!
Comment #23
alexpottCommitted d6458cd and pushed to 8.0.x. Thanks!
Fixed on commit.