I can't use variable from #props in Laravel blade - laravel

#props(['active' => false])
#php
$classes = 'block text-left px-3 text-sm leading-6 hover:bg-blue-500 focus:bg-blue-500` `hover:text-white focus:text-white';
if ($active) $classes .= ' bg-blue-500 text-white';
#endphp
<a {{ $attributes(['class'=> $classes]) }}>
{{ $slot }}
</a>
If statement doesn't access to $active variable, how can I fix it

Related

Laravel cannot find a Controller Method

Method App\Http\Controllers\CommunityController::show does not exist
My route
Route::get('/community/{id}', [CommunityController::class, 'community'])
->name('profile.community');
Controller
public function community($id)
{
$communityProfile = Community::find($id);
/* $join = CommunityUser::join('communities', 'communities.user_id', '=', 'community_users.user_id')->get(); */
return view('user.comprofile', compact('communityProfile', 'join'));
}
View community
#for ($i = 0; $i < 3; $i++)
<a href=" {{ route('profile.community', $communities[$i]->id) }} ">
<div class="w-full p-6 overflow-hidden bg-white border hover:bg-gray-50 border-gray-200 rounded-lg shadow-md dark:bg-gray-800 dark:border-gray-700">
<h5 class="mb-2 text-2xl font-semibold tracking-tight text-gray-900 dark:text-white">{{$communities[$i]->community}}</h5>
<p class="mb-3 font-normal text-gray-500 dark:text-gray-400 flex gap-3">
<x-iconsax-out-location class="text-[#F15E4A] w-5"/> {{$communities[$i]->address}}, {{$communities[$i]->city}}
</p>
<div class="flex gap-2">
<a href="#" class="inline-flex items-center font-semibold text-[#F15E4A] hover:underline cursor-default">
{{ $communities[$i]->type }}
</a>
#if ($communities[$i]->user_id === Auth::user()->id)
<span class="text-sm text-gray-500 pt-1">{{__('Created by: ')}}</span>
{{Auth::user()->name}}
#else
<span class="text-sm text-gray-500 pt-1">{{__('Created by: ')}}</span>
{{ $communities[$i]->name }}
#endif
</div>
</div>
</a>
#endfor
I am trying to view the community created by users but it gives me "cannot find a Controller Method ".
This can have several causes. Therefore, here is a small checklist:
The controller path is missing from your route:
use App\Http\Controllers\CommunityController; // this line
Route::get('/community/{id}', [CommunityController::class, 'community'])->name('profile.community');
Your CommunityController class name is misspelled
The namespace of the CommunityController is wrong
And then just to be sure, run: php artisan route:clear.

Attempt to read property "menus" on null

when i run laravel project on my computer after doing php artisan serve as soon as it login it shows error "Attempt to read property "menus" on null"
Please help me
#foreach ($specials->menus as $menu)
<div class="max-w-xs mx-4 mb-2 rounded-lg shadow-lg">
<img class="w-full h-48" src="{{ Storage::url($menu->image) }}" alt="Image" />
<div class="px-6 py-4">
<h4 class="mb-3 text-xl font-semibold tracking-tight text-green-600 uppercase">
{{ $menu->name }}</h4>
<p class="leading-normal text-gray-700">{{ $menu->description }}.</p>
</div>
<div class="flex items-center justify-between p-4">
<span class="text-xl text-green-600">${{ $menu->price }}</span>
</div>
</div>
#endforeach
welcomecontroller.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Menu extends Model
{
use HasFactory;
protected $fillable = ['name', 'price', 'description', 'image'];
public function categories()
{
return $this->belongsToMany(Category::class, 'category_menu');
}
}
I suppose you forgot to initialize $specials, it is null, that's why you get the error.
Could you try to use dd before foreach statement, so we can see it's content?
{{ dd($specials) }}
UPDATE:
#if(!is_null($specials))
#foreach ($specials->menus as $menu)
<div class="max-w-xs mx-4 mb-2 rounded-lg shadow-lg">
<img class="w-full h-48" src="{{ Storage::url($menu->image) }}" alt="Image" />
<div class="px-6 py-4">
<h4 class="mb-3 text-xl font-semibold tracking-tight text-green-600 uppercase">
{{ $menu->name }}</h4>
<p class="leading-normal text-gray-700">{{ $menu->description }}.</p>
</div>
<div class="flex items-center justify-between p-4">
<span class="text-xl text-green-600">${{ $menu->price }}</span>
</div>
</div>
#endforeach
#else
<div>no item was found</div>
#endif
Your issue is with this line of code (from the comments):
$specials = Category::where('name', 'specials')->first();
->first(); can return null, so when you use it later as $specials->menus, it can be null->menus, which is not valid.
You can use ->firstOrFail() to trigger a 404 in the event $specials results in null, or #foreach($specials->menus ?? [] as $menu) to short-circuit your foreach() with an empty array if $specials is null:
In your Controller:
$specials = Category::where('name', 'specials')->firstOrFail();
return view('welcome', compact('specials'));
OR
In your View:
#foreach($specials->menus ?? [] as $menu)
...
#endforeach
Either case will properly handle your "unsafe" code (unsafe meaning functional, but possible for unhandled errors, like null->menus, etc.) and either trigger a 404 before the view is rendered, or perform a foreach() on an empty array, which does nothing.

