I'm using Laravel 8, but don't seem to know which controller controls the layout master blade file. I have been able to pass variables to the sub-view (Profile page) file successfully but don't know how to achieve that with the layout view master blade.
I am trying to pass variables from a controller called ProfileController in app\Http\Controllers to the master blade layout. In the profile controller, I have a code that retrieves user profile data from the database.
$profileInfo = Profile::with('address')->where('id', '=', '1')->get();
return view('admin_pages.profile', compact('profileInfo'));
In the profiles table, I have names and image fields first_name, last_name, photo which I can access with a foreach loop from the data $profileInfo passed to the sub-view using
#foreach($profileInfo as $data)
{{ $data->first_name}}
#endforeach
and so on.
My master blade file is located at resources\views\layout\admin.blade.php. I want to be able to display the names and photo from the admin.blade.php so the logged in user can see their profile image when logged in even when they don't visit their profile page (sub-view) which is located at resources\views\admin_pages\profile.blade.php, extending the master blade (admin.blade.php).
Please kindly help out.
Solution 1:
You can pass variable from the blade file via the #extends as second argument function.
Controller:
public function index(){
$title='Sir/Madam';
return view('home',compact('title'));
}
Home.blade.php
<?php
#extends('layouts.admin', ['title' => $title])
Layout.master.blade.php
dd($title)
you will see results.
I suggest you to learn about Laravel Component.
You can make the profile in admin layout with dynamic data, reusable without pass variable in every controller and route.
Create an Admin component with artisan:
php artisan make:component Profile
It will create a Profile.php as component controller and profile.blade.php
Open Profile.php and add this code:
public function render()
{
return view('components.profile', [
'profile' => Profile::with('address')->where('id', '=', '1')->first();
]);
}
Open profile.blade.php
<div>
{{$profile->first_name}}
</div>
Now, render the Profile component on your template admin.
Replace
#foreach($profileInfo as $data)
{{ $data->first_name}}
#endforeach
with
<x-profile/>
You can learn more by reading blade documentation in this link
Related
I have simple URL /players/USERNAME to view user profile. I want to insert some thing only in user profile page. Cuz user profile got another links.
Example:
#if (Request::is('players/{{ $user->slug }}'))
#include('users::stats')
#endif
But dont get anything. Any ideas what's wrong? Thanks!
I don't think Request::is is necessary in your blade view. You should have a route defined in your web.php file to capture that pattern meaning you already know the end user is on players/{username}.
web.php
Route::get('/players/{slug}', [
PlayerController::class, 'show'
])->name('players.show');
PlayerController.php
public function show($slug)
{
$user = User::where('username', $slug')->firstOrFail();
return view('players.show', compact('user'));
}
Blade view (players/show.blade.php)
// some stuff
#include('users.stats')
// some other stuff
Note that I've named the methods and files based on what you've provided, you'll need to change them to be whatever they are in your project.
I'm making a presonification menu on my navbar so that i can access from any page i don't want to use the getRepository inside a controller and pass to the frontend.
Is there a way on symfony 4 that I can get all the users from my database and call it to front? like the app.session.user (to get info on the logged user) for example?
Thanks!
As Cerad mentioned, you can embed a Controller in your templates : https://symfony.com/doc/current/templates.html#embedding-controllers
Instead of doing {% include 'base/navbar.html.twig' %} you will do
In your template :
{{ render(controller('App\\Controller\\BaseController::renderNavbar')) }}
In BaseController
public function renderNavbar(UserRepository $userRepository) {
return $this->render('base/navbar.html.twig', [
'activeUsers' => $userRepository->findActiveUsers(),
]);
}
It's not a route, it's simply a function that renders html, so you don't need to add annotations.
I have a layout that is used when you are logged in. menu.blade.php.
Then I use it in blade files #extends('admin.layouts.menu')
I want to show some information in the layout, let's say the number of messages near the "message" link in the menu. I could easily do this by adding:
$message_count = Message::where("user_id", Auth::user()->id)->count();
and adding: <div>{{$message_count}}</div> to menu.blade.php
to every single controller and view where the layout is used, but this is clearly not a clean way to do it.
Is there a way to pass information to the view in a single step instead of having to do it in every single controller?
Use view composers.
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
Register the view composer within a service provider:
public function boot()
{
View::composer('menu', function ($view) {
$view->with('messagesCount', auth()->user()->messages->count())
});
}
Then each time when the menu view will be rendered, it will have $messagesCount variable with counted messages for an authenticated user.
I have an admin template which I builded with blade templates,including one another.The user request is extending the main blade and returning only the content.
However in the template I have stuff like - user messages(count),theme options etc.
These things must be saved in the user session.Cookies are not an option.
The question is how to do it in the best possible option.
I'm thinking of gettind the request in middleware and accessing the session there.After that I must pass the data to the blade templates (not the final extending one).
Whats your opinion ?! Thanks!
If I understand correctly, you have a main layout blade template that is later extended by the user view returned by the controller.
No additional code like you described is needed. Both user and layout templates are processed after controller action is executed and both have access to user session via session() helper and user object via Auth::user().
So the following sample code should work for you :
// SomeController
public function someAction() {
return return response()->view('user');
}
// main.blade.php
#if (Auth::check())
Show this text only to authenticated users
#endif
Value of session parameter is {{ session('parameter_name') }}
// user.blade.php
#extends('main')
I have a laravel page which can be extended from admin layout or user layout.
If the user logged as admin it should extend from admin, otherwise it should extend from user.
Can I make this control with a simple if inside of my view like:
//in my view
#if(Auth::check())
#extends('layouts.admin')
#else
#extends('layouts.outside')
If I do this control in my controller I need to make two view for user and admin and I dont want to duplicate my views like:
//in my controller
if(Auth::check())
return View::make('bot/bwin_admin');
else
return View::make('bot/bwin_user');//the view is duplicated :(
So how can I use different parent layout for a view without duplicating that view in laravel?
You can control the layout in your controller.
First add the default layout to your controller:
public $layout = 'layouts.outside';
Then do this in your action:
if(Auth::check()){
$this->layout = View::make('layouts.admin');
}
$this->layout->content = View::make('bot/bwin');
Also, you can then remove the #extends() from your view. It is not needed anymore since the controller defines the layout.