I have been learning Laravel recently and I have seemingly missed a key point: why should relative links be avoided?
For example, I have been suggested to use URL::to() which outputs the full path of the page passed as a parameter - but why do this when you could just insert a relative link anyway? E.g., putting URL::to('my/page') into a <href> will just insert http://www.mywebsite.com/my/page into the <href>; but on my website href='my/page' works exactly the same. On my website I have based all relative URL's from the index.php file found in the public directory.
Clearly, I'm missing a key point as to why full paths are used.
I've found that using route() on named routes to be a much better practice. If at one point you decide, for example, that your admin panel shouldn't point to example.com/admin, but example.com/dashboard, you will have to sift through your entire code to find all references to Url::to("/admin"). With named routes, you just have to change the reference in routes.php
Example:
Route::get('/dashboard', ['as' => 'admin', 'uses' => 'AdminController#index']);
Now every time you need to provide a link to your admin page, just do this:
Admin
Much better approach, in my opinion.
This is even available in your backend, say in AdminController.php
// do stuff
return redirect()->route('admin');
http://laravel.com/docs/5.1/routing#named-routes
Neither absolute nor relative links should be used - it's advisable to use named routes like so:
Route::get('my/page', ['as' => 'myPage', function () {
// return something
}]);
or
Route::get('my/page', 'FooController#showPage')->name('myPage');
Then, generate links to pages using URL::route() method (aliased as route() in L5), which is available in Blade as well as in your backend code.
That way, you can change the path to your routes at any time without having to worry about breaking links anywhere in your application.
Related
When I have this named route:
Route::get('/', 'IndexController#index')->name('home');
Then in any action method of any Controller; when I need to redirect to the named route home; any of these statements redirects properly to the intended route:
return redirect('/');
return redirect()->route('home');
return redirect()->home();
When to use each?
What are the differences?
Are there any benefits of using one over the others?
As the documentation mention :
When you call the redirect helper with no parameters, an instance of
Illuminate\Routing\Redirector is returned, allowing you to call any
method on the Redirector instance. For example, to generate a
RedirectResponse to a named route, you may use the route method
As you can see in the API methods(link below) there is a lot of methods that you can use and also there is one specific helper method home() it's just a shortcut for redirect()->route('home') as highlighted by #ceejayoz.
Now the we will talk about return redirect('/'); and return redirect()->route('home'); the two of them redirects properly to the intended route as you said BUT the second one is really useful if in the future.
Why ?
Because if you want to change the URL structure in the routes file all you would need to change is the route only for example :
Route::get('/', 'IndexController#index')->name('home');
Will be :
Route::get('/home_page', 'IndexController#index')->name('home');
and all the redirects would refer to that route and there is no other thing that you should change => all redirects will still work perfectly.
BUT
If you choose to use the first one (i mean return redirect('/');) then after the change in the route you will need to parse all your controllers to check if there is some redirects that uses then changed route and the change them :p
redirect()->home() is simply a shortcut for redirect()->route('home'). The source code can be seen here.
Named routes are generally better than raw URLs for maintainability purposes. The home route isn't all that likely to change location, but it is possible that you might host a Laravel app in a subfolder, or move the home page from / to /app to make room for a marketing landing page at the root.
redirect('/')
It redirects you to the base URL.
redirect()->route('home')
Redirects to the route named home.
See More about named routes here.
redirect()->home();
Alternative way to redirect to named route.Redirects to 'home' route as well. It does the same thing as above but with slightly different syntax.
I preferred named routes over raw URLs, because if you decide to change the URL later on, you have to make changes into your routes file only.
When you are passing a string it will redirect a user to the domain plus the string you pass.
http://localhost:3000 + string
It will also add / if you forget it, now if you name your routes like you did then you can call it by the name.
An advantage of using named routes is in case you want to change the URI you can do it without worrying about changing a bunch of ahref in your view, redirects in your controllers, etc.
home() is a method from Laravel's Redirector or redirect() so, I don't think you can just call a named route as a method.
in routes.php,we write some route for the controller. such as:
Route::post('/account/create',array(
'as' =>'account-create',
'uses'=>'AccountController#postCreate'
));
I know that 'uses' is to search for the controller,then what 'as' is dealing with?
as is used to create a named-route in laravel.
As the doc says:
we can use them to refer to the route while generating URLs or redirects:
//generate URL
$url = URL::route('account-create');
//redirect to the route from another
$redirect = Redirect::route('account-create');
// with helpers
$url = route('account-create');
$redirect = redirect()->route('account-create');
as is for creating named routes and in fact it's very useful. In your application you can create urls or redirection using this named route URL::route('account-create'); and Redirect::route('account-create'); and it gives you huge bonus.
If you decide that you want to change your url, you just change it in your route and everything will be working without a problem because in other parts you used only route name.
So for example if you use named routes:
Route::post('/account/create',array(
'as' =>'account-create',
'uses'=>'AccountController#postCreate'
));
and in other parts URL::route('account-create'); and Redirect::route('account-create'); and now you decide you want to change url from /account/create to newaccount you need to change only in routes.php /account/create to newaccount and your whole application will work without a problem
On contrary, if you used urls in other part of your application, if you want to change this route url you would need to change urls in many parts of your application so you should use named routes because it can save you huge amount of time if you decide to change some urls in future.
For example if you don't use named-routes:
Route::post('/account/create',array(
'uses'=>'AccountController#postCreate'
));
and in other parts URL::to('/account/create'); and Redirect::to('/account/create'); and now you decide to change your url from /account/create to newaccount you will need to change it not only in routes.php file but in all files that use this url where you make any URL::to('/account/create'); or Redirect::to('/account/create');
Let assume, the base URL of my application is - http://www.example.com (I have not set anything in any config file to specify this). There are a lot of hard coded urls in the application.
eg. Contact
Now, if I go though the application using an URL like - http://www.example.com/country, is it possible to assign a global base URL, where when I click on contact it will take me to - http://www.example.com/country/contact.
There are a lot of such hard-coded URL, changing it individually will take a lot of time (like appending it with a global variable). Is there any simpler way to do this or is there any config specific for this in laravel? I am fairly new to laravel. Any help would be appreciated.
You can use the somewhat cumbersome solution of applying a filter, as suggested by #worldask, but I think it would be better to set a named route and change all occurrences using a regular expression (any decent editor allows for that). That way, for the lifetime of your application you only need to change the routes in routes.php, and it will be reflected everywhere.
e.g
Route::get('country/contact', ['as' => 'contact',
'uses' => 'SomeController#someFn'];
Contact
Of course, the same principle applies to adding a prefixed group of routes, so you can wrap the entire routes file with a group prefixed by 'country'.
you can try Route Prefixing
Route::group(array('prefix' => 'country'), function(){
Route::get('Contact', 'HomeController#index');
Route::get('another', 'HomeController#index');
});
edit
try route filter
Route::filter('filtername', function($route, $request, $value)
{
if ($route == 'country') {
return Redirect::to(url);
}
});
I'm making a link shortener as part of a school project,
Route::get('{short_url}', array('uses' => 'UrlController#shortUrlRedirect');
This function works fine alone, but as I have other functions such as
Route::post('register', array('uses' => 'HomeController#doRegister'));
whenever example.com/anylink
is now used, it is handled by one function alone.
A working solution I found would be to do something like:
Route::get('url/{short_url}', array('uses' => 'UrlController#shortUrlRedirect');
But of course with a link shortener, the goal is to have as little characters as possible.
Any ideas of a possible way to handle this issue within laravel?
The earlier or 'higher' in the routes.php file is the route, the more priority it gets, so if you define two identical routes or two routes that match one pattern, like in your example, the first one will be executed.
So you should define register route earlier, as it should not be overriden by the {short_url}.
Here is the explanation: Routes: First in, first out
TL;DR: Laravel receives a request, and uses the URI of the request to find a matching pattern iterating the routes file, when it finds one, it break;s the loop.
In Laravel the default controller is the Home_Controller. However I have a controller called frontend. I want to use this instead of the home controller.
When I register a route like this:
Route::controller(Controller::detect());
then a request to /offer will be handled from within the home controller like home#offer. I want to use frontend#offer and access it from the site's root - not like /frontend/offer.
What should I do?
Thanks in advance.
Home_Controller is one of the hard-coded convention which exist in Laravel 3, however there are still ways to define routing to point the Frontend_Controller methods, my preference would be.
Route::any('/(index|offer|something)', function ($action)
{
return Controller::call("frontend#{$action}");
});
Limitation with this is that you need to define all supported "actions" method in Frontend_Controller.
My guess is that the only reason you think the Home_Controller is some sort of default is because you are using Controller::detect(); I really haven't seen anything in the documentation to make me think that the Home_Controller is anything special at all. In fact, it doesn't even look like it is routed to in the example documentation. Given that, my first suggestion would be to get rid of Controller::detect() and see if that fixes your problem.
Barring that, have you tried registering frontend as route named home? It appears that all URL::home() does is search for the 'Home' route, and then redirect to it. When using controller routing this can be done with something to the effect of.
Route::get('/',
array(
'as' => 'home',
'uses' => 'frontend#index'
)
);
Or is that not your desired effect? Do you want all routes which aren't otherwise found to be redirected to your frontend controller?
If you are concerned about your urls looking pretty, you can probably use some rewrite rules in your .htaccess file to make the whole process of routing to /frontend/index transparent you your users.
Add this to your routes.php :
Route::get('/', array('as' => 'any.route.name', 'uses' => 'frontend#offer'));
If you have any other / route, just remove it.