I am trying to display the currently logged in username, as a link to the user info, in my main navigation. I can get the name to display, so I am pulling the info from the db, and passing it to the view OK. But, when I try to make it a link, I get the method not defined error.
Here is how I pass the user info to the navigation (as the var $userInfo):
public function index()
{
$Clients = \Auth::user()->clients()->get();
$userInfo = \Auth::user();
return view('clients.index', compact('Clients', 'userInfo'));
}
Here is the relevant bit from my navigation:
<ul class="nav navbar-nav">
<li>{!! link_to_action('AuthController#show', $userInfo->username, [$userInfo->id]) !!}</li>
</ul>
The method from my controller:
protected function show($id)
{
$userInfo = User::findOrFail($id);
return view('users.show', compact('userInfo'));
}
And, the route definition:
// User Display routes
Route::get('auth/{id}', 'Auth\AuthController#show');
Here is the error I get:
Action App\Http\Controllers\AuthController#show not defined.
Can anyone tell me what I am missing?
First, you need to make your AuthController::show() method public:
public function show($id)
{
$userInfo = User::findOrFail($id);
return view('users.show', compact('userInfo'));
}
Second, as your controllere is in App\Http\Controllers\Auth namespace, you need to use the **Auth** prefix in the view:
<ul class="nav navbar-nav">
<li>{!! link_to_action('Auth\AuthController#show', $userInfo->username, [$userInfo->id]) !!}</li>
</ul>
Related
I want to show the emails that the logged in user has sent from the database
This is the route code:
Route::get('/myEmails/{id}','PagesController#myEmailsShow');
This is the function in the controller:
public function myEmailsShow($id)
{
$myEmails = DB::table('emails')->where('user_id',$id)->get();
return view('content.myEmails', compact('myEmails'));
}
This is the a link where the user click to open the page:
#if(Auth::check())
<a class="nav-link text-white" href="/myEmails/{id}"> my emails</a>
#endif
And here where i want to show the data (i am showing only the name for test):
<div class="row">
#foreach($myEmails as $myEmail)
{{$myEmail->name}}
#endforeach
</div>
I think the best way to accomplish your goals here would be using a hasMany relationship between User and Emails (if emails is a Model).
//User.php
public function emails()
{
return $this->hasMany('App\Models\Email');
}
In the controller, apply the Auth middleware to the myEmailsShow method in a constructor:
//PagesController.php
public function __construct()
{
$this->middleware('auth')->only(['myEmailsShow']);
}
Then, in your myEmailsShow method, do something like the following:
//PagesController.php
public function myEmailsShow()
{
// Middleware Eliminates the need for ID in the function.
$user = auth()->user();
$myEmails = $user->emails;
return view('content.myEmails', compact('myEmails'));
}
You can remove the ID parameter from the route and just make it something like Route::get('/myEmails', 'PagesController#myEmailsShow');. Only users who are logged in will be able to access this page, and they will only see emails belonging to them.
Route::get('/myEmails/{user}','PagesController#myEmailsShow')->name('myemails');
with the controller
use App\Email;
use App\User;
public function myEmailsShow(User $user)
{
///calling the model Email at parameters instead of $id eloquent automatically the data from DB
$myEmails = Email::where('user_id',$user->id)->get();
return view('content.myEmails')->with('myEmails', $myEmails);
}
The link has little modifications
#if(Auth::check())
<a class="nav-link text-white" href="{{route('myemails', $user->id)}}"> my emails</a>
#endif
displaying the value
#foreach($myEmails as $myEmail)
{{$myEmail->name}}
#endforeach
This question already has an answer here:
Database driven menu that can be loaded in view
(1 answer)
Closed 5 years ago.
So,I have a the navbar in my home page where all the module name gets listed from the database. Instead of re-writing the whole code to list module name in all page I decided to use blade's #yeild() functionality.
This is my home page Controller where I get all the module names and pass it to the homepage view like so
public function index()
{
$data = Module::get();
return view("BaseView.home")->with('data',$data);
}
This is my homepage view where I display all the modules and it's respective name in the navbar like so
<ul class="navbar-nav">
#foreach($data as $modules)
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ $modules->module_name) }}<i class="plusMinus" aria-hidden="true"></i>
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
#foreach($modules->module_categories as $category)
<?php
$getModuleNameToLowerCase = strtolower($modules->module_name);
$getCategoryNameToLowerCase = preg_replace('/\s+/', '_', strtolower($category->categories_name));
?>
<a class="dropdown-item" href="#">{{ $category->categories_name }}</a>
#endforeach
</div>
</li>
#endforeach
</ul>
<div class="container-fluid">
#yield('mainBody')
</div>
Now When I extend this in another view like so
#extends('BaseView.home')
I get Undefined variable: data.
Can someone help me/guide me on how to solve this issue?
In you controller, you need to pass modules to each view, because view does not keep the values after new request. For each request there must be modules ($data).
Remember, the data passed to master blade using one controller method will not work for another controller method, because every time each new request need all values of those variables again that are used in master and child blades.
Controller
//..............
//.................
public function index()
{
$data['modules'] = Module::get();
//$data['other_data'] = User::get(); //To get other data and pass to your view
return view("BaseView.home")->with('data',$data);
}
public function profilePage()
{
$data['modules'] = Module::get();
//$data['profile_detail'] = Profile::get(); //To get other data and pass to your view
return view("BaseView.home")->with('data',$data);
}
//Something like this
But writing $data['modules'] = Module::get(); for each controller method, you can write it inside your constructor of the your controller. This will be for all methods (Requests) .
public function __construct(){
$data['modules'] = Module::get();
}
public function index()
{
//$data['other_data'] = User::get(); //To get other data and pass to your view
return view("BaseView.home")->with('data',$data);
}
//................
//.................
And view:
<ul class="navbar-nav">
<?php
if(isset($data['modules'])&&count($data['modules'])>0){
?>
#foreach($data['modules'] as $modules)
.............
..............
#endforeach
<?php
}
else{
echo "Modules are not available";
}
?>
</ul>
<div class="container-fluid">
#yield('mainBody')
</div>
The above is for your error message, But if you want that modules to be available anywhere then you can use session or creating helper
Instead of passing data on every view, use Providers boot method which triggers before loading any view and pass your default data on every view. simple.
I want that when the user click the profile page i want to pass Auth::user()->username as argument to my userController's show method.I have the profile link as following:
<li>Profile</li>
And in my route i have the following route
Route::get('/profile/{username}',function(){
return View::make('user.show')->with($username);
});
my question is how i can set username in my '/profile/{username}' as Auth::user()->username when i click the profile link?currently the profile link does not attach any parameter with it
First of all
{{URL::to('/profile')}} is not pointing to Route::get('/profile/{username}) url,there are two different routes
So what you need to do is either change the link , i.e.
{{URL::to('/profile/' . \Auth::user()->username)}}
and then in your route file
Route::get('/profile/{username}',function($username){
return View::make('user.show')->with(['username' => $username]);
});
//note that you need to pass the array in with() method
or you can do this
Route::get('/profile/{username}',function($username){
return View::make('user.show',compact('username'));
});
When the user clicks on profile link:
<li>
My Profile
</li>
The UserController#show method is called.
<?php
// routes.php
Route::get('profile/{username}', 'UserController#show')->name('user.show');
// UserController.php
public function show($username)
{
$user = User::whereUsername($username)->first();
return view('user.show', compact('user'));
}
and a View response is returned to the user.
#update
If you need is just redirect the control to the UserController#show method, you can do this:
<li>
My Profile
</li>
<?php
// routes.php
Route::get('profile/{username}', function ($username) {
return redirect()->route('user.show', Auth::id());
})->name('user.profile');
Now if you want customize the UserController#show action:
<li>
My Profile
</li>
The UserController#show method is called.
<?php
// routes.php
Route::resource('user', 'UserController', ['except' => ['show']);
Route::get('profile/{username}', 'UserController#profile')->name('user.profile');
Now you can delete the UserController#show method if you want or change the profile method name to show.
// UserController.php
public function profile($username)
{
$user = User::whereUsername($username)->first();
return view('user.show', compact('user'));
}
A quick way is to setup a redirect from /profile and it won't break the functionality if they want to view someone else's profile.
Route::get('/profile',function(){
return Redirect::to('/profile/'.Auth::user()->username);
}
However, I'd recommend doing an Auth::check() before the redirect.
i did something like the following
<li>Profile</li>
and in route.php:
Route::get('/profile',function(){
return redirect()->route('user.show',[Auth::user()->username]);
});
In Twig partial rendered by separate controller, I want to check if current main route equals to compared route, so I can mark list item as active.
How can I do that? Trying to get current route in BarController like:
$route = $request->get('_route');
returns null.
Uri is also not what I'm looking for, as calling below code in bar's twig:
app.request.uri
returns route similar to: localhost/_fragment?path=path_to_bar_route
Full example
Main Controller:
FooController extends Controller{
public function fooAction(){}
}
fooAction twig:
...some stuff...
{{ render(controller('FooBundle:Bar:bar')) }}
...some stuff...
Bar controller:
BarController extends Controller{
public function barAction(){}
}
barAction twig:
<ul>
<li class="{{ (item1route == currentroute) ? 'active' : ''}}">
Item 1
</li>
<li class="{{ (item2route == currentroute) ? 'active' : ''}}">
Item 2
</li>
<li class="{{ (item3route == currentroute) ? 'active' : ''}}">
Item 3
</li>
</ul>
pabgaran's solution should work. However, the original problem occurs probably because of the request_stack.
http://symfony.com/blog/new-in-symfony-2-4-the-request-stack
Since you are in a subrequest, you should be able to get top-level (master) Request and get _route. Something like this:
public function barAction(Request $request) {
$stack = $this->get('request_stack');
$masterRequest = $stack->getMasterRequest();
$currentRoute = $masterRequest->get('_route');
...
return $this->render('Template', array('current_route' => $currentRoute );
}
Haven't run this but it should work...
I think that the best solution in your case is past the current main route in the render:
{{ render(controller('FooBundle:Bar:bar', {'current_route' : app.request.uri})) }}
Next, return it in the response:
public function barAction(Request $request) {
...
return $this->render('Template', array('current_route' => $request->query->get('current_route'));
}
And in your template compares with the received value.
Otherwise, maybe is better to use a include instead a render, if you don't need extra logic for the partial.
in twig you can send request object from main controller to sub-controller as parameter:
{{ render(controller('FooBundle:Bar:bar', {'request' : app.request})) }}
in sub-controller:
BarController extends Controller{
public function barAction(Request $request){
// here you can use request object as regular
$country = $request->attributes->get('route_country');
}
}
In route.php I have the following...
Route::get('/user/{username}', array(
'as' => 'profile-user',
'uses' => 'ProfileController#user'
));
In ProfileController I have the following...
class ProfileController extends BaseController {
public function user($username) {
$user = User::where('username', '=', $username);
if($user->count()) { // if the corresponding user exists...
$user = $user->first();
return View::make('profile.user')
->with('user', $user);
}
return App::abort(404);
}
}
In navigation.blade.php I have the following...
<li>User Profile</li>
How can I make it so that navigation.blade.php will provide the correct link to the user profile? At the moment the link looks like the following in html...
http://website.dev/user/%7Busername%7D
I'd like it to look like this:
http://website.dev/user/currentlyLoggedInUserName
You can try using HTML::link. Example:
{{ HTML::link('/user/<?=$user_name?>', 'User Profile')}}
You should use
<li>User Profile</li>
because it is a Laravel PHP function url() that must resolve first, and the result is passed to Handlebars.
This is how I solved it. I'll leave the answer here for other people.
<li>User Profile</li>