October CMS - How to correctly route - php

I've been reviewing the documentation for October CMS routing (https://octobercms.com/docs/plugin/registration#routing-initialization), but I think that I am missing something. I have a page called 'deals' that renders some basic information along with a plugin (called 'deals') component. The page normally appears at the url:
http://www.example.com/deals
However, I want to create a route so that if someone visits the url:
http://www.example.com/deals2
it will automatically route them back to
http://www.example.com/deals
I know that I should create a routes.php file in my plugin directory. However, when I try using
Route::get('/deals2', function()
{
return View::make('deals');
});
It complains that it can't find the 'deals' view. What am I doing wrong?
Additionally, how can I route it so that my homepage
http://www.example.com
would route to
http://www.example.com/deals

In OctoberCMS, and Laravel which it's based on, to redirect one route to another you can do this:
// Redirect /deals2, /deals3, ... to /deals
Route::get('{dealSlug}', function($dealSlug) {
return redirect('deals');
})->where('dealSlug', '^deals[0-9]+');
// Redirect homepage to /deals
Route::get('/', function() {
return redirect('deals');
}
The first route uses a route parameter with a regex constraint and will redirect any request that starts with /deals and ends with a number to your /deals route. That means it will route /deals1, /deals2, /deals3, etc to /deals.
The second route will redirect your homepage to /deals.
Of course, redirecting will cost an extra request. If you don't want to do that, then you could do the redirect in Apache or Nginx.
As per your comment, if you wanted to redirect /deals[any-number]/[anything] to /deals/[that-same-anything] then you would add an optional route parameter to the first route. That would look like this:
// The new first route
Route::get('{dealSlug}/{extra?}', function($dealSlug, $extra = '') {
return redirect('deals/' . $extra);
})->where('dealSlug', '^deals[0-9]+');
Of course, if that /deals/[anything] route doesn't exist, then you'll get a 404.

Try
Route::get('/deals2', function(){return Redirect::to('/deals')}); which will redirect the browser at the cost of an extra request.

Related

How do you redirect to the "base URL" if a web page is not found in CodeIgniter 4?

How do you redirect to base_url() if a page is not found that matches the current URI?
I have tried this in app/Config/Routes.php, but it's not working:
$routes->set404Override(function () {
return redirect()->to(base_url());
});
404 Override
When a page is not found that matches the current URI, the system will
show a generic 404 view. You can change what happens by specifying an
action to happen with the set404Override() option. The value can be
either a valid class/method pair, just like you would show in any
route, or a Closure:
// Would execute the show404 method of the App\Errors class
$routes->set404Override('App\Errors::show404');
// Will display a custom view
$routes->set404Override(function ()
{
echo view('my_errors/not_found.html');
});
Solution:
So in your case, you could do:
$routes->set404Override('App\Controllers\Home::index'); ✅

When to use: redirect('/') vs. redirect()->route('home') vs. redirect()->home()?

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.

How can I check whether the route "URL" exists?

In Laravel 5.2, is there a particular way (handler) to check whether a route is existing or not? Let's say, for a basic URL like:
http://www.example.com/laravel
I then want to handle the non-existing URLs (like: /laravel) from my Main Page Router, which is:
Route::get('/{page}', funtion(){
//check if $page is a valid route URL? Or 404?
});
How do I purposely check whether this route is a valid one or not?
I use the following as my last route:
Route::any('{catchall}', function($page) {
abort(404);
} )->where('catchall', '(.*)');
If you are not aware yet, abort(404) will return the view 404.blade.php from resources/views/errors.
Simply put your Route::get('/{page}','MainController#getPage'); last. That way if it finds another route before it will use it but if it doesn't then it will get caught by this. For example:
Route::get('/welcome','WelcomeController#getWelcome');
Route::get('/test','TestController#getTest');
Route::get('/{page}','MainController#getPage');
If you were to hit /welcome or /test it should route them to the correct controller. If you where to hit /hello it should go to the MainController and hit function getPage($page) with $page being the page you hit.
If it hits MainController#getPage you know it was basically a 404.
If you need to know before you hit the route for some reason you could create something like this:
Route::get('/checkurl/{page}',function($page) {
$exists = Route::has('/' . $page);
return (new Response(json_encode(['exists'=>$exists]),200);
});
Adding last route with any catch doesn't works anymore with laravel 5.5.1+

Incorrect routing via /config/routes.php

I have the following (basic) route set up in a CI-based web app:
$route['sms/resend/(:num)/(:any)'] = 'sms/resend/$1/$2';
The controller + 'resend' method:
class Sms extends CI_Controller {
public function resend($to, $message) {
// my code
}
}
Logically speaking, anything that doesn't fit the route should be directed to a 404 page instead of the resend() method within the sms controller. This isn't the case, however. The following URL, for example, isn't redirected correctly, it goes to the same controller+method:
http://myapp/sms/resend/uuuu/WhateverMessage
What could be the problem?
After a bit of digging, I've come to understand that CI's default routing does not get deactivated when a default route related to a specific controller/method pair is added. That being said, if a URL does not fit the route $route['sms/resend/(:num)/(:any)'] = 'sms/resend/$1/$2', then the same URL is run through CI's default routing mechanism as a fallback, so it still takes me to the resend method of the sms controller. To prevent this from happening, I needed to add another custom route that follows all others related to the sms resending, that redirects any other url to a different controller+method. If this controller doesn't exist, you get the default 404 page.
So the final /config/routes.php file:
$route['sms/resend/(:num)/(:any)'] = 'sms/resend/$1/$2';
$route['sms/checkoperator/(:num)'] = 'sms/checkoperator/$1';
$route['sms/(:any)'] = 'somewhereovertherainbow';
I think the rout file is just for rerouting. Your URL don't fits the routing Conditions so it don't gets rerouted! So it goes the normal way wich is the same (in this case!)
Something like this could work!
(! :num) /(:any) '] = error page (or not existing page)
So every request wich doesn't start with a number gets redirected to the error page!
The syntax might be wrong!
This would work great :
$route['sms/resend/[^0-9]/(:any)'] = 'errorpage';
You have to replace the error page by something ;)

Only allow URL's specified in routes to be seen in Codeigniter

If I have a controller called articles, which has a method called view_articles, a user can type in http://example.com/articles/view_articles/some-post and have it return a page.
I have specified a route to be http://example.com/article/post-name. How can I make it so that only the URL specified in the route is visible? Is there a way for articles/view_articles/some-post to show a 404 instead of showing the same page as the route URL?
I am trying to prevent duplication for SEO purposes.
You can always make default routing to a 404 page by correctly defining routes in your routes.php file:
$routes['article/(:any)'] = 'articles/view_articles/$1';
$routes['(:any)'] = 'main/e404';
As stated by CodeIgniter user guide:
Routes will run in the order they are defined. Higher routes will always take precedence over lower ones.
So you can basically define all you want to be seen at the beginning of the file and block everything else on the last line.
As for your main(can be any other) controller's 404 method -
function e404() {
show_404();
}
Use $this->uri->segment(n) as part of the URI class inside of view_articles to redirect traffic to your route if the URI contains view_articles as it's second segment.
I'v done that in other tricky way, first of all you should add some code to __construct function in sys/core/Controller.php
you can check whether the requested url is in routes or not by this code
if(!isset($this->router->routes[uri_string()])){
show_404(); // Or whatever you want ...
}

Categories