I'm a Silex newbie and I'd like to redirect the '/' url to the default language like '/en' for example. I do this :
$app->match('/', function(Application $app){
return $app->redirect('/Silex/www/'.$app['locale_fallbacks'][0]);
});
Am I constrained to put the absolute url from the root of the server ? I'd like to put only $app->redirect('$app['locale_fallbacks'][0]);. And is it the right way to get the default language ?
Thanks a lot
You do not have to give the host there. As in your match() you will pass a relative url. However it would probably be better not to make a new roundtrip to the browser and to forward the request internally or even rewrite it via .htaccess.
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
$app->match('/', function () use ($app) {
$subRequest = Request::create('/' . $app['locale_fallbacks'][0], 'GET');
return $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
});
Related
I am attempting to provide users with a common functionality, redirecting them after login to the originally requested url that is behind a secure path. Example, user clicks link in email triggered via notification in the system, attempts to go to:
https://mysite.com/secure/notifications/1
User is not logged in so kicked back to
https://mysite.com/login
After login they should be brought not to their home page, but to the originally requested url.
I am familar with the technique to store the attempted URL in session before redirecting to login page. The issue is if the URL contains a backbone router after the core URL, ie
https://mysite.com/secure/notifications/1#details
The #details part of the URL is not sent to server it seems, as this is typically for inner page jumping. I am wondering how are web developers dealing with this as JS MVC frameworks like backbone, angular, and other are emerging? Some trick? Any way to actually have the # pass to server in http specification?
Any ideas are appreciated, thank you.
The easiest solution to this problem, if you don't need to support this behaviour for older browsers, is to enable pushState in your backbone router so you don't use # for routes:
Backbone.history.state({pushState: true});
Edit:
The other potential solution, though it is a bit messy, is to do some URL tomfoolery to figure out what should be after the hash and then navigate to that route.
For example, let's say that you want to navigate to:
http://webapp.com/abc/#page1 where 'page1' is the fragment which makes up the Backbone route.
If you instead send the user to http://webapp.com/abc/page1. You can detect whether the browser has pushState. If not, you can replace everything after the 'root' with the hash. Here is some example code which might get you on the right track to supporting both sets of browsers:
var _defaults = {
pushState: Modernizr.history,
silent: true,
root: '/'
};
var start = function(options) {
// Start the routing either with pushstate or without
options = _.extend(_.clone(this._defaults), options);
Backbone.history.start(options);
if (options.pushState) {
Backbone.history.loadUrl(Backbone.history.getFragment());
return;
}
this.degradeToNonHistoryURL();
};
/**
* For fragment URLs, we check if the actual request is for the root i.e '/',
* If it is, we can continue and Backbone will do the magic
* If it isn't we redirect to the root with the route as a fragment
* foo.com/bar/1 -> foo.com/#bar/1
*/
degradeToNonHistoryURL = function() {
var pathName = window.location.pathname;
// If the root is '/', length is one. If the root is 'foo', length is 5 (/foo/)
var rootLength = _getRoot().length;
var isRootRequest = pathName.length === rootLength;
if (!isRootRequest) {
var route = pathName.substr(rootLength);
window.location.href = _getRoot() + '#' + route + window.location.search;
return;
}
Backbone.history.loadUrl(Backbone.history.getFragment());
},
/**
* Get the effective root of the app. Normally it's '/', but if set to 'foo', we want
* to return '/foo/' so we can more easily determine if this is a root request or not.
* #returns {String} The effective root
*/
_getRoot = function() {
if (Backbone.history.options.root === '/') {
return '/';
}
return '/' + Backbone.history.options.root + '/';
},
The trick here is making the pushState URL your canonical URLs and always sending users to those ones. Once browser adoption increases, it should theoretically be easy to cut all of this crap out without having to update all of your links.
After some research it seems there are only two solutions
As recommended by Will, use pushState and only support HTML5 browsers, but this is a massive change for existing apps using hash or hashbang javascript navigation.
Workarounds on server side, the main option here is around providing redirect endpoints to get users where then need to go. Example
/myapp/redirector?pathroot=notifications&hashroot=details&hashparam1=2
this would then build up a url on server side
/myapp/notifications/1#details/2
So in #2 the server cannot receive http requests with hashtags, however it can send them. The browser will receive this full path including hash nav part, and do its normal javascript MVC routing thing.
So I know how to access both external and internal URL's in the Titanium Webview. But I have no idea how to redirect from an external url to the internal url.
I've got a file called "index.html" in the root folder, so for the webview this should work to access it:
Ti.UI.createWebView({
url: 'index.html'
});
External urls are pretty straight forward
Ti.UI.createWebView({
url: 'http://www.google.com'
});
However, when on the external url, how do I redirect to this local file? None of these work:
LOCAL?
LOCAL?
or the javascript variant
window.location = 'file:///index.html';
Any clues on how to do this?
What I discovered, in the end, are 2 possibilities to achieve this. But it can't be done through redirection.
One: Poll for a certain variable using the webview.evalJS() function
var my_data = $.login_webview.evalJS('global.data;');
Of course, it works only with strings, not with objects. So if you're passing JSON, make sure it is set as a string!
Two: Do an actual redirection server side, to another serverside page and monitor for URL change and then do evalJS() once again, but no need for polling
$.login_webview.addEventListener('load',function(e){
if (e.url.indexOf('mobile/redirect.php') > -1){
var my_data = $.login_webview.evalJS('global.data');
}
});
Just make sure, with 2 that you're actually setting the required data in Javascript using server side technology.
I want to manipulate the client url "www.example.com/download.." to "one.other.com/download...
But I want that the url on the client maintain the first "www.example.com/download"
Is there any way with Varnish 3 to do this??
Yes, you can easily do it using the regsub() function in VCL in vcl_recv.
For instance:
if (req.http.host ~ "^(www\.)?example\.com" && req.url~ "^/download/") {
set req.http.host = "one.other.com";
set req.url = regsub(req.url, "^/download/", "/");
}
This examples rewrites access to http://www.example.com/download/example.jpg to http://one.other.com/example.jpg. Of course, it is not visible to the user.
The Url for my development environment is:
http://localhost/mysite/blah...
I am using jQuery & getJSON to perform some ajax actions on my site, which work fine all the time I specify the url as:
/mysite/controller/action
..but this is not ideal as I don't want to hardcode my development url into my seperate jQuery include files.
When the site goes live, it'll be fine to have controller/action or /controller/action as the url as that will resolve ok, but for the development site, it's no go.
I've tried:
controller/action
..but this returns a 404, which suprised me as I thought the lack of / at the front of the url would prevent from looking at the website root.
There must be a neat solution to this?
I would do this by inserting a global constant in my HTML header:
<script type="text/javascript">
var BASE_URL = '/mysite/';
</script>
That would be inserted from your server so it can be dynamically changed.
Later in your script, you'll be able to make AJAX requests with (jQuery style here):
$.ajax( BASE_URL + '/controller/action', ...);
If you're in
/mysite/controller/action
then the correct relative path to
/mysite/some_other_controller/some_other_action
is
../../some_other_controller/some_other/action
You can use this code to get the current path of the .js script and use it for calculate your relative path.
var url;
$("script").each(function () {
if ($(this).attr("src").indexOf("[YOUR_SCRIPT_NAME.JS]") > 0) {
url = $(this).attr("src");
url = url.substr(0, url.lastIndexOf("/"));
return false;
}
});
var final_url = url + "/your_target_script.js"
Replace YOUR_SCRIPT_NAME with the unique name of your script.
I am having a problem with Twitter's oauth authentication and using a callback url.
I am coding in php and using the sample code referenced by the twitter wiki, http://github.com/abraham/twitteroauth
I got that code, and tried a simple test and it worked nicely. However I want to programatically specify the callback url, and the example did not support that.
So I quickly modified the getRequestToken() method to take in a parameter and now it looks like this:
function getRequestToken($params = array()) {
$r = $this->oAuthRequest($this->requestTokenURL(), $params);
$token = $this->oAuthParseResponse($r);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}
and my call looks like this
$tok = $to->getRequestToken(array('oauth_callback' => 'http://127.0.0.1/twitter_prompt/index.php'));
This is the only change I made, and the redirect works like a charm, however I am getting an error when I then try and use my newly granted access to try and make a call. I get a "Could not authenticate you" error. Also the application never actually gets added to the users authorized connections.
Now I read the specs and I thought all I had to do was specify the parameter when getting the request token. Could someone a little more seasoned in oauth and twitter possibly give me a hand? Thank You
I think this is fixed by twitter by now or you might have missed to provide a default callback url in your application settings, which is required for dynamic callback url to work as mentioned by others above.
Any case, I got this working by passing the oath_callback parameter while retrieving the request token. I am using twitter-async PHP library and had to make a small tweak to make the library pass the callback url.
If you are using twitter-async, the change is below:
modified getRequestToken and getAuthenticateURL functions to take callback url as parameter
public function getRequestToken($callback_url = null)
{
$params = empty($callback_url) ? null : array('oauth_callback'=>$callback_url);
$resp = $this->httpRequest('GET', $this->requestTokenUrl, $params);
return new EpiOAuthResponse($resp);
}
public function getAuthenticateUrl($callback_url = null)
{
$token = $this->getRequestToken($callback_url);
return $this->authenticateUrl . '?oauth_token=' . $token->oauth_token;
}
And pass the callback url from your PHP code.
$twitterObj->getAuthenticateUrl('http://localhost/twitter/confirm.php');
#Ian, twitter now allows 127.0.0.1 and has made some other recent changes.
#jtymann, check my answer here and see if it helps
Twitter oauth_callback parameter being ignored!
GL
jingles
even me to was getting 401 error.. but its resolved..
during registering your application to twitter you need to give callback url...
like http://localhost:8080.
i have done this using java...
so my code is: String CallbackURL="http://localhost:8080/tweetproj/index.jsp";
provider.retrieveRequestToken(consumer,CallbackURL);
where tweetproj is my project name
and index.jsp is just one jsp page...
Hope this may helps u...
After the user authorizes the application on twitter.com and they return to your callback URL you have to exchange the request token for an access token.
Twitter does not honor the oauth_callback parameter and will only use the one specified in the registered application settings.
It also doesn't allow for 127.0.0.1 or localhost names in that callback, so I've setup http://dev.twipler.com which is setup for 127.0.0.1 in DNS so you can safely use;
http://dev.twipler.com/twitter_prompt/index.php