How to add a parameter to every URL Vanilla generates
I'm creating a plugin similar to Multilingual, but instead of having the locale chosen by user preference, I'm having it go only based on a request parameter. To make this work right, I need to add the locale parameter to every URL generated by Vanilla so that when users click around, they will always stick with the same locale.
What I've done is create a bootstrap.before.php
file with:
<?php if (!defined('APPLICATION')) exit(); # Just like in functions.general.php, except add the locale function Url($Path = '', $WithDomain = FALSE, $RemoveSyndication = FALSE) { $Result = Gdn::Request()->Url($Path, $WithDomain); $Result .= (strpos($Result, '?') ? '&' : '?') . 'locale=' . urlencode(GetValue('locale', $_GET, FALSE)); return $Result; }
This seems to add the parameter to most links, but many do not get the change, for example Categories, Recent Discussions, Activity, and the self-links to individual posts. Other links get mangled, like the jsConnect sign in URL, where the URL gets generated with two question marks.
I'm wondering if there's a more effective way to accomplish this. If not, would pull requests be accepted to make it so all URLs get passed through the Url
function?
Best Answers
-
x00 MVP
assume that
forum
is the location of you forum.create a file called
alter_root.php
in the forum root, add<?php if(array_key_exists('locale', $_GET)){ $_SERVER['PHP_SELF'] = '/'.$_GET['locale'].$_SERVER['PHP_SELF']; }
Add these location rules
location ~ ^(/([a-z][a-z]))/forum { set $args $args&locale=$2; rewrite ^(/[a-z][a-z])/forum(/?(.*)) /forum/$2 last; } location /forum { try_files $uri $uri/ @forum; } location @forum { fastcgi_param PHP_VALUE "auto_prepend_file=$document_root/forum/alter_root.php"; rewrite ^/forum/(.+)$ /forum/index.php?p=$1 last; }
grep is your friend.
3
Answers
if you don't get changes made with your pull requests....
what about somehow adding it via jQuery.
or something similar to
https://github.com/vanilla/vanilla/issues/1436
or doing what you have and searching for locale and filling in if not present. and skipping when two question marks appear in string.
I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.
Adding it with JS is a good suggestion and may be part of the solution, but it would miss redirects, dynamically generated content, and of course wouldn't work with JS disabled.
The problem with the jsConnect case is that it runs after my code, and its code is the one adding the second question mark.
If you want to make some kind of preference persist, why not use
You could still switch it with a url parameter by checking for that like so
If you are also targeting unregistered users, I'd just set a cookie.
My themes: pure | minusbaseline - My plugins: CSSedit | HTMLedit | InfiniteScroll | BirthdayModule | [all] - PM me about customizations
VanillaSkins.com - Plugins, Themes and Graphics for Vanillaforums OS
That's what Multilingual does, and it's not what I want. I want URLs to be consistent in what language they load, as I think that's best practice and matches the site I'm integrating Vanilla into.
JasonBarnabe with respect this not smart. Not smart at all, and definitely not best best practice. You don't want that crap in links, it is not clean nor is it RESTful, it is not what GET parameters are for, persistent user setting across the site.
Best practice would be either Session variable or submission/directory prefix, working with detection.
The later you will handle with server rule, then you will detect it.
Example
http://en.youdomain.com/forum/
orhttp://youdomain.com/en-GB/forum/
Where parameter are use at all, this would be an internal request such as for a legacy software.
grep is your friend.
I intend on making it a path prefix and have it rewritten through server rules, but I'm starting with a query parameter to keep things simple for testing. In either case, the problem remains the same - the
Url
function is not being called for all URLs, so I can't retain the path prefix/request parameter as the user navigates through the site.This is an interesting issue.
Why not do something like the API application and create controllers for all the supported languages. They all extend a base controller that will set redirect control to the "proper" controller. They also set the prefix to the real route via the URL function.
You would end up with routes like
en/discussions/unread
andgb/discussions/unread
that go to the same routediscussions/unread
.You still have the same issue as before with links that don't go through the Url function. Not necessarily better, but cleaner imo.
Search first
Check out the Documentation! We are always looking for new content and pull requests.
Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.
If the locale identifier is in the path like @x00 suggested, it will appear in every url that vanilla creates
You might need to play around with C('Garden.WebRoot') or set it dynamically
My themes: pure | minusbaseline - My plugins: CSSedit | HTMLedit | InfiniteScroll | BirthdayModule | [all] - PM me about customizations
VanillaSkins.com - Plugins, Themes and Graphics for Vanillaforums OS
Thanks for the suggestion. I was thinking of using an Nginx rewrite rule to turn the path prefix into a query parameter by the time Vanilla got a hold of the URL, but I'll keep that in mind if that doesn't work out.
(That was a reply to @hgtonight)
@Bleistivt You think if I do the rewrite rule to turn path prefix into request parameter Vanilla will automatically generate the URL with path prefixes? I don't think it'll work like that, but I'll try a bit later and let you know.
It should work, but if not there are various environment variables you can set in nginx rule to force it to work, it is all depends how php is handled.
grep is your friend.
I have the nginx rewrite rule working, I can load my forum for example at /en/forum/ and my plugin can see locale=en as a parameter. This however has done nothing to the URLs generated - they still do not include the locale.
I looked at Webroot as suggested by @Bleistivt. The only effect this seems to have is in combination with StripWebRoot, where the value set will be removed from the URL rather than added, which results in URLs like /discussion instead of /forum/discussion as it is now.
I came across the reason why some URLs are not rewritten by my custom
Url
function - they get generated by a direct call toGdn::Request()->Url
. This seems limited to about 15 calls, so a pull request changing this wouldn't be too crazy. I'd like to know if this kind of change would be accepted before I pursue this avenue.I think I may have found a stupid hack to make it work, though. If I take the rewrite rule out and symlink /en/forum/ to /forum/, things seems to be working...
Like I said it can be done with server rules.
Add
fastcgi_param SCRIPT_FILENAME $document_root/en$fastcgi_script_name;
inside the forum location block
grep is your friend.
No, that's the opposite of what I'm doing. That will make the URL /forum/ try to load the PHP scripts from /en/forum/. I want the URL /en/forum/ to load the PHP scripts from /forum/. The symlink method accomplishes this. Is there a way I can use a rule like that to strip the /en from $fastcgi_script_name?
Hold on the rule a bit more complex that that. let me get an example together.
grep is your friend.
assume that
forum
is the location of you forum.create a file called
alter_root.php
in the forum root, addAdd these location rules
grep is your friend.
sorry add
fastcgi_param PHP_VALUE "auto_prepend_file=$document_root/forum/alter_root.php";
to the php pass section of the the conf
grep is your friend.
Thanks for that, at first glance it seems to be working. I'm going to test some more and will include it in the documentation when I release the addon.
http://vanillaforums.org/addon/languagebypath-plugin