Intercepting pretty URLs in Laravel4 - laravel-4

I am trying to implement a talking url scheme in laravel4 for SEO purposes.
What I have in my routes.php is this:
Route::get('{url}', array('as' => 'prettyurl', function($url) .........
which works for URLs such as
mywebsite.com/this-is-my-fancy-url-about-foo
mywebsite.com/bars
but doesn't for those such as
mywebsite.com/bars/this-is-my-fancy-url-about-foo
it seems that laravel splits the URL according to / before parring it to individual routes.
I could do something like
Route::get('{prefix}/{url?}', array('as' => 'prettyurl', function($prefix, $url) .........
but it seems a little contrived.
Any ideas?

You can use regular expressions to make it catch everything (including the slashes).
Route::get('{url}', ['as' => 'prettyurl', function($url)
{
})->where('url', '.*');

Related

Route with non-English characters doesn't work with Laravel Collective

I'm trying to use routes with non-English characters (Russian cyrillic) and these routes work just fine:
Route::resource('франшизы/подкатегории', 'Franch\SubCategoryController');
However when I'm trying to use same route with Form:: construction and sending the form, I get a NotFoundHttpException in RouteCollection.php line 161 exception:
// generates: http://localhost:8000/франшизы/подкатегории/20/edit?
{!! Form::open(array('method' => 'Get', 'route' => array('франшизы.подкатегории.edit', $subCategory->id))) !!}
I've copy-pasted code and added new route and Form:: with English only characters which works just fine:
// generates: http://localhost:8000/franch/sub/20/edit?
{!! Form::open(array('method' => 'Get', 'route' => array('franch.sub.edit', $subCategory->id))) !!}
Route::resource('franch/sub', 'Franch\SubCategoryController');
My question is how can I make non-English routes work? If it's impossible, what alternatives are there?
I've asked this questions at four forums, but noone was able to help me with it. I still do not know the best solution to the issue, but I have done this:
Route::get('франшизы/подкатегории', 'Franch\SubCategoryController#index')->name('franch_sub_categories_index');
Route::resource('franchises/subcategories', 'Franch\SubCategoryController', ['except' => ['index']]);
And it works just fine.
I'm using URL with utf-8 characters in the first route for the simple
#index requests which is important for SEO and URL readability.
The
second route handles all RESTful requries.
Hope it'll be helpful for some of you.

Laravel href redirection

So I've started using Laravel and I found it very easy and now I'm creating my own restful services. My problem is I don't know if I am doing the href link correct, but yes it is working. Here is the code:
Add user
And in my controller I just render the blade:
public function create()
{
return view('accounts.create');
}
So if I click the link Add user, it will redirect me to localhost:8080/accounts/create which is working well. My question is, is there a better way of doing this? Like if ever I changed any in my routes file, I will not change anymore the href link?
Ideally, you will name the route in your routes file.
Something like,
Route::get('accounts/create', [as => 'createAccount', 'uses' => 'AccountsController#create']);
You will use it as follows
Add user
in your view.
This way, even if you change the url (accounts/create), or the action name (create), you will not have to change it in the view. Allows your view to be independent.
What you can do is give your route a name using the as key in the array in the second argument of your route:
Route::get('accounts/create', [
'as' => 'accounts.create',
'uses' => 'AccountController#create'
]);
Then you can refer to this route in your application by it's name and it'll go to the same place even if you happen to change the URL. For an anchor tag you can do the following:
{{ URL::route('accounts.create') }}
If you're using a resource controller there will be predefined routes which you can see here under Actions Handled By Resource Controller: http://laravel.com/docs/5.1/controllers#restful-resource-controllers
You can always get a quick overview of your available routes and their names by running php artisan route:list
http://laravel.com/docs/4.2/routing#named-routes
Example:
Route::get('accounts/create', array('as' => 'signup', 'uses' => 'UserController#create'));
Add user
This route is named as "signup" and you can change the url anytime as:
Route::get('accounts/signup', array('as' => 'signup', 'uses' => 'UserController#create'));
Yes, you can use the action() helper to call a method inside a controller and generate the route to it automatically on demand.
So let's consider you have a controller called FrontendController.php and a method called showFrontend( $section), and assuming that you have a route that matches this controller and method (let's say "frontend/show/{$section}", you can call:
action('FrontendController#showFrontend', array( 'index' ) )
That will return:
frontend/show/index
So basically it looks for the route associated to that method/controller. You can combine this with other helpers to create a whole URL.
NOTE: Consider the namespaces, in case that you have different folder for controllers, nested resources, etc.
I hope it helps!

How to handle Laravel 4 sub-domain route with controller, passing subdomain as an argument

Following the Laravel 4 documentation on Routing, I've been trying to create a domain route that will handle a wildcard subdomain and pass it over to a controller action, but I'm having trouble passing the argument.
Route::group(array('domain' => '{subdomain}.myapp.com'), function()
{
Route::get('/', function($subdomain)
{
die($subdomain);
});
});
If I write the route like this, it will print out the subdomain, whatever it might be. The problem is that I don't want to write the code that handles these situations in the routes.php file, but use a Controller to handle it all, without redirecting from subdomain.myapp.com to myapp.com/controller/action/subdomain.
So, something like this:
Route::group(array('domain' => '{subdomain}.myapp.com'), function()
{
Route::get('/', 'MyController#myAction', $subdomain);
});
How do I pass the {subdomain} argument to the controller in this case?
It seems as though the morning is smarter than the night. I went with a dispatch solution, so if anyone else has a more elegant solution, please feel free to post and I'll accept your answer instead.
Route::group(array('domain' => '{subdomain}.myapp.com'), function()
{
Route::get('/', function($subdomain) {
$request = Request::create('/myRoute/' . $subdomain, 'GET', array());
return Route::dispatch($request)->getContent();
});
});
Route::get('myRoute/{subdomain}', 'MyController#myAction');

Laravel 4 - How to redirect without subdomain parameter name in url

I need some assistance clarifying how to properly generate redirects in laravel when the subdomain of the url is being used as a parameter in the routing.
The route in question is as follows:
Route::group(array("domain"=>"{subdomain}.mydomain.com"),function(){
Route::group(array("before"=>"auth"),function(){
Route::get("logout",array("as"=>"logout",function(){
Session::flush();
Redirect::route("login");
}));
});
Route::group(array("before"=>"guest"),function($subdomain){
Route::get("login",array("as"=>"login",function($subdomain){
return View::make('login');
}));
});
});
The "logout" route redirects to http://dev.mydomain.com/http://%7Bsubdomain%7D.mydomain.com/login
While I had anticipated:
http://dev.mydomain.com/login
When I remove the outer route group (the one grabbing the subdomain as a parameter), everything works as expected.
Any help is greatly appreciated
I solved this by using Redirect::to('login') instead of using named routes.
It only happens when using Redirect::route('login').
It may be related to your domain name. If you use local domain, you may use invalid character inside it such as "_", "+", "," etc.
I've read countless articles about this issue in Laravel 4. Not one of the solutions worked for me. You cannot URL::to('login') and remove the subdomain when inside the subdomain. Laravel remembers it.
This is how you should "get outside" of the subdomain.
First you should name the root route and also define your main domain.
Route::group(['domain' => 'yourwebsite.com'], function()
{
Route::get('/', ['uses' => 'YourController#getIndex', 'as' => 'home']);
});
Second you can construct the route by yourself:
URL::route('home').'/login'
That would be enough to resolve the L4 subdomain routing problem.
If you want to automatically redirect to the the non-subdomain URL. You can do this at the end of your subdomain handling:
Route::group(['domain' => '{subdomain}'.'.yourwebsite.com'], function() {
// Here goes all your subdomain handling
// Then handle subdomain requests that where not found
Route::get('{slug}', function($subdomain, $slug) {
return Redirect:to(URL::route('home').'/'.$slug);
})->where('slug', '.*');
});

Laravel 4: Unable to generate a URL for the named route "login" as such route does not exist

I'm creating an authorization system in my Laravel 4 project. I am trying to use the auth "before" filter.
In my routes.php file, I have:
Route::get('viewer', array('before' => 'auth', function() {
return View::make('lead_viewer');
}));
Route::get('login', 'LoginController');
The before filter calls this line in the filters.php file:
Route::filter('auth', function()
{
if (Auth::guest()) return Redirect::route('login');
});
I can manually navigate to my login route. But the auth system isn't letting this happen. I've run composer dump-autoload a couple of times, so that isn't the problem. What am I doing, since I can actually load the login page if I do it manually?
I figure it out. Laravel is looking for a named route: I had to do this:
Route::get('login', array('as' => 'login', function() {
return View::make('login');
}));
An interesting, not very intuitive approach in Laravel. But there must be a reason Taylor did this that I'm not seeing.
To do what you were trying to do in your initial approach you could have just done:
Route::filter('auth', function()
{
if (Auth::guest()) return Redirect::to('/login');
});
and it would have worked just fine.
If you want to use named routes then you do what you posted in your answer to your own question. Essentially...more than one way to skin a cat.
Hope that helps
I know you've probably solved this by now but after stumbling across your post while trying to solve a similar problem, I wanted to share my thoughts...
Laravel is NOT looking for a named route for the guest method, it is expecting a path.
Your example works because because the named route and the path are the same i.e. "login". Try changing your URL to something other than 'login' and watch it fail.
If you want to use a named route you should use the route helper method as so...
if (Auth::guest()) return Redirect::guest( route('login') )
Hope that helps someone.

Resources