Static controller multiple routes/single controller - laravel

I tried to find an answer that does the job, but the ones I found didn't really feel right to me, I have a static part of my site which I can arrange the route normally as in the code below.
it seems so messy to repeat the same route for more 7 pages, there got to be a smarter way to do it, I need to some opinions, maybe a controller with a slug or something, but I don't quite understand how to do it with a static part of the site like this.
Thanks.
Route::get('/first/home', function()
{
return View::make('/first.home');
});
Route::get('/first/aboutus', function()
{
return View::make('/first.aboutus');
});
Route::get('/first/contact', function()
{
return View::make('/first.contact');
});

I have a feeling your coming from WP, or maybe i'm wrong. In anycase, Laravel has a diff. ballgame in terms of serving static pages.
Now after your clarification, I would recommend you group your routes, as follows:
Route::group(['prefix' => 'first'], function () {
Route::get('(.*)', 'HomeController#getPageByName');
});
in HomeController You can write the following function:
function getPageByName(Request $request)
{
$pageName = $request->path();
//since your url does not begin with the page but with 'first',
//best is to turn this into an array.
$parsedPath = explode("/",$pageName)
$data = 'any data you want to pass';
if(View::exists($pageName[1] ){
return view($pageName[1] , compact($data));
} else {
abort(404)
}
}
Essentially your url would look like this, if you want page one:
http://example.com/first/home
Now Laravel will look for views/home.blade
Let me know if this helps your issue.

Related

How to setup url in JavaScript to pass multiple parameter to controller in Laravel without using request

I setup the url by JavaScript to call a function in controller with only one parameter($RoleID) like this
$(document).on('change','#role',function(){
$RoleID = $(this).val();
let $url = '{{route("Admin.role.permission.LoadMember",':id')}}'
$url = $url.replace(':id', $RoleID);
$.ajax({
url:$url,
success:function(data)
{
$('#member').append(data);
}// end fucntion success
});
});
It works ok, Now I would like to do the same with more than one parameter without using Request
I tried like this
document.getElementById('function').addEventListener('change', function(e) {
if (e.target.name==='function') {
$FncID = e.target.value;
let $url = '{{route("Admin.role.permission.LoadActionsInRolePermissions",'[$ModuleID,$RolID,$FncID]')}}';
$.ajax({
url:$url,
success:function(data)
{
$('tbody').html(data);
//$('#member').append(data);
}// end fucntion success
});
}
})
But unfortunately, It is not work. Pls help me.
Thank in advance
You haven't shown us how you defined the route, nor what laravel version you're using, but I highly suggest taking a read on the docs on how route parameters work.
As example, say this is your LoadMember route:
Route::get('permission/load-member/{id}', [PermissionController::class, 'loadMember'])->name('Admin.role.permission.LoadMember')
Then, as follows:
{{route("Admin.role.permission.LoadMember",['id' => ':id'])}}.
By passing an associative array with key => value assignment, Laravel knows where to place the given values in the url.
For a multi-parameter route, it works exactly the same:
Route::get('permission/load-actions-in-role-permissions/{moduleId}/{rolId}/{fncId}', [PermissionController::class, 'loadActionsInRolePermissions']) ->name('Admin.role.permission.LoadActionsInRolePermissions')
{{route("Admin.role.permission.LoadActionsInRolePermissions",'['moduleId' => $ModuleID, 'rolId' => $RolID, 'fncId' => $FncID]')}}
Also, may I suggest using camelCase for variable names, and kebab-case or snake_case for route naming? It highly improves readability and future developers who might work on your project will have a better guess at how your route structure works.

Sending different data from different method on same route - laravel 8

I am trying to get order data in order tab and profile details data in profile tab.
Is it possible to achieve ???
If Yes, then please tell me how ?
If No, then please tell me, laravel is the most advance framework of PHP, why we can't send multiple data from multiple methods in same View ?
Controller
public function GetOrders()
{
$gtord = DB::table('orders')->where('email',Session::get('email'))->get();
return view('/my-account')->with('gtord',$gtord);
}
public function ProfileEdit()
{
$data = DB::table('customers')->where('email',Session::get('email'))->first();
return view('/my-account')->with('data',$data);
}
Routes
Route::get('/my-account', 'App\Http\Controllers\CustomerController#ProfileEd');
Route::get('/my-account', 'App\Http\Controllers\CustomerController#GetOrders');
Thank you in advance
You can't have multiple routes with the same 'signature', ie method and url.
If you're just showing/hiding tabs using JS, what you can do is return the view with two variables, eg:
public function AccountView()
{
$data = DB::table('customers')->where('email',Session::get('email'))->first();
$gtord = DB::table('orders')->where('email',Session::get('email'))->get();
return view('/my-account')->with(['data' => $data, 'gtord' => $gtord]);
}
And then just use one route:
Route::get('/my-account', 'App\Http\Controllers\CustomerController#AccountView');
If the two tabs are different urls, or you're using Vue or similar you would have two distinct routes with different signatures.
First, you can't have 2 same routes with the same method. It's quite logical and necessary. Otherwise, the whole routing system would collapse.
On the other hand, you can have a function in the controller, and call the other functions to collect data.
// web.php
Route::get('/my-account', 'App\Http\Controllers\CustomerController#index');
// controller
public function index()
{
$orders = $this->getOrders();
$profile = $this->getProfiles();
return view('yourView', compact(['orders', 'profile']));
}
public function getOrders()
{
//
}
public function getProfiles()
{
//
}
BTW, it's a better practice to move custom function to models, services or traits, and keep only the functions of 7 verbs in the contoller.

How to render a cms page with default theme AND variables from controllers in OctoberCMS?

I'm wondering how I can render a view, or display a page with my default theme in OctoberCMS, via a route that executes a function in a controller.
If I have the following route:
Route::get('bransje', [
'uses' => 'Ekstremedia\Cityportal\CPController#bransje'
]);
And in my controller CPController ive tried several things, like I used to with Laravel:
public function bransje() {
$stuff = Stuff::with('info');
return View::make('cms::bransje')->with('stuff',$stuff);
}
But I cannot seem to get it to work, and I've tried to search the web, but it's hard to find answers. I have found a workaround, and that is to make a plugin component, then I can include that component and do:
public function onRun()
{
$this->eventen = $this->page['stuff'] = $this->stuff();
}
protected function stuff()
{
return ...
}
Is there any way so I can make pages without using the Cms, and that are wrapped in my default theme? I've tried
return View::make('my-theme-name::page');
and a lot of variants but no luck.
I know I can also do a:
==
public function onRun()
{
}
in the start of my page in the cms, but I'm not sure how to call a function from my plugin controller via there.
You can bypass frontend routing by using routes.php file in your plugin.
Full example in this video turotial.
If this answer can still be useful (Worked for October v434).
I have almost the same scenerio.
What I want to achieve is a type of routing like facebook page and profile.
facebook.com/myprofile is the same url structure as facebook.com/mypage
First I create a page in the CMS for each scenario (say catchpage.htm)
Then a created a catchall route at the buttom of routes.php in my plugin that will also not disturb the internal working of octobercms.
if (!Request::is('combine/*') && !Request::is('backend/*') && !Request::is('backend')) {
// Last fail over for looking up slug from the database
Route::get('{slug}/{slug2?}', function ($slug, $slug2 = null) {
//Pretend this are our routes and we can check them against the database
$routes = ["bola", "sade", "bisi", "ade", "tayo"];
if(in_array($slug, $routes)) {
$cmsController = new Cms\Classes\Controller;
return $cmsController->render("/catchpage", ['slug' => $slug]);
}
// Some fallback to 404
return Response::make(View::make('cms::404'), 404);
});
}
The if Request::is check is a list of all the resource that october uses under the hood, please dont remove the combine as it is the combiner route. Remove it and the style and script will not render. Also the backend is the url to the backend, make sure to supply the backend and the backend/*.
Finally don't forget to return Response::make(View::make('cms::404'), 404); if the resource is useless.
You may put all these in a controller though.
If anyone has a better workaround, please let us know.

Testing redirect links to external sites

I have a link on a page /my/example/page which links to a laravel route my.route.
Route
Route::group(['middleware' => ['auth']], function () {
Route::group(['middleware' => ['Some\Custom\Auth\Middleware:1']], function () {
Route::match(['GET', 'POST'], '/my/route/to/external/controller', 'exampleController#externalLink')->name('my.route');
}
}
Link on /my/example/page
Link
This route /my/route/to/external/controller points to this controller method externalLink in the exampleController controller, which returns the url for the href to use
public function externalLink()
{
return $this->redirect->away('www.externalsite.com');
}
My test is
$this->visit(/my/example/page)
->click('Link')
->assertRedirectedToRoute('my.route');
I constantly get the error
Symfony\Component\HttpKernel\Exception\NotFoundHttpException
when I use the click() testing method.
I can catch this using #expectedException but his doesn't help as I am expecting to see a different page.
I have also tried (not together);
->assertResponseStatus(200);
->seePageIs('www.externalsite.com');
->assertRedirect();
->followRedirects();
From browser inspection, when the url is clicked I get
http://www.example.com/my/route/to/external 302
http://www.externalsite.com 200
How can I functionally test the button being clicked and redirecting to an external site?
I am struggling with a similar problem right now, and I have just about given up on testing the endpoint directly. Opting for a solution like this...
Test that the link contains proper information in the view:
$this->visit('/my/example/page')
->seeElement('a', ['href' => route('my.route')]);
Moving the logic in the controller to something you can test directly. The Laravel\Socialite package has some interesting tests that might be helpful if you do this...
class ExternalLinkRedirect {
public function __construct($request){
$this->request = $request;
}
public function redirect()
{
return redirect()->away('exteranlsite.com');
}
}
Then test it directly
$route = route('my.route');
$request = \Illuminate\Http\Request::create($route);
$redirector = new ExternalLinkRedirect($request);
$response = $redirector->redirect();
$this->assertEquals('www.externalsite.com', $response->getTargetUrl());
A simple way is to use the get method instead of visit.
An example:
$this->get('/facebook')
->assertRedirectedTo('https://www.facebook.com/Les-Teachers-du-NET-516952535045054');

Share variable based on route group

I have 2 versions of a site. One is located in the root URL of the site and one is using a route prefix. They use the same resources but provide different links when accessed from the prefixed route:
Route::get('/', function(){
View::share('outgoing_url','something.com');
//regular links here
});
and a few more of the above pointing to different routes or
Route::group(array('prefix'=>'tour'), function(){
View::share('outgoing_url','somethingelse.com');
//different links here
});
View::share doesn't work since it uses whatever is assigned last so I am trying to find a solution for this problem.
Also, when I use HTML::link() in the views that go through the prefix, everything still points to the root URI of the site instead of the 'tour' prefix. Is there any way to differentiate between the two? Right now I am stuck with this problem and the only solution seems to be to make identical copies of the views and controllers responding to the routes. But that approach seems stupid to say the least.
I hope I explained the problem understandably.
HTML Macro:
<?php
HTML::macro('myLink', function($url, $title = null, $attributes = array(), $secure = null)
{
if (Request::segment(1) === 'tour')
{
$url = 'tour/'.$url;
}
return HTML::link($url, $title, $attributes, $secure);
});
?>
Usage:
HTML::myLink(...);
Just use a before filter - and set it that way
App::before(function($request)
{
if (Request::segment(1) === 'tour')
{
View::share('outgoing_url','tour.com');
}
else
{
View::share('outgoing_url','other.com');
}
});

Resources