Laravel - Change base URL globally? - php

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);
}
});

Related

Laravel 5 redirect to path with parameters (not route name)

I've been reading everywhere but couldn't find a way to redirect and include parameters in the redirection.
This method is for flash messages only so I can't use this.
return redirect('user/login')->with('message', 'Login Failed');
This method is only for routes with aliases my routes.php doesn't currently use an alias.
return redirect()->route('profile', [1]);
Question 1
Is there a way to use the path without defining the route aliases?
return redirect('schools/edit', compact($id));
When I use this approach I get this error
InvalidArgumentException with message 'The HTTP status code "0" is not valid.'
I have this under my routes:
Route::get('schools/edit/{id}', 'SchoolController#edit');
Edit
Based on the documentation the 2nd parameter is used for http status code which is why I'm getting the error above. I thought it worked like the URL facade wherein URL::to('schools/edit', [$school->id]) works fine.
Question 2
What is the best way to approach this (without using route aliases)? Should I redirect to Controller action instead? Personally I don't like this approach seems too long for me.
I also don't like using aliases because I've already used paths in my entire application and I'm concerned it might affect the existing paths if I add an alias? No?
redirect("schools/edit/$id");
or (if you prefer)
redirect("schools/edit/{$id}");
Just build the path needed.
'Naming' routes isn't going to change any URI's. It will allow you to internally reference a route via its name as opposed to having to use paths everywhere.
Did you watch the class Illuminate\Routing\Redirector?
You can use:
public function route($route, $parameters = [], $status = 302, $headers = [])
It depends on the route you created. If you create in your app\Http\Routes.php like this:
get('schools/edit/{id}', 'SchoolController#edit');
then you can create the route by:
redirect()->action('SchoolController#edit', compact('id'));
If you want to use the route() method you need to name your route:
get('schools/edit/{id}', ['as' => 'schools.edit', 'uses' => 'SchoolController#edit']);
// based on CRUD it would be:
get('schools/{id}/edit', ['as' => 'schools.edit', 'uses' => 'SchoolController#edit']);
This is pretty basic.
PS. If your schools controller is a resource (CRUD) based you can create a resource() and it will create the basic routes:
Route::resource('schools', 'SchoolController');
// or
$router->resource('schools', 'SchoolController');
PS. Don't forget to watch in artisan the routes you created

Laravel - why not relative URL's?

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.

Add JSON routes for all routes to handle backend requests

I'm using Laravel 5.1 and am building a service that can be seen as JSON or HTML. This approach is already done by sites like reddit.
Example
Normal view: http://www.reddit.com/r/soccer
JSON view: http://www.reddit.com/r/soccer.json
As you can see, they simply add .json to an URL and the user is able to see the exact same content either as HTML or as JSON.
I now wanted to reproduce the same in Laravel, however I'm having multiple issues.
Approach 1 - Optional parameter
The first thing I tried was adding optional parameter to all my routes
Route::get('/{type?}', 'HomeController#index');
Route::get('pages/{type?}', 'PageController#index');
However, the problem I was facing here, is that all routes were caught by the HomeController, meaning /pages/?type=json as well as /pages?type=json were redirected to the HomeController.
Approach 2 - Route Grouping with Namespaces
Next I tried to add route groupings with namespaces, to seperate backend and frontend
Route::get('pages', 'PageController#index');
Route::group(['prefix' => 'json', 'namespace' => 'Backend'], function(){
Route::get('pages', 'PageController#index');
});
However, this doesn't work either. It does work, when using api as prefix, but what I want, is that I can add .json to every URL and get the results as json. How can I achieve that in Laravel?
You can apply regular expressions on your parameters to avoud such catch-all situation as you have for HomeController#index:
Route::get('/pages{type?}', 'PageController#index'->where('type', '\.json'));
This way it type will only match, if it is equal to .json.
Then, to access it in your controller:
class PageController {
public function index($type = null) {
dd($type);
}
}
and go to /pages.json

Laravel Route Group Prefixing and Breadcrumbs

I am using route prefixing and I am coming up with an issue and not sure how to fix it.
First actual question is can I keep my links the same as they were before I added the prefixing?
Previously I had links for example and my routes were like this.
Edit
Route::resource('users', 'UsersController');
However now I have added in a prefix to a group of routes so that links will show up as mysite.com/backstage/users.
Route::group(array('prefix' => 'backstage'), function()
{
Route::resource('users', 'UsersController');
});
So now with ALL my views do I have to go through each one and edit all the links so that they look like this or can I do something different so I can handle this situation differently.
Edit
I'm also concerned about my breadcrumbs for my application.
<?php
Breadcrumbs::register('users.index', function($breadcrumbs) {
$breadcrumbs->parent('home');
$breadcrumbs->push('Users', route('backstage.users.index'));
});
Do I have to include the backstage or can I keep it without?
The only way I know to do it is pass names as a third argument like:
Route::resource('users', 'UsersController',
['names'=>['index'=>'users', 'store'=>'users.store']]);
A lot of people avoid using the resource routing. Phil explains some reasoning here Beware the route to evil. Basically he's saying it can be a nightmare if you, or someone else, comes back to it later to figure out. You often have special cases that you put ahead of the resource so they get hit first in the routing and the whole thing turns into a mess.

Change Laravel's default (root) controller

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.

Categories