Problem/Motivation
Handling of query strings in URL aliases is broken - for example, it is possible to create an alias /?p=123
pointing to /node/123
, but although the alias exists and can be listed/edited/deleted, it will not have an effect. Conversely, it is possible to create an alias /withquery
pointing to /my/custom/module?needs=query
, but the expected path will not be invoked.
Eight years of comment history on this issue indicate that the former case is attempted often, typically to avoid breakage of existing URLs when migrating from a non-Drupal platform. The latter case seems less requested, which stands to reason given the rare use of query strings in Drupal.
Proposed resolution
For the former case (/?p=123 -> /node/123), questions arise because unlike paths, which always are matched by string comparison, query string parameters are unordered. If /path?product=123&sort=asc
should alias /node/4
, shouldn't /path?sort=asc&product=123
? What about /path?product=123
?
The answers to such questions will be site-dependent and could require rules of arbitrary complexity. But, simple support that addresses most users' needs out of the box, as well as a service custom/contrib could implement more advanced rulesets on seems reasonable in core.
In Drupal 8, this alias processing is the purview of the installed InboundPathProcessorInterface
implementations, especially Drupal\Core\PathProcessor\PathProcessorAlias
. Some attempts at quick fixes in PathProcessorAlias
show that simple / seemingly obvious logic like concatenating the query string to the path before sending it to the alias manager do not work reliably, because the path received by PathProcessorAlias
has been subjected to arbitrary futzing-with by the other InboundPathProcessorInterface
implementations. For example, PathProcessorFront
rewrites the path of any URI whose path component is '/' to the site's configured frontpage, which can be anything. PathProcessorAlias
receives this rewritten value that bears no relation to the path '/', so your alias /?p=123
will not work. Contrib is able to add additional unknown futzing before PathProcessorAlias
as well. Unfortunately, the task of reconstructing a path suitable for alias lookups based solely on the Symfony Request is nontrivial, and involves selectively applying only certain InboundPathProcessors to the Request path. See the discussion in #99 for details.
The patch of #99 hardcodes the set of path processors on a site with no contrib modules that yield reliable alias-style matching into PathProcessorAlias
, which works, but has some disadvantages:
- Modules seeking to implement their own
InboundPathProcessorInterface
implementations that support alias-style matching, such as to support more complex query parameter matching rulesets, and likely also modules that want to redirect rather than rewrite the path, should be able to use the same logic to build the match string. - The set of PathProcessors that need to be applied for aliases to match may depend on the modules in use, for example it already depends on whether or not Language is. If PathProcessors used are hardcoded in
PathProcessorAlias
, contrib modules can't contribute to the process.
Therefore, the proposed solution is to create a list of InboundPathProcessors that are appropriate for building a path suitable for alias-style matching, a means for non-core to supplement this list, a manager class that applies this list in a stacked fashion, and a means for users besides PathProcessorAlias
to call on that manager's services. This is implemented in very little code by extending PathProcessorManager
and creating a new service_collector tag which only those path processors providing useful futzing for reliable alias-style matching can be registered with.
"Resolving" the latter case (/withquery -> /my/custom/module?needs=query) might be best done by just disallowing the creation of such things for now -- even if you arrange for the expected route/controller to run, it would be necessary to provide the custom code expecting the query string with the query parameters in all places it might look for them.
Remaining tasks
New tests
User interface changes
May want to add validation to the alias creation form to prevent the latter case, TBD.
API changes
Provides a new service, alias_processor_manager
. Some modules (redirect?) may benefit from using it.
Original report by geilhufe
I am trying to create a path alias for "civicrm/contribute/transact?reset=1&id=4"
I have tried escaping the characters without result. It seems like the alias works all the way up the the "?" then basically doesn't pass any of the arguments past the "?".
Comments
Comment #1
revival CreditAttribution: revival commentedam having the same problem
Comment #2
pfaocleJust noticed this myself, and I posted what I'm up to on this issue. Perhaps related?
Comment #3
pvasener CreditAttribution: pvasener commentedI also have the same problem. It seems that the alias in only valid for the part before the exclamation point. BTW, the link you provided above about another maybe-related issue is broken. Can you advise?
Comment #4
pfaocleOops: issue.
Comment #5
tobias CreditAttribution: tobias commentedI'm struggling with this issue myself - esp using civicrm which produces attrocious URLs.. though it also happens when creating menus. Has anyone found a solution to this problem?
Comment #6
mfbMoving this over to a feature request on drupal core.
Comment #7
tobias CreditAttribution: tobias commentedHi,
Any news with this issue? It is severely hampering my abilities to create clean URLs for civicrm profile pages which I'd very much like to do.
Many thanks in advance for any insights,
Tobias
Comment #8
imrook CreditAttribution: imrook commentedI have recently run into this problem and have a solution that meets my needs so I'll chime in with my two cents here. The part after the '?' character in the URL is called the query string. boombatower created an issue with a patch for this problem here. Some users complained that it didn't work -- I personally haven't tested it. chx doesn't seem too intent on adding the functionality at this time.
But there is still hope. Here's why the problem occurs in the first place: Apache uses mod rewrite to rewrite a URL like
to become
. During the bootstrap phase, Drupal uses the value of the variable
to map a URL to a function call. Now look what happens with the following URL:
Apache's mod_rewrite turns it into
This is normally a good thing. The problem with Drupal is that the core doesn't look at any other variables besides
so it will only use
for the lookup. Luckily Drupal provides a place where we can change that:
Add the following code to your
file:
This will allow you to set a path alias for a node that contains a query string and Drupal will redirect to the correct page. Note that when Drupal generates a link to the node it will be urlencoded, but it will still work properly.
This code is actually written for 5.x In Drupal 6, the function is called custom_url_rewrite_inbound and the parameters have changed a bit. I haven't taken a look at 7 yet so I don't know anything about that.
Comment #9
tobias CreditAttribution: tobias commentedvery nice! I have implemented this and it seems to work very well for my site.
One issue I still run into is with a custom civicrm signup form which breaks upon submission when I use your hack with a "Cannot add or update a child row: a foreign key constraint fails" error. Not a big deal since I have already setup apache redirects for these signup forms.
But your hack will help with accessing other civicrm pages from the menu. Many, many thanks. You've addressed one of my major issues with civicrm. I'll be sure to spread the word in the civicrm forum if you have not done so already.
Cheers,
Tobias
Comment #10
imrook CreditAttribution: imrook commentedSince I'm not using CiviCRM, I'm not very surprised that this approach has some flaws with that module. I did think what I had was relevant and may be a good starting point for others, which it appears is correct. I'm glad I could help at least some with this issue. Since I'm not using CiviCRM, you can feel free to mention this method in that forum but beware that people will probably come back with posts citing all the things that still don't work correctly.
Comment #11
Damien Tournoud CreditAttribution: Damien Tournoud commentedSubscribing. We need a better solution for that issue.
Comment #12
imrook CreditAttribution: imrook commentedI kinda thought this was too good to be true. I found a problem with the code in comment #8. If a user has "administer menu" permission and edits a node, the cached menu tree that is created will have all menu links pointing to the current node. If you are bittin by this, clear your menu cache with "DELETE FROM cache_menu;" Unfortunately, I haven't found a way to fix this in custom_url_rewrite and have resorted to hacking path.inc during the drupal_init_path() call. I'm interested to see if anyone can find a solution that works within custom_url_rewrite.
Comment #13
haggan CreditAttribution: haggan commentedIs this drupal 6-7 specific or does this hack work on drupal 5.7? I cant get it to work, when I paste it into my settings.php my webpage is just blank...
Comment #14
tobias CreditAttribution: tobias commentedthis worked for me on drupal 5.3, except for the civicrm issue I explained above which is why I don't use it.
cheers,
tobias
Comment #15
sonicthoughts CreditAttribution: sonicthoughts commentedYes - please fix - you can't add any civicrm menus to drupal without a hack. I have found nothing that works with 5.6
Comment #16
StevenPatzfeatures should go into the latest dev version and then backported.
Comment #17
dgeilhufe@yahoo.com CreditAttribution: dgeilhufe@yahoo.com commentedTheoretically resolved in Drupal 6:
http://drupal.org/node/90570
Comment #18
dgeilhufe@yahoo.com CreditAttribution: dgeilhufe@yahoo.com commentedFixed in Drupal 6.x / CiviCRM 2.1+
Comment #19
Anonymous (not verified) CreditAttribution: Anonymous commentedAutomatically closed -- issue fixed for two weeks with no activity.
Comment #20
himtuna CreditAttribution: himtuna commentedthanks for that fix, I was realy getting annoyed from it.
Comment #21
Damien Tournoud CreditAttribution: Damien Tournoud commentedHow that is fixed?
Comment #22
sbydrupal CreditAttribution: sbydrupal commentedDrupal 6 version available ? thx.
Comment #23
jsimonis CreditAttribution: jsimonis commentedI tried applying the patch, but it failed.
I'd really like to get this working so I can point /donate to the donation page.
Comment #24
Dave Reid@jsimonis The path "donate" does not have a question mark in it...what problems are you having adding an alias for it?
Comment #25
babbage CreditAttribution: babbage commentedI was trying to alias the following url in D6:
http://example.com/civicrm/event/register?id=1&reset=1
I wanted it to display as:
http://example.com/events/2009/conference/register
It wasn't working. Instead it was redirecting to the event configuration page. However, I stumbled upon a solution. If I set the url to alias as:
http://example.com/civicrm/event/register/?id=1&reset=1
...with an extra slash after the "register", it then redirects correctly to:
http://example.com/events/2009/conference/register?id=1
Which works! I don't know if the dropping of the &reset=1 is of significance, but so far it appears to work. So this seems to be a bug, but it's a pretty easy one to work around until it can be fixed.
Comment #26
jsimonis CreditAttribution: jsimonis commentedSorry, the page I was trying to alias to /donate is the contribution page in CiviCRM. Those pages all have a question mark in them, similar to those in comment #25 above.
Comment #27
luxx CreditAttribution: luxx commentedI have faced similar issue and have been directed to rewrite urls via .htaccess http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html
Comment #28
Dave ReidMarked #191917: Allows paths to contain query strings as a duplicate of this issue.
Comment #29
Dave ReidAlso bumping version, since this is no longer viable for D7.
Comment #30
duncanc CreditAttribution: duncanc commentedWe can alter the alias translation by using the custom_url_rewrite_inbound() function.
This function examines the translated alias value ($result).
If it contains any query parameters (identified by '&') then new $_GET variables are created for those, and $result returned without those query parameters
How it works
Create alias 'signup' to Drupal path 'civicrm/profile/create&reset=1&gid=7'
$_GET['q'] will be 'signup', and the path module will translate this to 'civicrm/profile/create&reset=1&gid=7'
this function is called by the path module before returning and modifies the result to be 'civicrm/profile/create' which will eventually get back into $_GET['q'] and sets $_GET['gid'] to 7 and $_GET['reset'] to 1.
Comment #31
philipashlock CreditAttribution: philipashlock commentedI'm running drupal 6.13 and was having this same issue trying to do URL aliasing for CiviCRM pages. Manually adding the additional slash to the original query string helped somewhat - it seemed to make everything work in Safari or in any browser if I was logged in as an administrator, but I needed to apply this custom function provided here to get it to work everywhere.
Is there a more official fix for this yet?
Comment #32
Dave ReidPlease don't change the meta-data for feature requests in core.
Comment #33
philipashlock CreditAttribution: philipashlock commentedAs an update: It doesn't look like the custom function completely solved the problem - or maybe it just created a new one. I have aliases that look like this:
Alias > Source Path
full-membership > civicrm/contribute/transact/?reset=1&id=6
partial-membership > civicrm/contribute/transact/?reset=1&id=5
deferred-membership > civicrm/contribute/transact/?reset=1&id=8
Each of those aliases only direct to one of the source paths, but not the ones they're assigned to. For some reason they're all pointing to /?reset=1&id=5
Comment #34
duncanc CreditAttribution: duncanc commentedThe code I posted expects the alias not to contain a '?', but to contain only '&' to separate the parameters. This kind of made sense at the time but isn't intuitive.
Try changing your aliases to be like this:
full-membership > civicrm/contribute/transact/&reset=1&id=6
Otherwise you will need to change the function to split on '?' before exploding the parameters on '&'.
Comment #35
yngens CreditAttribution: yngens commentedI am drupalizing an old site with tons of pages ending with:
view.php?i=12345 (12345 - variable)
I need to either:
1) to find a workaround to make pathauto module generate url aliases with question and equal marks in them like 'view.php?i=[nid]'
2) or to redirect all the requests view.php?i=[nid] to node/[nid]
Second way seems easier to go just with writing in .htaccess proper redirection rule. But there I have problem - for some reason it does not redirect url requests with question marks. I guess, because all the requests go to 'index.php?q='
Could anyone advice me what would be best solution in my case? Thanks!
Comment #36
kenwest CreditAttribution: kenwest commentedI have used the code provided by duncanc at #30 (above) and extended it to handle both '?' and '&' characters in query arguments.
To do so, take his code and replace...
$parts = explode('&', $result);
...with...
$parts = preg_split('/[\?\&]/', $result);
Ken
(disclaimer: while I'm confident this change is OK, I'm not an experienced PHP developer, so you should apply this change with caution.)
Comment #37
kenwest CreditAttribution: kenwest commentedI found a problem with duncanc's code at #30.
When I try to edit a menu item where the URL has query arguments, the arguments get stripped. To avoid this I made the following change to modules/menu/menu.admin.inc (a change to core, unfortunately)
Comment #38
Dave ReidComment #39
j0nathan CreditAttribution: j0nathan commentedSubscribing.
Coming from HOWTO: create URL Aliases for CiviCRM forms.
Comment #40
mrfelton CreditAttribution: mrfelton commentedThe code in #37 doesn't seem to work for me. The querystring still gets stripped off when saving a menu link.
Example. I create a menu item that points to node/1234?somequery=test#fragment and I end up with a menu item that points to node/1234. The entire querystring and fragment has been stripped out, just as without the change in #37.
Comment #41
brian_c CreditAttribution: brian_c commentedI appear to have gotten this working in D7 via hook_url_inbound_alter():
Seems to be working fine, including for Exposed Filter Blocks (my use case was creating friendly URLs pointing to specific search result pages).
Please note you need to add a trailing slash to the path component when defining the URL Alias, as per comment #25, otherwise it won't validate.
So you need to use:
myalias => some/path/?foo=bar
instead of:
myalias => some/path?foo=bar
Comment #42
brian_c CreditAttribution: brian_c commentedHere's a better version of the code in #41, that won't overwrite values already present in $_GET (so values from the URL will always take precedence over the "defaults" provided by the URL Alias):
Comment #43
brian_c CreditAttribution: brian_c commentedSigh. The URL Alias works properly (in terms of feeding the right query params to the page), but I can't then add that alias as a Menu Link properly (even though that works fine for "normal" aliases)... the underlying path shows through when displaying the menu, instead of the friendly alias. Which was the whole point. :(
Edit: For the record, was able to fix this using THEME_menu_link() to intercept the link, overwriting [#href] to the desired alias, and unsetting ['#localized_options']['query'].
Comment #44
webchickThis is not a feature request. This is a straight-up bug. It might even be a 'major' bug. As long as Drupal can generate paths with ?s in them, it ought to be able to alias them.
I hit this trying to create a path alias to /project/issues/search?projects=&status[]=1&status[]=13&status[]=8&status[]=14&status[]=15&status[]=2&issue_tags=Novice
Comment #45
webchickTagging for backport.
Comment #46
mrfelton CreditAttribution: mrfelton commented@webchick - totally agree. Seems like a pretty major issue to me. Tagging the issue as such.
Comment #47
bfroehle CreditAttribution: bfroehle commentedObviously this could be easily done with a redirect.
In D7 the magic path alias to normal path is run in drupal_path_initialize(). If query strings were allowed in the path they'd have to be processed here and injected into $_GET.
Comment #48
missmobtown CreditAttribution: missmobtown commentedSubscribe.
Comment #49
scott.whittaker CreditAttribution: scott.whittaker commentedSubscribe
Comment #50
catchThis is anything but a major bug, the issue has been around since 2007, and webchick marked the duplicate issue as a feature request in 2008: http://drupal.org/node/191917#comment-958209
I'm not sure drupal_path_initialize() is the right place to do this though. Or at least if we do it there, then we'd only be supporting aliases one way.
Trying to do it the other way would be a can of worms - since when you call url(), $_GET parameters go into $options, not in the url string, so there is no way to look it up at all.]
In fact I'm tempted to mark this won't fix, because of this:
system url = path resolvable to a menu router item. So we make it clear that aliases are only supported for that, not for any of the extra crap that can be added to a url.
Comment #51
bfroehle CreditAttribution: bfroehle commentedI didn't come out and say it directly in #47, but I certainly agree. This would be a huge feature addition and very difficult (if not impossible) to engineer correctly. There are numerous other ways to accomplish something similar (including using path redirection or mod_rewrite directly).
Comment #52
mrfelton CreditAttribution: mrfelton commentedIs asking people to use mod_rewrite so that they can create a menu item for a page that the created in Drupal really an acceptable solution? What percentage of Drupal user's do you think know what mod_rewrite is, let alone how to use it? Granted, it possible to do it with the path_redirect module, but this requires installation of a module for something that really should be a basic task, as well as setting up dummy redirect paths just so you can get something in the menu.
Comment #53
catchThis issue isn't about menu items, it's about URL aliases.
The design of the URL alias system, url() etc. is very explicit that it only supports 'system paths', in the same way we don't allow separate router items to exist based on $_GET params either. So changing that is a feature request since it's currently by design.
If links like this don't work as menu items, that's a separate bug report but has nothing to do with this issue.
Comment #54
scott.whittaker CreditAttribution: scott.whittaker commentedI don't think we need to support the entire gamut of url() functionality, but the ability for non-developers to create one-way path aliases is extremely useful, bordering on necessary. Same goes for allowing querystrings in menu items. Views filters especially can make some funky URLs that would be usefully served by allowing short semantic aliases.
Comment #55
joetsuihk CreditAttribution: joetsuihk commentedre #53 I think supporting extra $_GET params as destination in alias is a feature request, but not having error message when saving a system path with ? is a bug. At least, add more descriptive helping text in add URL alias page.
Comment #56
sbydrupal CreditAttribution: sbydrupal commentedNot a programmer. For #42, and #43, where shall we place the codes ? Thank you!
I think the purpose of we are using a CMS is to have such utility functions available without programming and getting into details of mod rewrite or core drupal function modifications. Url aliasing with ? seems to me is important for SEO purposes and I dont see why it should not be default functionality available. In many cases using views exposed filters, I don't see any other practical solution, otherwise, creating views for every possible filter combination which doesn't make sense.
Comment #57
brian_c CreditAttribution: brian_c commentedThe code in #42 would need to go in a custom module, with 'HOOK' replaced with the name of the module. (Other than the name change, the code in #42 can be used exactly as is.)
The code (or rather, the approach outlined) in #43 would need to go in your theme's template.php file, with 'THEME' replaced with the name of your theme. It will need custom "hard coded" values to use... a less than ideal solution, but it worked for our limited needs with a small, fixed number of "aliased queries". Our code for #43 looks something like this:
Hope this helps.
Comment #58
sbydrupal CreditAttribution: sbydrupal commentedThx Brian!
Comment #59
Donsov CreditAttribution: Donsov commentedi need allow ?param=value in taxonomy_menu path alias i tried accept these hooks but they don't work
Comment #60
NicoDruif CreditAttribution: NicoDruif commentedsubscribing, because I also encounterd this issue, because I want to use the rendered exposed filter url with arguments in it, in an path alias...
Comment #61
NicoDruif CreditAttribution: NicoDruif commentedI tried to create a custom module, following suggestions in comments #42 and #57, but it did not work out.
It still does not work, because my drupal 7.14 installation won't validate an alias with arguments, even with a trailing slash like:
bestemming/wenen/?field_bestemming_nid[]=75&sort_by=field_prijs_value&sort_order=ASC
Too bad! Any suggestions are very welcome!
I will now try a solution like suggested on http://drupal.org/node/210430...
Comment #62
NicoDruif CreditAttribution: NicoDruif commentedWell, at the end of the day I just ended up writing custom RewriteRules for every url I want to alias. Like:
before the default drupal rewrite section
Comment #63
globber CreditAttribution: globber commentedHaving the same problem with Drupal 7.15.
urls look like this:
?q=browse&f[0]=vocabulary%3A9
Comment #64
sonicthoughts CreditAttribution: sonicthoughts commentedComment #65
jsimonis CreditAttribution: jsimonis commentedWish we could get this working. I'd like to create links to specific filters on our calendar, like http://www.rmcptk.org/calendar/month?field_location_tid%5B%5D=12
I tried URL aliases. Doesn't work. Tried linking straight to that page in the menu. Didn't work. I end up with extra characters in the address, which keeps it from working.
Comment #66
sonicthoughts CreditAttribution: sonicthoughts commentedRESOLVED WORKAROUND: Use Global Redirect module.
Comment #67
NicoDruif CreditAttribution: NicoDruif commentedHow does the Global Redirect module resolve this issue? What setup do you use? Thanks!
Comment #68
nchicong CreditAttribution: nchicong commentedSuch feature should be supported in Drupal 7. @sonicthoughts, what settings did you have to get it work with Global Redirect?
Comment #69
sonicthoughts CreditAttribution: sonicthoughts commentedNo settings - there were no issues with query strings that I've come across.
Comment #70
svouthi CreditAttribution: svouthi commentedI am running Drupal 7.19 and have Global Redirect installed, but am experiencing the same issue on my e-commerce site.
My Views pages have Simple Hierarchical Select (shs) exposed filters, and instead of displaying the selected taxonomy terms in the results page urls, they display: ?shs_term_node_tid_depth=%. I would love to fix this.
So far, I've altered the Filter identifiers in Views for each of my exposed filters. I replaced the "shs_term_node_tid_depth" with my custom text, but that still leaves the leading "?" and "=%". It would be great to show the tiers of user selections automatically instead.
Comment #71
marcingy CreditAttribution: marcingy commentedFeatures go into latest version of drupal first and then might be backported.
Comment #72
gaurishankarHey
After over viewing all the above suggestion i'm not getting solutions.
I have to alias www.example.com/manager?cust=5 to www.example.com/manager/anything
this aliases also takes internal value like ?cust=5.
Have you any exact solution in D7.
Many Many Thanks in advance for this solution.
Comment #73
StevenPatzComment #74
Exploratus CreditAttribution: Exploratus commentedInterested in a solution for clean exposed filters urls as well.
Comment #75
kenorb CreditAttribution: kenorb commentedBetter Exposed Filters: #2093481: Make filter as links SEO friendly
Comment #76
pitxels CreditAttribution: pitxels commentedGlobal redirect module is working for me as well, but only on the menus not in the aliases
The trick on the menus was using absolute URLs. Hope that helps
Comment #77
edenb CreditAttribution: edenb commentedI have Read all suggestions above.
My goal is to direct users that click on taxonomy term to a search page, which the relevant filter will be already filtered on.
I am using URL aliases,
and trying to direct taxonomy to: www.example.com/search-content?tid=777
I get: www.example.com/search-content%3Ftid%3D777
I have Global redirect installed, but it's still not working.
I also tried URL direct, but I get the same result with html code (%3F), instead punctuation ("?").
Is there any solution?
Or even any work around?
Comment #78
aparnapc CreditAttribution: aparnapc commentedhttp://drupal.stackexchange.com/questions/111307/disable-encoded-url-sho... refer this link .Its work for me.
Comment #79
aparnapc CreditAttribution: aparnapc commentedhttp://drupal.stackexchange.com/questions/111307/disable-encoded-url-sho... refer this link .Its works for me.
Comment #80
vishal.sirsodiya CreditAttribution: vishal.sirsodiya commentedI also have the same problem.
Comment #81
webchickComment #82
alcroito CreditAttribution: alcroito commentedIn case if anyone is interested in the specific use case of rewriting paths with query parameters into a clean URL, there is a contributed module that addresses that.
https://www.drupal.org/project/query_parameters_to_url
It can turn something like
example-site.com/events?field_category_id[0]=100&field_category_id[1]=101&field_author_name[0]=John&field_author_surname[0]=Doe
into
example-site.com/events/p/field_category_id/100-101/field_author_name/John/field_author_surname/Doe
Comment #83
anderso CreditAttribution: anderso commentedThe "Query Parameters to URL" seems to work well - I just tested on a D7 site.
But it does not solve the problem of creating menu items with queries in the URL. I tried and Drupal returned a message that the menu system only stores system URLs, not aliases. Hence, the URL created by "Query Parameters to URL" cannot be used as a menu item.
For me, using "Query Parameters to URL" also caused infinite redirects. I needed to deactivate "Global Redirect" to get it to work and this of course creates new problems with duplicate content.
The only way I could get a menu item with a "?" query in the URL to work was to use an absolute URL as the link. And this causes other issues: 1) not being able to let the user's browser settings choose between HTTP and HTTPS and 2) updating issues and ekstra work if you work with a DEV, TEST and LIVE environment.
Comment #84
alcroito CreditAttribution: alcroito commented1) Regarding menu items, indeed you are right, that it stores the initial url. I'm not sure if this can be fixed, but I'll look into it.
2) I am aware of issues with global redirect, and am trying to work on it. But more specific details would be welcome. Try downloading the latest DEV version of the module, some global redirect issues where fixed there.
Also I'm not sure if this is the best place to discuss about the module. This should be used for fixing the problem in core.
EDIT: I have added experimental code to the Dev version, to allow saving menu items with the encoded query parameters, which can be enabled in the configuration form of the module. Though I consider this a hack.
Comment #85
fjgarlin CreditAttribution: fjgarlin commentedI had the same problem and created a simple module (8 lines!) that does the trick for me. I found this thread from here.
Assuming the module is called "my_url_special_chars", the code is as follows:
There might be another way to solve it, but this did the job for me. Basically I parse the URL and if I find a potential encoded query string I try to go there. That's it. It means that in URL alias patterns I can use "url?key=[term]".
I hope it helps.
Comment #86
arruk CreditAttribution: arruk commented#85 not working for me....
Both terms report: ...is either invalid or you do not have access to it. Access is not the problem. This is for a views created page.
Any thoughts? Thank you :)
Comment #87
fjgarlin CreditAttribution: fjgarlin commentedHi,
Can you dump what's on $url['path'] and $query before doing the drupal_goto?
I've tried this module with replacement patterns, not hardcoded ids, but it should still work anyway.
Let us know what's the output of the dump.
Thanks.
Comment #88
winstonchurchil99 CreditAttribution: winstonchurchil99 as a volunteer commentedI reviewed the #85, this version works fine with drupal 7, just don't use 'q' as query parameter.
Comment #89
anbudhan CreditAttribution: anbudhan commentedHi I am trying to get data from drupal service api using postman.
https://btycc-prod..net/api/v1/entity_commerce_product?parameters[create...
can some one tell me how to get set the parameter to download lesserthan a specific date?
I tried https://bcc-prod.codeenigma.net/api/v1/entity_commerce_product?parameter... <=1428930969:
but it is not working. any help will be hugely appreciated
Comment #90
kenorb CreditAttribution: kenorb commented@anbudhan This is not a help page, but feature report. Try asking your question at DA.
Comment #91
mbayntonAnyone considering implementing this should be aware of #1553358: Figure out a new implementation for url aliases, especially starting around #1553358-40: Figure out a new implementation for url aliases wherein some consensus forms. At time of this post, these are both 8.1.x-dev issues and should be developed with knowledge of each other.
Comment #92
mbaynton8 years and 92 comments later, here's a first stab at a solution. It's late but I'd like to see what testbot has to say about this -- seems there may be a quick enough solution to this that it might as well be handled under the current state of affairs, even if it would need significant rework in #1553358: Figure out a new implementation for url aliases. Still need to evaluate it wrt. multilanguage sites/aliases.
Comment #93
mbayntonHmph. Any way to let the bots in the cloud run the tests for me, without un-postponing it?
Comment #94
webchickTemporarily putting to needs review on 8.0.x so testbot can take a crack at it. Way to completely kick ass, Mike! :D
Comment #96
dawehnerI would vote to use $path . '?' . $request->getQueryString()
Comment #97
mbayntonI don't think that'll work, because according to Symfony docs, "It builds a normalized query string, where keys/value pairs are alphabetized and have consistent escaping." So I have to know that when I want to alias
/thing?query=abcd&page=1
I better actually create the alias as/thing?page=1&query=abcd
.I'm also unsure whether $path is a part of the thing that an alias match should even be attempted against, because $path can be pre-futzed in any unknown way before it's tested against the defined aliases. Since de-aliasing is itself a kind of futzing, it was implemented in the stack of path futzers, but perhaps became an unwitting participant in an overly complex system as a side-effect. If my browser goes to '/a/b/c/d' and I've defined an alias for '/a/b/c/d', is there ever a time when I wouldn't want it to match? If not, de-aliasing should look right at the request URI, with the only possible preprocessing being IRI decoding.
Will look into the test failures later today.
Comment #98
dawehnerGood point!
Well, your implementation won't work because the request URI includes the base path. Could we just use
$this->server->get('QUERY_STRING')
?Comment #99
mbaynton@webchick, thanks for noticing my patch and setting this issue so it's testable!
@dawehner, thanks for the tip on
$this->server->get('QUERY_STRING')
. I wonder if this might cause wrong breadcrumbs from PathBasedBreadcrumbBuilder, but we'll deal with that later I think.The complexity on this ended up ratcheting up a notch or two...of course. If someone sees a simpler way let me know. These obvious things to try don't work:
$path
, such as$path . '?' . $this->server->get('QUERY_STRING')
: doesn't work because it falls victim to the layers of futzing that already happened to $path. In the case of a url whose path looks like the frontpage, ie[drupal]/?p=123
, the $path is rewritten to whatever the configured path for the frontpage is ('node' by default) by the time it is received atPathProcessorAlias
, and you end up asking theAliasManager
to de-aliasnode?p=123
. For this issue's objective, that is bad futzing.$path
, such assubstr($request->getRequestUri(), strlen($request->getBasePath()))
: doesn't work, mainly because the AliasManager expects any language identifiers to have been removed from the path if multilingual's on. That's usually handled byPathProcessorLanguage
, which is good futzing for this issue, but is bypassed since not using$path
. (This code is also no good because of internationalized uri incompatibility and the fact that it lets you define aliases including URL fragments that would actually impact the response, which is worse Internet abuse than the query parameter order being important that this issue enables.)The only thing I could think to do then was to start with $request->getPathInfo() + $request->server->get('QUERY_STRING'), pull in the "good" futzers, and apply only them before de-aliasing. This works, more or less, with some subtleties I still need to address. I probably am accessing the other PathProcessor services wrong, those code patterns are still new to me. But this is a good stopping point to see if anyone sees a simple/obvious better way before finishing polish on this one (to include new tests.)
A general note about the objective/rationale of this patch: it intentionally processes query strings by string equality comparison; so
?var1=abc&var2=def
does not yield the same response as?var2=def&var1=abc
. I justify this as acceptable because 1) it's sufficient to make lots of the above discussed use cases "just work", 2) it's simple, 3) if a particular site finds such things unacceptable, just refrain from creating aliases that utilize them, and 4) this change wouldn't prevent a contrib module sitting on top of it to define more complex rules about which query parameters have which impacts on path futzing.This passed a subset of likely tests locally, crossing my fingers...
Comment #101
mbayntonLooks like some more unit tests would need updating, but simpletests all green.
Comment #102
dawehnerWe should certainly expand the test coverage for this new feature.
Comment #103
mbayntonJust feeding the testbots -- this is still a WIP, but also a much improved rewrite from #99
Comment #104
mbayntonComment #106
dawehnerTo be honest I don't get why we can't just put the logic into the alias path processor and be done. The additional abstraction seems not necessary for me.
Do you mind explaining it a bit in the issue summary?
Comment #107
mbayntonComment #108
mbayntonComment #109
mbayntonQuestion: handling query parameters irrespective of query string order could be accomplished at the AliasStorageInterface level, by just stipulating that
lookupPathSource
detects query strings in any aliases passed to it, and returns the corresponding path regardless of parameter order. In core'sAliasStorage
implementation you'd do this by just transforming any query string present in an alias to its normalized form inDrupal\Core\Path\AliasStorage::save
, and again inlookupPathSource
. But, would that kind of logic be appropriate for a storage class?Comment #110
mbayntonHere's a (first) patch that I expect will pass all existing tests. Writing a complete set of additional test coverage for this approach would presumably involve some unit tests of the new service, but I'm still wondering if @dawehner (or anyone) thinks the functionality I've split out to a new service is justified, now that I've written up my rationale in the issue summary. Depending on that I'll do the time investment on new unit tests or not.
Comment #111
mbayntonComment #114
dawehnerWe should really have tests ... that's kind of important to not get stuck in one specific implementation.
Comment #117
emclaughlin CreditAttribution: emclaughlin at Boston Digital commentedReroll
Comment #119
drupalninja99 CreditAttribution: drupalninja99 at Mediacurrent commentedRight now I get a 404 going from alias /test to /node/1?foo=bar even if the latter system path works on its own.
Comment #120
kiss.jozsef CreditAttribution: kiss.jozsef commentedAny update on this , or any other idea how to accomplish this ? i am getting 404 errors too
Comment #121
mbayntonI resorted to just telling Apache to do the redirects via server / .htaccess configuration
Comment #123
Spudley CreditAttribution: Spudley commentedI would like to add my voice to the others who are asking for this. It seems like a simple request to be able to make a path alias for
/node/1?foo=bar
. Please Drupal, can we fix this?Comment #124
Falco010Any update on this? Facing similar issues
Comment #125
mlncn CreditAttribution: mlncn at Agaric for MASS Design Group, Drutopia commentedAlso need this. We only need from
/simple-alias
to/internal-path/?query=this&otherquery=that
. It seems that the approach in this issue is to handle both directions at once, so we'll try to support that, but wondering if it would be better to take the two needs separately? And i don't understand why this seemingly simpler case (just don't throw away the configured query string!) is being recommended against even being allowed in the present issue summary.Comment #128
StijnStroobantsOld topic, but it still looks relevant.
Are there any updates on this?
Comment #129
PasqualleComment #132
ankithashetty++ on the feature request.
Even the pathauto module does not allow us to add tokens as query parameters.
Comment #136
ressa CreditAttribution: ressa at Ardea commentedI agree @ankithashetty, this would still be a great feature to add to the Path module.
Comment #137
prudloff CreditAttribution: prudloff at Insite commentedI tried to reroll the patch for Drupal 10.1.
It applies correctly and does not crash but I think it does not do what we need so I have not tested it fully.
We need to create an alias from
/foo
to/node/42?foo
and if I understand the patch correctly, it only handles the reverse scenario/?foo
to/node/42
?