How to make a variable optional in blade template (laravel 8)

I get an error :
$count is undefined
Make the variable optional in the blade template. Replace {{ $count }} with {{ $count ?? '' }}
Here is my blade file:
#extends('layouts.layout')
#section('content')
<div class="container">
<br>
#if ($count == 0 && !$count == '')
<h3>Δε βρέθηκαν eshops με τον όρο αναζήτησης : <span class="badge badge-secondary">{{ $q }}</span>.
<br>
Θα κάνουμε ό,τι μπορούμε να καλύψουμε την ανάγκη σας !<h3>
<h5>Μπορείτε να δοκιμάσετε με ένα νέο όρο αναζήτησης ή επιβεβαιώστε την ορθογραφία σας.</h5>
<button type="button" class="btn btn-success">Δοκιμάστε πάλι !</button>
#else
<h3>Βρέθηκαν <span class="badge badge-secondary">{{ $count }}</span> eshops με τον όρο αναζήτησης : <span class="badge badge-secondary">{{ $q }}</span></h3>
#endif
#foreach($eshops as $eshop)
#include('includes.eshop')
<br>
#endforeach
</div>
#endsection
You could use the blade #isset or #empty as well:
#isset($count)
// $count is defined and is not null...
#endisset
#empty($count)
// $count is "empty"...
#endempty
More info can be found here: If Statements
Instead of {{ $count }} try this {{ isset($count) ? $count : ''}}
// Try this method.
{{( !empty($count)) ? $count : 'No Logs Found' }}
You can Try This.
#if(isset($count))
.....
#endif
I think shortest and most elegant would be:
{{ $variable ?? '' }}
or
{{ $variable ?? null }}
or
{{ $variable ?? 'Default value' }}

Yielding HTML inside of a slot doesn't work for components

So I have this simple admin toolbar:
<div class="admin-toolbar {{ $class ?? '' }}">
<i class="fas fa-user-shield"></i>
{{ $buttons }}
</div>
And I use it as such:
#admintoolbar
#slot('buttons')
<a href="/snippet/destroy/{{ $snippet->id }}">
<i class="margin-left(8px) far fa-trash-alt"></i>
</a>
#endslot
#endadmintoolbar
Surprisingly, I get Undefined variable: buttons at line {{ $buttons }}

Creating nested comments in laravel

