What does "as" keyword mean in Laravel routing? - laravel

As I understand from the Laravel documentation, it's used for redirection, but maybe I'm wrong.
I wrote
Route::get('user/profile', ['as' => 'profile', function () {
echo 'some_text';
}]);
then I was expecting my URL to redirect from
https://base_url/public/index.php/user/profile to https://base_url/public/index.php/profile but it doesn't happen.
Overall, I want to know, what the difference is if I used
Route::get('user/profile', function () {
echo 'some_text';
});
instead of the above routing rule.

The purpose isn't for re-direction in your routing file.
Instead, with the example route you provided, Laravel will allow you to reference said route by using:
$url = route('profile');
So you don't have to build the URL manually over and over again in your code.
So, in short: the difference is the first thing is a named route, and the last thing is a non-named route. Since you called the first route, you can reference it by that name.

Related

Route::redirect with wildcard in Laravel 5.5+

The new Route::redirect introduced in Laravel 5.5 is practical, but does it allow {any} wildcard?
Here is what I used to do in Laravel 5.4
Route::get('slug', function () {
return redirect('new-slug', 301);
});
In Laravel 5.5, I can do the following:
Route::redirect('slug', url('new-slug'), 301);
Which allows route caching by getting rid of the closure.
So far so good, but what if I want to use a wildcard? In Laravel 5.4, I could do:
Route::get('slug/{any}', function ($any) {
return redirect('new-slug/'.$any, 301);
});
Of course, I can still use this in Laravel 5.5, but my point is to be able to cache my route files.
Does the new Route::redirect allow the use of a wildcard, or is my only option to use a controller?
EDIT: What I am attempting to do is something like this:
Route::redirect('slug/{any}', url('new-slug/'.$any), 301);
Which of course doesn't work because I don't know where to reference the $any variable.
You may use:
Route::redirect('slug/{any}', url('new-slug', Request::segment(2)), 301);
If you need to redirect with input data:
Route::redirect('slug/{any}', str_replace_first('slug', 'new-slug', Request::fullUrl()), 301);
Note that the above functions url() Request::segment(2) str_replace_first will be called in each request although there is no match for slug/{any}, nothing to worry about but I prefer to create my own controller in this case or add the redirect in the web server directly.

Laravel 5.2 blade route to resource

The documentation says:
If the named route defines parameters, you may pass the parameters as
the second argument to the route function. The given parameters will
automatically be inserted into the URL in their correct positions:
Route::get('user/{id}/profile', ['as' => 'profile', function ($id) {
//
}]);
$url = route('profile', ['id' => 1]);
If i do have a nested resource route by using Route::resource(...) twice, i will get a named route wich contains a placeholder like
employees.{employee}.images.index
How can i create a route for this nested resource using the blade templating engine?
I thought about
route('employees.{employee}.images.index', ['employee' => $employee->id]);
but that does not work. I know i can "manually" create the routes, but this will make them less maintainable.
Update 1
I know i can name the routes manually and then use the given name. But if there is a way without naming them i would prefer it.
You don't have to add anything like employee into a route name. Run php artisan route:list command and you will see real names of all routes (look at column called Name), created by resource clause. Then just use them like usual:
route('employees.images.index', ['employee' => $employee->id]);
Also, you can name resource routes.

how to pass variable from view to route in laravel

How to pass a variable from view to route in Laravel?
Here's the code at my route.php:
Route::get('/{id}/{id1}', 'WelcomeController#index');
And at welcome.blade.php:
< a href="{{URL::route('/{4}/{5}')}}">test</a>
I want to build a link referencing the route above.
A good approach to do it would be to name your route and then reference it by name, passing the parameters needed. Here is how:
At routes.php:
Route::get('/{id}/{id1}', ['as' => 'welcome_index', 'uses' => 'WelcomeController#index']);
And at your view, you can do this:
test
Notice that the first parameter represent the route name and the second, the parameters for your URL. You can read more here.
The advantages of naming a route is that you can change your route path later and your URL will still work with the code above.

Laravel Redirect::action outputs extra "index"

I am using this code in a controller
Redirect::action('myController#getIndex')
and in routes.php
Route::controller('/my','myController');
I was expecting redirect to /my but this redirected to /my/index instead.
How can I fix the URL in this case.
P.S: Both URLs are ok and show same page, but I prefer the cleaner one.
With the ::controller routes the function name maps/plays a part in the url, so you would not be able to get around this easily using ::controller based routes. Instead I would advise to make use of named routes like so:
Route::get('my', array('as' => 'my.index', 'uses' => 'MyController#getIndex'));
Then to redirect to this route:
Redirect::route('my.index');
See this blog article post by Phil Sturgeon why using implicit routing is generally bad practise.

