Subpage In Laravel? - php

I tried applying some solutions I've found online but I can't seem to have any of them work for me. (I'm fairly new to Laravel) I'm trying to get Laravel to direct to blade views I set up. However, I want to be able to access them via sub-page urls. Could I get some help? The URLs I'm using to at the moment are
/course/{course_slug}
/lesson/{lesson_slug}
/module/{module_slug}
I have course.blade.php , lesson.blade.php, and module.blade.php set up. (not sure why it doesn't let me post my code)
But I want to be able to route to these views using this syntax:
/course/{course-slug}
/course/{course-slug}/{lesson-slug}
/course/{course-slug}{lesson-slug}/{module-slug}
Any suggestions would be great. Thank you so much.
Erwin
EDIT: Code used for blade files (changing out the module variable to lesson, course, etc)
#foreach($modules as $modules)
<li>
<a href="/modules/{{ $lesson->lesson_slug}}/{{ $modules->module_slug }}">
<span>{{ $modules->module_title }}</span>
</a>
</li>
Here's my routes file code:
Route::get('course/{slug}', function($slug){
$course= App\Course::where('slug', '=', $slug)->firstOrFail();
$lessons = App\Lesson::where("course_id", "=", $course->id)->get();
return view('course', compact('course'))->with('lessons', $lessons);
});
Route::get('lesson/{slug}', function($slug){
$lesson = App\Lesson::where('lesson_slug', '=', $slug)->firstOrFail();
$modules = App\Module::where("lesson_id", "=", $lesson->id)->get();
return view('lesson', compact('lesson'))->with('modules', $modules);
});
Route::get('module/{slug}', function($slug){
$module = App\Module::where('module_slug', '=', $slug)->firstOrFail();
return view('module', compact('module'));
});

Related

Laravel redirecting to the wrong route

web.php
Route::get('/gigs/{id}', [GigsController::class, 'info'])->name('clientside.gigs_info');
Route::get('/gigs/create', [GigsController::class, 'create'])->name('clientside.gigs.create');
Controller
public function create()
{
$categories = Category::select('id', 'name')->get();
return view('clientview.gigs.create', compact('categories'));
}
public function info($id)
{
$gig = Gigs::join('users', 'users.id', '=', 'gigs.created_by')
->join('categories', 'categories.id', '=', 'gigs.category_id')
->select('gigs.*', 'categories.name as category_name', 'users.name as user_name', 'users.surname')
->where('gigs.id', '=', $id)
->orderBy('name', 'ASC')
->firstOrFail();
return view('clientview.gigs.info', compact('gig'));
}
When I try to click this:
<a class="dropdown-item" href="{{ route('clientside.gigs.create') }}">Create Gigs</a>
When I click this I can observe from DebugBar that it directs to route ('clientside.gigs_info')
I think "/create" thinks it is an /{ID} but however, I direct to a different route
Answer by Michael Mano,
Make sure you write on web.php static routes before dynamic.
Just write create route before info route because it is dynamic route (That accept parameter) so always write dynamic route after the static route.
You actually created a dynamic route gigs/{id} so anything that comes after gigs will be called as a parameter of gigs. So to fix this change the order in your web.php like below. So it will search for static route first and then go for dynamic route.
Route::get('/gigs/create', [GigsController::class, 'create'])->name('clientside.gigs.create');
Route::get('/gigs/{id}', [GigsController::class, 'info'])->name('clientside.gigs_info');

How do I inject data in my sidebar that is included in every single blade of my project

I'm using a layout system and my sidebar is included in my master, and my master page is the layout for all my blades
//master.blade.php
<div clas="main-wrapper" id="app">
#include('layout.sidebar')
<div class="page-wrapper">
#include('layout.header')
<div class="page-content" >
#yield('content')
</div>
</div>
</div>
I want to display on the sidebar items the project names that belongs to the authenticated user.
So I tried the first solution which is to use the route function like this:
//web.php
Route::any('/home',function(){
$p = DB::table('projets')
->join('users', 'users.id', '=', 'projets.ID_chercheur')
->select('projets.nom', 'users.name', 'users.prenom')
->where('projets.ID_chercheur','=',Auth::user()->id)
->get();
return view('dashboard')->with(['projets' => $p]);
});
the problem with this solution that it works only in my dashboard view, any other view it won't work it will give me the following error:
ErrorException
Undefined variable: projets (View: C:\laragon\www\Labo1\resources\views\layout\sidebar.blade.php)
I understand what the error means but I don't know how to fix it, I tried:
//web.php
Route::match(['get', 'post', 'PUT', 'PATCH','DELETE'], '/', function () {
$p = DB::table('projets')
->join('users', 'users.id', '=', 'projets.ID_chercheur')
->select('projets.nom', 'users.name', 'users.prenom')
->where('projets.ID_chercheur','=',Auth::user()->id)
->get();
return ['projets' => $p];
});
but it doesn't work either, could someone tell me what solution could I use?
Use View Composer to tackle the issue. View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location.
Implementation
Step 1 Create Service Provider
php artisan make:provider ViewServiceProvider
Step 2 Register Service Provider
You will need to add the service provider to the providers array in the config/app.php configuration file.
Like add this App\Providers\ViewServiceProvider::class, to providers array, then run config:cache to clear cache and regenerate config.
Step 3 Write Logic in Provider's Boot Method
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class ViewServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
// Using Closure based composers...
View::composer('layout.sidebar', function ($view) {
$p = DB::table('projets')
->join('users', 'users.id', '=', 'projets.ID_chercheur')
->select('projets.nom', 'users.name', 'users.prenom')
->where('projets.ID_chercheur','=',Auth::user()->id)
->get();
$view->with('projets', $p);
});
}
}
then you can access projets in your blade like {{projets}} and the foreach over it or whatever.
Further Refer to Documentation
I think what you want is something like this in one of your ServiceProviders (e.g. AppServiceProvider)
View::composer('layout.sidebar', function ($view) {
$p = DB::table('projets')
->join('users', 'users.id', '=', 'projets.ID_chercheur')
->select('projets.nom', 'users.name', 'users.prenom')
->where('projets.ID_chercheur','=',Auth::user()->id)
->get();
$view->with('projets', $p);
});
I haven't tried it out myself. But I think it should also work for partials.
Another Approach
if you have limited data to access in all views like for only projects data then definitely go for view composers but if you think that in future you have to access multiple external data then you can make a separate helper file and write code there like make functions and then in your blade just simply call those functions.
Implmentation
Create a helpers.php file in your app folder and load it up with composer like:
"autoload": {
"classmap": [
...
],
"psr-4": {
"App\\": "app/"
},
"files": [
"app/helpers.php" // <---- ADD THIS
]
},
After adding that to your composer.json file, run the following command:
composer dump-autoload
If you don't like keeping your helpers.php file in your app directory (because it's not a PSR-4 namespaced class file), you can do what the laravel.com website does: store the helpers.php in the bootstrap directory. Remember to set it in your composer.json file:
"files": [
"bootstrap/helpers.php"
]
Then in your helpers.php file make a function
<?php
function getProjects()
{
$p = \DB::table('projets')
->join('users', 'users.id', '=', 'projets.ID_chercheur')
->select('projets.nom', 'users.name', 'users.prenom')
->where('projets.ID_chercheur','=',Auth::user()->id)
->get();
return $p;
}
and access it in blade like {{ getProjects() }}
Hey guys thank you so much for your answers but i found a simple way to resolve my problem
i wasn't familiar with the php syntax in laravel so my friend helped me and this solution seemed to help me:
#php
$projets=DB::table('projets')
->join('users', 'users.id', '=', 'projets.chefProjet')
->select('projets.nom', 'users.name', 'users.prenom')
->where('projets.chefProjet','=',Auth::user()->id)
->get();
#endphp
...
I puted this piece of code in the top of my sidebar.blade.php and now i can work with the data in the same page and also the data is loaded with every other blade
if(count($projets)>0)
#foreach ($projets as $p)
<li class="nav-item {{ active_class(['forms/*']) }}">
<a class="nav-link" data-toggle="collapse" href="#forms" role="button" aria-expanded="{{ is_active_route(['forms/*']) }}" aria-controls="forms">
<i class="link-icon" data-feather="trello"></i>
<span class="link-title" name="monspan">{{$p->nom}} </span>
<i class="link-arrow" data-feather="chevron-down"></i>
</a>
</li>
....
#endforeach
#elseif(count($projets)==0)
<li class="nav-item">
<p class="text-muted">Aucun projet active</p>
</li>
#endif
i got to learn about the providers from your answers so once again thank you for your time