I have the following blog control
public function show($slug)
{
$post = Blog::where('slugs', '=', $slug)->first();
$vars['pageTitle'] = Config::get('site.pageTitle') . $post['title'];
// The breadcrumbs... needs to be repopulated every page
$vars['breadCrumbs'] = [[
'url' => action('SimpleController#index'),
'title' => 'CovertDEV'
],[
'url' => action('BlogController#index'),
'title' => 'Blog'
],[
'url' => route('blog_post', ['slug' => $slug]),
'title' => $post['title']
]];
$vars['blog'] = $post;
$vars['comments'] = $post->Blog_comments->groupBy('comment_id');
return view('blog', $vars);
}
And the following scary view for the comments
#php
function display_comments($main, $depth = "\t")
{
foreach($main[0] as $mcomment)
{
#endphp
<div class="media">
<img class="m-3 avatar-sm rounded-1 border border-thick-1 shadow" src="../public/css/images/avatar-placeholder.png" alt="<?=$mcomment->firstname;?> <?=$mcomment->lastname;?>'s Avatar">
<div class="media-body">
<h6 class="mt-0 p-1 lead m-0 border-bottom"><?=$mcomment->firstname;?> <?=$mcomment->lastname;?></h6>
<div class="p-2">
<p><?=$mcomment->comment;?></p>
</div>
#php
if(isset($main[$mcomment->id]))
{
display_child($main, $main[$mcomment->id], $depth);
}
#endphp
</div>
</div>
#php
}
}
function display_child($main, $comment, $depth)
{
foreach($comment as $ccomment)
{
#endphp
<div class="media">
<img class="m-3 avatar-sm rounded-1 border border-thick-1 shadow" src="../public/css/images/avatar-placeholder.png" alt="<?=$ccomment->firstname;?> <?=$ccomment->lastname;?>'s Avatar">
<div class="media-body">
<h6 class="mt-0 p-1 lead m-0 border-bottom"><?=$ccomment->firstname;?> <?=$ccomment->lastname;?></h6>
<div class="p-2">
<p><?=$ccomment->comment;?></p>
</div>
#php
if(isset($main[$ccomment->id]))
{
display_child($main, $main[$ccomment->id], $depth."\t");
}
#endphp
</div>
</div>
#php
}
}
display_comments($comments);
#endphp
That is as ugly as it gets. It generates how I want it, but that is ugly, terribly ugly.
This is an image of the created nested comments
What is the best way to make this work elegantly in the blade template? I tried extending the blade template thing according to the docs, but that didn't prove fruitful for me. I simply couldn't figure out how to do it.
With this, I can't call asset, or anything like that... those are already out of scope.
I finally found my solution I'm satisfied with. If anyone has a better solution, do feel free to suggest.
My Blog controller is the same, only thing that changed is my view. In my blog view (where I see those comments as a user):
blog.blade.php
#foreach($comments[0] as $comment)
<div class="media comment">
#if(!is_null($comment->users['avatar']))
<img class="m-3 avatar-sm rounded-1 border border-thick-1 shadow" src="{{ asset( Config::get('site.asset_folder') . 'users/images/' . $comment->users['avatar']) }}" alt="{{ $comment->users['firstname'] }} {{ $comment->users['lastname'] }}'s Avatar">
#else
<img class="m-3 avatar-sm rounded-1 border border-thick-1 shadow" src="{{ asset( Config::get('site.asset_folder') . 'css/images/avatar-placeholder.png') }}" alt="{{ $comment->users['firstname'] }} {{ $comment->users['lastname'] }}'s Avatar">
#endif
<div class="media-body">
<h6 class="mt-0 p-1 lead m-0 border-bottom">{{ $comment->users['firstname'] }} {{ $comment->users['lastname'] }}</h6>
<div class="p-2">
<p>{{ $comment->comment }}</p>
</div>
#if(isset($comments[$comment->id]))
#include('block.comments', ['comments' => $comments, 'parent_id' => $comment->id, 'depth' => 0])
#endif
</div>
</div>
#endforeach
And then, my block/comments.blade.php
#foreach($comments[$parent_id] as $comment)
#if($depth >= Config::get('site.max_nested'))
</div>
</div>
#endif
<div class="media comment">
#if(!is_null($comment->users['avatar']))
<img class="m-3 avatar-sm rounded-1 border border-thick-1 shadow" src="{{ asset( Config::get('site.asset_folder') . 'users/images/' . $comment->users['avatar']) }}" alt="{{ $comment->users['firstname'] }} {{ $comment->users['lastname'] }}'s Avatar">
#else
<img class="m-3 avatar-sm rounded-1 border border-thick-1 shadow" src="{{ asset( Config::get('site.asset_folder') . 'css/images/avatar-placeholder.png') }}" alt="{{ $comment->users['firstname'] }} {{ $comment->users['lastname'] }}'s Avatar">
#endif
<div class="media-body">
<h6 class="mt-0 p-1 lead m-0 border-bottom">{{ $comment->users['firstname'] }} {{ $comment->users['lastname'] }}</h6>
<div class="p-2">
<p>{{ $comment->comment }}</p>
</div>
#if(isset($comments[$comment->id]))
#include('block.comments', ['comments' => $comments, 'parent_id' => $comment->id, 'depth' => $depth + 1])
#endif
#if($depth < Config::get('site.max_nested'))
</div>
</div>
#endif
#endforeach
And then I have a config file site in the config folder with the following contents
return [
// We define the max depth for the nested comments
// You could obviously define this value in database and be retrieving it from there
'max_nested' => 3,
];
The way my $comments array is set-up, the parent comments are always going to be in $comments[0] while the child comments would be in $comments[$parent_id]
I think that's fairly simple yet effectively functional!

Resources