Problem/Motivation
We currently have a token [site:url]. The URL of the site's front page. The language prefix is added if the page is multilingual (e.g. http://www.example.com/pl).
In many cases a language prefix is unnecessary.
Example:
Open graph image path
[site:url]/sites/default/files/og_image.jpg
JSON LD ImageObject path
[site:url]/sites/default/files/logo.jpg
We need a new token that returns the base url without the language prefix.
Proposed resolution
Add token [site:base-url]. Base URL.
Remaining tasks
Add test.
User interface changes
Users can use the new token [site:base-url].
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #74 | Site Base URL token.png | 81.01 KB | mitthukumawat |
| #61 | Screen Shot 2020-09-12 at 9.38.00 AM.png | 22.78 KB | anas_maw |
| #58 | drupal-base_url_path_tokens-1088112-58-D8.patch | 5.52 KB | liam morland |
| #48 | 1088112-48-44-interdiff.txt | 1.7 KB | mbovan |
| #48 | 1088112-48.patch | 4.48 KB | mbovan |
Issue fork drupal-1088112
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 10.1.x
compare
- 9.3.x
compare
- 1088112-introduce-a-token
changes, plain diff MR !451
Comments
Comment #1
dave reidPassing a string when $options['language'] needs to be a language object is invalid input and would cause PHP notices. This works as designed. Sounds like you want to be using 'Path based negotiation with fallback to default language if no defined path prefix identified.' mode for locale.module instead.
Comment #2
ao2 commentedChanging the focus a little bit, as code out of context can be misleading sometimes.
The point is that I would have expected the
[site-url]token to give back the base URL, without the language prefix in it, for the latter maybe another token could be used. What is your opinion on that?@Dave Reid: I am already using the “Path prefix with language fallback” setting.
BTW, your suggestion sounded more about the “input” URL for getting to contents, while my concerns were more about the token “output” itself, but maybe I am still missing something.
Thanks,
Antonio
Comment #3
dave reidPardon, it's the 'Path prefix only' setting on that will not output the default language prefix when using url() which is what you want.
Comment #4
nicolas bouteille commentedSorry I don't understand how I am supposed to obtain the base url via a token.
I want my open graph image path to be set as [site:url]/sites/default/files/og_image.jpg
Unfortunately the language prefix is added so the path http://www.mywebiste.com/fr/sites... does not exist.
What should I do ?
Comment #5
guile2912 commentedI had the same problem, finished creating my own token so that images in mail works. Just use [url-abs] and tadda, you have the web url without the language prefix.
Comment #6
Wtower commentedAlternatively, if you do not wish to create a new module, you can use the Custom Tokens module and create the new custom token url-abs with the following PHP code in it:
I didn't manage to do #5 in template.php, which is a nice solution. I don't understand why standard token module does not have such a token.
Comment #7
candelas commentedThanks @guile2912 I could use your code in menu_token to link to pdfs, as you can see here
https://drupal.org/node/1151856#comment-8794261
Comment #8
allenfantasy commentedJust in case someone is looking for this answer, this comment has already made the shot:
https://api.drupal.org/comment/46528#comment-46528
Comment #9
luksakThis issue still seems to exist. Can we provide a token for this?
Comment #10
berdirYes, it exists, but it does so by design. "Fixing" it to work like you'd expect might break it for others that expect it.
The only solution would be to define a new token, something like [site:base]
Comment #11
luksakTrue, this would make more sense. Should we use this issue or a new one for this?
Comment #12
kopeboyThis is true in Drupal 7 too, OMG! I've been using this wrong forever :/
This is so serious for Metatag module..
Comment #13
luksakI tried to find the right place to fix this. The token contrib module doesn't seem to be providing the site tokens. Drupal core's system module provides them.
The attached patch fixes the issue for me. Three things are missing:
1) IS update
2) The other tokens add cachable dependencies:
$bubbleable_metadata->addCacheableDependency($result);My patch doesn't for the new
[site:base-url]token.3) Test are missing.
For those that want to implement this in a custom module, here is a gist: https://gist.github.com/luksak/6e1d24e10be056a304b46ce77e90b71f
Comment #16
YurkinPark commentedI've checked your patch and realized that it doesn't work, i'm providing own.
Comment #17
weseze commentedPatch works perfectly. Can't believe this is not in core...
Comment #18
krzysztof domańskiMissing dot in the description text.
Comment #19
krzysztof domańskiAdds test coverage.
Comment #21
krzysztof domańskiImproving test and bubbleable metadata.
Comment #22
krzysztof domańskiUpdate issue summary.
Comment #23
krzysztof domańskiThe description of the token [site:url] requires more details. The new and old token are very similar. It can be confusing. I suggest change the description of the old token [site:url].
Comment #24
kamil jaszczuk commentedComment #25
alexpottThe words
base urlare complex in Drupal. The problem is what the Symfony request thinks of as the base URL and what Drupal defines it as are different concepts. See \Drupal\Core\DrupalKernel::initializeRequestGlobals() and what's called$base_rootand$base_urland how the base url global in Drupal is changed depending on the script location.Especially as this is user-facing text we need to describe this differently. Maybe something based around the Symfony words of
the scheme and HTTP host.Comment #27
mbovan commentedI have tried to address #25 by coming up with "Origin URL" term which sounds more user-friendly IMHO.
Comment #28
anybody+1 for #27!
Comment #29
mohammed j. razem+1 for #27 in my opinion.
Since "location.origin" indicates protocol + domain name, to me it sounds descriptive to call it "Origin URL"
[site:origin-url].Comment #30
mrshowermanReroll of #27 against current 8.8.x; patch wasn't applying any more due to https://www.drupal.org/node/2731817
Comment #31
ahmad abbad commented+1 for #30
Comment #32
anybodyI agree with #29: To be consistent, it should be
"origin-url" instead of "url-origin" which would mix things up. Positive side-effect: All URL tokens are ordered below each other.
Comment #33
krzysztof domański1. I updated the issue summary according to recent comments (new token name).
2. We need a change record.
Comment #35
mbovan commentedPrepared a change record at https://www.drupal.org/node/3092269.
Comment #36
mbovan commentedI triggered tests for #30 on 8.9.x branch all tests passed successfully.
Since many people, +1'd the latest changes regarding the token name I am going to remove "needs usability review" tag and RTBC it.
Comment #37
alexpottDoing a bit of thinking about this change. It's quite complicated because on multi-lingual sites where this is an issue what does actually mean? Which language and how it is determined.
Here's the list of site information URLs we have with core (name, token and description) - we now have both scheme and protocol describing essentially the same thing. Somehow all of these need to work together to make it is easy for the user to choose the correct one.
Another complicating factor is the fact that Drupal can be in a sub-directory and the Origin URL will not reflect that. I think the name and token need to replace that this is only the http-host and protocol/scheme. I don't think "Origin URL" quite covers that atm.
Maybe an alternative here would be to provide the HTTP_HOST only - minus the protocol/scheme. I'm pretty sure that's what people really wanted with the "URL (brief)" token and this way if people want to build URLs this will be flexible to provide the base for quite a few things. And it could be called "HTTP host" so it'd be very clear how it was different from everything else.
Comment #38
berdir> Doing a bit of thinking about this change. It's quite complicated because on multi-lingual sites where this is an issue what does actually mean? Which language and how it is determined.
Note that there is actually no change here, the only change is documenting the existing behavior. It defaults to the current URL language (like all links that don't provide the language explicitly) or the language provided to the token replace call. So for example for [site:url] in an password recovery e-mail is for the language of the user the e-mail is sent to.
Which makes it quite hard to explain, as the description is static and has no way of knowing what "the language" will be.
About base and original. I think the token *should* include the base url, and then IMHO site:base-url is still the better name. The example in the issue summary ( [site:url]/sites/default/files/og_image.jpg) does require the base path. Also, the site:url cache context that we use has this implementation:
which is base url, so I think we should use the same implementation and name. Additionally, it also maps to Url::fromUri('base:sites/default/files/og_image.jpg').
Comment #39
alexpott@Berdir great idea. +1
Comment #40
mbovan commentedUpdated the patch according to the latest suggestions ->
[site:base-url].I was not sure whether we should use
$request->getBaseUrl()or$request->getBasePath(). When you are ondrupal.test/subdir/index.php/user/login,$request->getBaseUrl()will return/subdir/index.phpwhich can produce unwanted results when this token is used in the mentioned example[site:base-url]sites/default/files/og_image.jpg.However, the same URL is resolved with
Url::fromUri('base:sites/default/files/og_image.jpg')so I followed the same behavior...Comment #41
mbovan commentedUpdated the issue summary and the change record https://www.drupal.org/node/3092269.
Comment #42
berdirHm, the index.php thing is interesting. If Url::fromUri('base:') works the same way then maybe we should keep it consistent, but it does seem wrong as your example shows.
This is a kernel test, so we should be able to hardcode what we expect exactly, afaik it's always going to be http://localhost. We could also simulate a base path by changing the request.
Comment #43
mbovan commentedAddressed #42.2.
Comment #44
mbovan commentedAdded assertion for the cacheable metadata too.
Comment #45
berdirThis looks good to me. The one remaining problem now is the getBaseUrl() vs getBasePath() thing, which is I think incorrectly implemented for Url::fromUri('base:') too. I'm not sure if we should add the likely wrong but consistent implementation here or use the correct one and open a follow-up to only fix for base:some/path.
There actually were bugs about base:, for example #2881999: Path to statistics.php is not correct when the path start with index.php, the "fix" there was to stop using base:, but maybe we should have fixed base: instead?
Comment #46
alexpottI think we should prioritise what’s right. If
base:is broken let’s fix it (in another issue). So let's make this work how a user would expect rather than being consistent with something that is a little bit borken.Comment #47
berdirDiscussed with @alexpott. Lets implement it here without index.php in the path (lets also test that explicitly if possible), and open a follow-up to fix Url::fromUrl('base'), as part of that we could revert the statistics.php fix and we should have some test coverage already.
Comment #48
mbovan commentedI created a follow-up to fix URLs with
baseprefix #3099926: Fix base prefix when generating URLs if index.php is in the path and fixed the [site:base-url] token to exclude "index.php" if it is present in the path.Additionally, I am uploading a test-only patch which adds test coverage for this case, created on top of #44.
Comment #50
liam morlandIt seems to me that there should be bothThis doesn't work with what getBaseUrl() actually does.[site:base-url](using Request::getBaseUrl()) and[site:base-path](using Request::getBasePath()).Comment #51
liam morlandAttached is a patch which builds on #48 and has both
[site:base-url]and[site:base-path].Comment #52
jungleFix coding standards, see https://www.drupal.org/pift-ci-job/1620405
14 | ERROR | Doc comment short description must be on a single line, further text should be a separate paragraph (Drupal.Commenting.DocComment.ShortSingleLine)
148 | WARNING | Line exceeds 80 characters; contains 84 characters (Drupal.Files.LineLength.TooLong)
In fact, there are two more, but Drupal.org CI did not complain about it, so they are untouched.
Comment #53
liam morlandRe-roll. In #52, item 1 is in the existing code, so this patch does not touch it.
Please let me know if a version of this patch is required for 9.0.x.
Comment #54
slv_ commentedJust confirming that #53 has been working well for me since I applied it a couple weeks ago on a production site.
Comment #56
liam morlandReroll.
Comment #57
liam morlandComment #58
liam morlandRe-roll.
Comment #59
anas_maw commentedPatch in in #58 working fine for me
Comment #60
liam morland@Anas_maw, feel free to mark this RTBC.
Comment #61
anas_maw commentedWorking as expected
Comment #62
alexpottI think we need to concatenate @scheme_and_http_post@base_path outside of the string. Ie.
That's because the current construction will make a replacement like this
<em>scheme_and_http_post</e><em>base_path</em>- also scheme_and_http_post - post? :)Comment #63
raman.b commentedAddressing #62
Comment #65
tanubansal commentedApplied patch #63, Issues mentioned in #62 has been resolved
RTBC + 1
Comment #66
ahmad abbad commentedPatch in in #63 working fine for me
Comment #67
pcate commentedPatch applied to 8.9 and 9 and new token worked. I needed this for including urls in some emails.
Comment #68
krzysztof domańskiNeeds a re-roll.
Comment #69
ankithashettyRerolled the patch in #63, thanks!
Comment #72
liam morlandI have created an issue fork and merge request with the patch from #69.
Comment #73
vakulrai commentedThe Patch #69 is getting applied cleanly, but I have a finding:
The method
\Drupal::request()->getBasePath();is actually not taking care of A scenario if /index.php is there in the url like http://localhost/web/index.php returns '/web' should return /web, but actually its truncating that and returning empty string , and because of thatis failing tests.
I think Symphony Symfony\Component\HttpFoundation\Request has a missing condition.
Please review !
Thanks
Comment #74
mitthukumawat commentedThe Patch #69 applied successfully and the site base URL token available now.
Comment #76
liam morlandRe-rolled for 9.3.x.
Comment #77
darvanenGood candidate for review pending discussion regarding scope of this core module vs contrib token module.
Comment #78
rlnorthcuttNote that we are recreating a similar thing for the Project Browser initiative, and I foresee this becoming more needed as we create more decoupled components.
https://www.drupal.org/project/project_browser/issues/3227738
Comment #80
darvanenI've read the comments and the current version of the code, everything seems to be squared away except for:
I'd be happy to push it to RTBC if those are complete.
Comment #81
jeroentI've updated the change record.
Only the author of the MR can change the target branch, so @Liam Morland should do this.
Comment #82
liam morlandComment #83
darvanenOk, looks good to me, test coverage was increased earlier and all the feedback has been addressed as far as I can see.
Comment #84
alexpottSetting to needs work to address the comment on the merge request.
Comment #85
jeroentComment #88
nod_D10 version needed
At this time we need a D10.1.x patch or MR for this issue.
Patch or MR doesn't apply anymore
The last patch or MR doesn't apply to the target branch, please reroll the code so that it can be reviewed by the automated testbot.
Comment #89
bhanu951 commentedComment #90
jeroent@Liam Morland, can you update the target branch to 10.1.x ?
Comment #91
bhanu951 commentedComment #92
liam morlandComment #93
darvanen#84 has been addressed, as has #88. I'm having difficulty comparing the current state of the MR to what it was last time I made this RTBC because of the rebase, but the code looks good and tests are passing so I'm gonna call this RTBC again.
Comment #95
lauriiiCommitted 84a67e9 and pushed to 10.1.x. Thanks!