view cannot access variable defined in controller in laravel

I could not think how to write question for this problem.
So this is my problem.
I have two views
store-side-menu.blade.php
×
#foreach($store_categories as $cats)
{{ $cats->category_of_store }}
#endforeach
employ.blade.php
#section('side-menu-section')
#include('fc.static.store-side-menu')
#endsection
In employ.blade.php is only includes the store-side-menu.blade.php. I have designed this structure due to need.
In controller I have
public function employment()
{
$search = "";
$store_categoies = Category::all();
return view('fc.employ.employ', compact('search', 'store_categories'));
}
Now I have included store_categories in compact but store-side-menu.blade.php cannot access it. How do I achieve with its solution.
Try the code below and you should be good to go:
#section('side-menu-section')
#include('fc.static.store-side-menu', ['store_categories' => $store_categories])
#endsection

Routing with parameters in laravel 5

I've got a results page for my website that outputs a list of users.
#extends('templates.default')
#section('content')
<h3>Results for "{{ Request::input('query') }}"</h3>
#if (!$users->count())
<p>No results found, sorry.</p>
#else
<div class="resultRow">
<div class="">
#foreach ($users as $user)
#include('user/partials/userblock')
#endforeach
{!! $users->appends(Request::except('page'))->render() !!}
</div>
</div>
#endif
#stop
with a fairly standard search controller:
class SearchController extends Controller {
public function getResults(Request $request) {
$query = $request->input('query');
$users = User::where(DB::raw("CONCAT(first_name, ' ', last_name)"), 'LIKE', "%{$query}%")->where('role', '=', 2)
->orWhere('username', 'LIKE', "%{$query}%")->where('role', '=', 2)
->orWhere('profile_text', 'LIKE', "%{$query}%")->where('role', '=', 2)
->orWhere('keywords', 'LIKE', "%{$query}%")->where('role', '=', 2)
->orWhere('tagline', 'LIKE', "%{$query}%")->where('role', '=', 2)
->simplePaginate(1);
return view('search.results')->with('users', $users);
}
}
Now, this works fine and well. If I search for "Jack", I get all the Jacks.
What I want to know now is, would it be possible to have a route with a predefined parameter or query string?
For example, say, on my front page I had a link to all the plumbers in my users.
<a id="plumbers" href="{{ route('search.results')->withQueryOfPlumbers }}">Plumbers</a></li>
Would this be possible? Or should I be outputting my data another way?
If you are just using GET parameters, the route() helper allows you to pass parameters as a second parameter such as: route('search.results', ['user-type, => 'plumbers'])
This will output: http://www.example.com/search/results?user-type=plumbers
You can add a column to your User called profession, then you'd do something like this:
$plumbers = User::where(['profession'=>'plumber', /*other WHERE options*/])->get();
This will return all of the users that are plumbers.
If you're hard coding the id and text of the a link, then you could just do
<a id="plumbers" href="{{ route('search.results') }}/plumbers">Plumbers</a>
And then match the keyword of plumbers in your routing table, see Laravel docs on routing parameters for more info.
Your route would look something like this:
Route::get('/search/{trade?}', ['uses' =>'SearchController#getResults', 'as' => 'search.results']);
You should be able to then inject the $trade variable into your controller. A small aside, I would avoid using raw queries in controllers as much as possible from a design and maintenance perspective and make a "search" helper function in your Eloquent model for users (See Eloquent query scopes).

how we can pass multiply id in laravel

My view.blade.php code here
<a href="{{ url('p_grid') }}/{{($cat_id)}}/{{$row->sub_id}}">
My route code here
Route::resource('p_grid', 'BasicController#p_grid');
And my BasicController code here
public function p_grid(Request $request, $id)
{
echo "success";
if ($id == 1) {
$r = DB::table('sub_category')
->select('*')
->where('cat_id', $id)
->where('sub_status', '1')
->orderBy('sub_id', 'asc')
->get();
$cat_name = DB::table('category')
->where('cat_id', $id)
->get();
$count = DB::table('products')
->where('sub_id', $id)
->count();
return view('buy-and-sell/p_grid', compact('r','cat_name','count','id'));
}
click on anchor tag to show this error
The extra parameter in your URL is causing the 404. Laravel doesn't expect the URL to have multiple id's, because you are using resourceful routing. You will need to append your routes.php file to account for this:
Route::resource('p_grid', 'BasicController#p_grid');
Route::get('p_grid/{category}/{subcategory}', [
'as' => 'category-with-subcategory',
'uses' => 'BasicController#gridWithSubcategory',
]);
And make sure you have a gridWithSubcategory method in your BasicController.php file.
That said, I'd advise you to understand better what Laravel is doing when you declare Route::resource(), because I would question how much of it you really need. It's really just a shorthand for registering ordinary routes (see here for the full list and specifications) like index, create, show, destroy, etc. If you want to see the routes your app actually has, after being parsed by Laravel (including routes not in your routes.php, which could have been registered by third-party packages) type php artisan route:list on a CLI.
Finally, I'd strongly suggest using route names throughout your app for better clarity and portability. The artisan command above will give you route names, so you can use something like this in your views:
<a href="{{ route('category-with-subcategory', ['category' => $cat_id, 'subcategory' => $row->sub_id]) }}">
That way, if you ever want to change your route's footprint, the view won't break (as long as you maintain the parameter requirements).
My view.blade.php code here
<a href="{{ url('p_grid', ['category' => $cat_id, 'subcategory' => $row->sub_id]) }}">
My route code here
Route::get('p_grid/{category}/{subcategory}', [
'as' => 'category-with-subcategory',
'uses' => 'BasicController#p_grid'
]);
And my BasicController code here
public function p_grid(Request $request, $id)
{
echo "success";
}
success image upload and work done
enter image description here

Categories