Problem/Motivation
We want to be able extract a URI from a URL to do, for example, token manipulation and then reconstruct the equivalent URL object
This is needed to support Views token processing of paths, among other things
This is currently blocking #2404603: Add proper support for Url objects in FieldPluginBase::renderAsLink(), so we can remove EntityInterface::getSystemPath()
Proposed resolution
Add a method to return a URI.
Add support for a route: scheme so we can have a URI representation of any URL object.
Add support in Url::fromUri() to set the query string and fragment.
Discussing with effulgentsia we can use the definition of URI formatting to separate route params using ; from the route name in the path.
Remaining tasks
do it
User interface changes
n/a
API changes
API addition
| Comment | File | Size | Author |
|---|---|---|---|
| #19 | 2418139-18.patch | 15.24 KB | kgoel |
| #17 | interdiff.txt | 2.06 KB | kgoel |
| #17 | 2418139-17.patch | 42.41 KB | kgoel |
| #13 | 2418139-12.patch | 13.85 KB | pwolanin |
| #9 | increment.txt | 7.99 KB | pwolanin |
Comments
Comment #1
pwolanin commentedstarting work on this now.
Comment #2
mpdonadioComment #3
pwolanin commentedthere is already a getUri method
Comment #4
pwolanin commentedWIP, but mostly working. Will continue refining.
Comment #5
pwolanin commentedconvert method sigs per discussion with tim.plunkett and extending tests further.
Comment #7
wim leers"query parameters" vs.
$uri_query— that's confusing. Let's be consistent.In HEAD,
$options = []by default. This causes$optionsto never be empty. I don't think we want that?Besides, we only set
$options['query']conditionally.So either set both
$options['fragment']and$options['query']only when necessary, or set both always.Should mention that it expects an array of the shape returned by
parse_url().This is a subtle change; we used to call
PathValidatorwith an URI reference, which included querystring/fragment, now it doesn't anymore.I'm pretty sure that this is fine, but I just wanted to make sure this is what we want.
Hrm, the param docs here are much longer than for the other protected static helpers. It also explicitly mentions query parameters plus explains them. Why? And it's strange that it omits fragment; does that mean that
route:URIs don't support fragments?Oh, I see, it's non-standard, it uses the semi-colon to indicate the query string instead of the question mark. Why?
EDIT: oh, the docs are just wrong; this is for route parameters, not query parameters! Then it makes sense. But the docs definitely need to be fixed then :)
Awesome test coverage! :) :)
Nit: s/URI/URIs/
Finally: do we call it "query parameters", "query arguments" or "querystring"? Let's go with whatever D8 uses elsewhere, and otherwise use the URI RFC's terminology.
Comment #9
pwolanin commentedTried to address those and fix the fails.
Quick consensus is "query parameters" for array of parameters and "querystring" when it's actually the string.
Comment #10
dawehnerThis documentation is confusing ... what about using route:{route_name};{route_parameters} or something? {path} is certainly confusing in that domain.
Given that this is a public method it should describe what it returns.
... mh, so previously we had just one single entry, in the test, can't we use a data provider here?
Data providers would be nice here as well.
Comment #12
almaudoh commentedThis patch is really nice <3
+1. Now that the various schemes are unified, it makes sense to do this, avoiding the extra parse_url() call.
Nit: extra space.
Comment #13
pwolanin commentedwill work more on addressing feedback, but want to re-test.
Comment #14
kgoel commentedComment #15
webchickOne minor point to get picked up in the next re-roll...
1) $options should be type-hinted as array like $uri_parts is
2) we deleted the docs for $uri but it's still a parameter?
Comment #16
dawehnerBeside of that change it looks great!
Comment #17
kgoel commentedFound another small missing test coverage, great that this didn't slept through.
Comment #19
kgoel commentedThis time with an actual sane rebase.
Comment #20
dawehnerGood catch!
Comment #21
webchickSo I was a bit concerned earlier on IRC about us introducing Yet Another Freaking Scheme™ here, and the DX impact on that. Basically, the rationale was that there are cases when you are intentionally resolving a link to a route, actually have all of the info you need already, and so re-resolving from some other scheme to this is wasted work. Also, from a DX POV you're mostly going to call Url::fromRoute() or use a Link field if you want to capture user input, same as Menu Link and Shortcut do, which handles all this whack-a-mole stuff scheme stuff for you. Fair enough.
Code-wise this is all pretty straight-forward, and nice catch on the additional test coverage.
Committed and pushed to 8.0.x, so we can continue to make progress on the _l()/_url() removal issues. w00t!
Comment #23
wim leersI think there's one actual bug in the code plus 3 nitpicks that aren't worth a follow-up unless the first is going to require a follow-up:
Why is the
unset()happening outside of the if-statement? That doesn't seem to make any sense?Before I file a follow-up for this tiny thing, I'd like confirmation from someone else that this is a problem.
Nit: This
$optionsdidn't get typehinted.Nit: Returns.
Nit: Double space after period, 80 col formatting a bit off.
Comment #24
pwolanin commented@Wim Leers -actually - this may be a different and more real bug - should probably really use
isset($uri_parts['fragment'])there in case we are trying to jump to#0Comment #25
pwolanin commentedFollow-up:#2418613: Fix #0 bug in toUriString() method in Url class, clarify toString() vs toUriString()
Comment #26
wim leersHadn't even considered that. Thanks for the follow-up!
Comment #27
xjmThe summary says:
However, I have no idea where this requirement comes from. Views is doing token processing of paths more or less as it always has in #2409209: Replace all _url() calls beside the one in _l(), using just Views' internal API. I can see a case for refactoring that as it's scary, but I don't see why this new scheme is somehow necessary to support Views?
Furthermore, in general, tokenized Views paths will be just that, paths, entered by the user. So it would make sense to store them with
user-path:or whatever we end up calling it.Comment #28
mpdonadio`views.view.files.yml` is a system defined view with a token in it (one of the alter paths). That was the view started us down this road.
Comment #29
xjm@mpdonadio, is that in scope for #2404603: Add proper support for Url objects in FieldPluginBase::renderAsLink(), so we can remove EntityInterface::getSystemPath()? Didn't see it in the patch there. I guess there's an attempt to make a distinction between what's usually user input (and user-alterable), but defined in default config, and what's actually entered by the user?