Laravel 4 Route Filter Never Called

I am sure that I am doing something wrong that is very obvious, but for some reason I cannot get any filters except App::before to work in my test application.
//routes.php
Route::get('site/login',
array(
'before'=>'science',
'as'=>'site/login',
'uses'=>'HomeController#getLogin',
)
);
Route::controller(site, 'HomeController');
//filters.php
App::before(function($request){
//var_dump("Before"); exit;
});
Route::filter('science',function(){
dd("Science B!TCH!");
exit;
});
//HomeController.php
public function getLogin(){
$this->layout->body = View::make('home.login');
}
The object was first to ensure that a user was not logged in so I was trying to use the built-in "guest" filter, but it was never being called. So I later created the "science" filter to test if ANY routes would work. If I uncomment the var_dump line in App::before, it displays "Before" and exits as expected.
Can anyone see what I am doing wrong here? When I go to the /site/login page I should see my Breaking Bad movie quote instead of the actual page. However, I am seeing my login form as if nothing was happening.
Thanks!
UPDATE:
I changed the route to look like this now:
//routes.php
Route::get('site/login', 'HomeController#getLogin')->before('science');
... and it works. I get the debugging string "SCIENCE ..." on the screen.
It also works if I do the following
//HomeController.php
public function __construct(){
$this->beforeFilter('science');
}
Are there any use cases or conditions in which the array version of routes gets ignored?
UPDATE 2:
In my efforts to simplify my original description I neglected to show other routes that were in routes.php. Take a look below.
//routes.php
Route::get('site/login',
array(
'before'=>'science',
'as'=>'site/login',
'uses'=>'HomeController#getLogin'
)
);
Route::post('site/login',
array(
'as'=>'site/login',
'uses'=>'HomeController#postLogin'
)
);
Having the POST route AFTER the GET route is what is causing the problem. When I put the POST route BEFORE the GET route, the GET route works with the filter as expected.
Now, I was under the impression that Laravel treated GET and POST requests differently, hence the usage of the different static methods in Route. However, apparently, this is not true as the filter on the latter affects the filter of the former.
Is this a correct assumption? Should I start a different thread about this? I would love to understand why this is working this way.
Thanks!
UPDATE 3
---- SOLVED ---
This tidbit of information is not specifically stated in the documentation but you cannot have identical route names even though those route names are going to different REST verbs.
//routes.php BEFORE
Route::get('site/login', array('as'=>'site/login','uses'=>'HomeController#getLogin', 'before'=>'science'));
Route::post('site/login', array('as'=>'site/login', 'uses'=>'HomeController#postLogin',));
In the above solution, the 2nd Route OVERRIDES the previous route because the "as" uses the same name. I thought that these would be treated differently since one is GET and the other POST, but this is not the case. The filter assignments must happen by name in the backend and, as such, using identical names will override each other.
//routes.php AFTER
Route::get('site/login', array('as'=>'site/login','uses'=>'HomeController#getLogin', 'before'=>'science'));
Route::post('site/login', array('as'=>'site/postLogin', 'uses'=>'HomeController#postLogin',));
As you can see here, I renamed the 'as' part of the array to 'site/postLogin' and I can now use different filters for each the POST, GET, and probably PUT, DELETE and etc.
For better practice if two or more routes use the same filter, those routes should belong in a group. I have a feeling that will correct the issue.
From http://laravel.com/docs/routing#route-groups
Route::group(array('before' => 'auth'), function()
{
Route::get('/', function()
{
// Has Auth Filter
});
Route::get('user/profile', function()
{
// Has Auth Filter
});
});
---- SOLVED ---
This tidbit of information is not specifically stated in the documentation but you cannot have identical route names even though those route names are going to different REST verbs.
//routes.php BEFORE
Route::get('site/login', array('as'=>'site/login','uses'=>'HomeController#getLogin', 'before'=>'science'));
Route::post('site/login', array('as'=>'site/login', 'uses'=>'HomeController#postLogin',));
In the above solution, the 2nd Route OVERRIDES the previous route because the "as" uses the same name. I thought that these would be treated differently since one is GET and the other POST, but this is not the case. The filter assignments must happen by name in the backend and, as such, using identical names will override each other.
//routes.php AFTER
Route::get('site/login', array('as'=>'site/login','uses'=>'HomeController#getLogin', 'before'=>'science'));
Route::post('site/login', array('as'=>'site/postLogin', 'uses'=>'HomeController#postLogin',));
As you can see here, I renamed the 'as' part of the array to 'site/postLogin' and I can now use different filters for each the POST, GET, and probably PUT, DELETE and etc.

Resources