How do I display images in a footer? - laravel

I have stored logos in the database and want to display them in the footer which is included #include('layouts.footer'). I am fetching images from the database using this code
public function show(){
$logo = DB::table('logos')->get();
return view('layouts.footer',['logo'=>$logo]);
}
I want to display these images in the footer using
<div class="footer">
#foreach($logo as $l)
{{ $l->company_name}}
{{ $l->company_logo}}
#endforeach
<p class="footer-text">© Copyright <?php echo date("Y"); ?> Hotel Store Partners</p>
</div>
but returns an error "undefined variable logo".
What is the correct way to display the images in the footer?

Try Using View Composer
In you AppserviceProvider boot method you can gather these name and pass to all Views at once.
Reference

Two ways you can achieve this:
1. Put this code in footer.
#php
$logo = DB::table('logos')->get();
#endphp
<div class="footer">
#if(count($logo))
#foreach($logo as $l)
{{ $l->company_name}}
{{ $l->company_logo}}
#endforeach
#endif
<p class="footer-text">© Copyright <?php echo date("Y"); ?> Hotel Store Partners</p>
</div>
But this method is a bad practice
Create FooterComposer
public function compose(View $view)
{
$logo = DB::table('logos')->get();
$view->with(['logo'=>$logo]);
}
Now $logo will be accessible in footer.

I have used View Composer.
In AppServiceProvider boot method, I added this code:
public function boot()
{
View::composer('layouts.app', function($view){
$view->with('logo', Logo::all());
});
}
In the Controller, I used this code:
return view('layouts.footer');
In the footer, I used this code:
<footer>
#foreach($logo as $l)
<p>{{ $l->company_name }}</p>
<img src="https://partners.hotelstore.co.ke/public{{ $l->company_logo }}" style="width:100px; height:75px;">
#endforeach
<p class="footer-text">© Copyright <?php echo date("Y"); ?> Hotel Store Partners</p>
</footer>
This is what finally displayed the images on the footer.

Related

property does not refresh in the internal components of Livewire

Take a look at the following examples:
showPost.blade.php:
<div>
<livewire:content-box :content="$post"/>
<button wire:click="nextPost" >Next Post >></button>
</div>
and
content-box.blade.php :
<div>
<h1>{{ $content->title }}</h1>
<p>{{ $content->content }}</p>
</div>
So far, it is completely clear what is going to happen ...: First, the information of the content to be viewed is received through showPost and passed to the contentBox, and everything is OK ..
Well now I want to get the information of the next content via the account through the button I put and calling the nextPost method:
class ShowPost extends Component
{
public Post $post;
public function render()
{
return view('livewire.show-post');
}
public function nextPost()
{
$id = $this->post->id;
$nextPost = Post::where('id', '>', $id)->first();
$this->post = $nextPost;
}
...
But nothing happens and the contentBox component has no reaction .... Has anyone had this problem ???!
I'm not sure livewire works well with nested components. could use the pagination instead. The livewire docs suggest you should not use them for little snippets or use blade components for that kind of nesting.
You can achieve what you're doing at the moment with some simple pagination.
<?php
namespace App\Http\Livewire;
use App\Models\User;
use Livewire\Component;
use Livewire\WithPagination;
class SomeContent extends Component
{
use WithPagination;
public function render()
{
// Using simplePaginate(1) instead of paginate(1).
// simplePaginate only shows "<- Previous" and "Next ->" links
// paginate shows those 2 buttons but also page numbers which you don't seem to want.
return view('livewire.some-content', [
'users' => User::simplePaginate(1),
]);
}
}
<div>
{{-- This might look wrong, but essentially it's looping through an array of length 1 because we're paginating --}}
#foreach ($users as $user)
<h1>{{ $user->name }}</h1>
<h2>{{ $user->email }}</h2>
#endforeach
{!! $users->links() !!}
</div>
EDIT
I can confirm blade components work.
Here, nextUser is the same implementation you gave.
public function nextUser()
{
$id = $this->user->id;
$nextUser = User::where('id', '>', $id)->first();
$this->user = $nextUser;
}
<div class="container">
<div class="content">
{{-- These two have the exact same template --}}
<livewire:child :user="$user" />{{-- Doesn't update when clicking Next --}}
<x-blade-child :user="$user" />{{-- Updates when clicking Next --}}
</div>
<div>
<button wire:click="nextUser">Next</button>
</div>
</div>
When clicking nextUser, the blade component updates but the livewire one doesn't.
Livewire doesn't like nested components. In your case, we can use basic blade component:
<div>
<x-content-box :content="$post"/>
<button wire:click="nextPost" >Next Post >></button>
</div>
And then:
Move content-box.blade.php to resources/views/components/
Remove component_name.php file in app/Http/Livewire
Most of the time, we can change 2 nested livewire components to livewire(parent) + basic blade component(child),

Showing data from database using Laravel Eloquent Model

So, I'm quite new to Laravel and what I am trying to achieve is to display some string from my data to a page. I'm using Eloquent Model and I can't figure out what I do wrong here. I've attached some of my code below. I hope I make it clear enough.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Product;
class ProductsController extends Controller
{
public function index()
{
$products = Product::all();
return view('products.index')->with('products', $products);
}
Here's where I want the data to be displayed.
#extends ('layouts.app')
#section ('content')
<div class="container-fluid">
<h1>Products</h1>
#if(count($products) > 1 )
#foreach ($products as $product)
<div class="well">
<h3>{{$product->prod_name}}</h3>
</div>
#endforeach
#else
<p>No product found</p>
#endif
</div>
#endsection
UPDATED: The problem is with my loop logic
Since I have only one item inside my database, my loop is supposed to be >= 1 instead of > 1
#if(count($products) >= 1 )
#foreach ($products as $product)
<div class="well">
<h3>{{$product->prod_name}}</h3>
</div>
#endforeach
#else
<p>No product found</p>
#endif
Let's fix up your code and use the correct approach.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Product;
class ProductsController extends Controller
{
public function index()
{
$products = Product::all();
return view('products.index', compact('products'));
}
Notice how I've passed an array via compact as the 2nd parameter of the view function. You can also use view('products.index', ['products' => $products]), I just prefer compact as it is cleaner.
#extends('layouts.app')
#section('content')
<div class="container-fluid">
<h1>Products</h1>
#if(!$products->isEmpty())
#foreach($products as $product)
<div class="well">
<h3>{{ $product->prod_name }}</h3>
</div>
#endforeach
#else
<p>No products found.</p>
#endif
</div>
#endsection
Notice how I've made use of isEmpty, which checks if a collection (obtained here from Eloquent) is empty or not.
Instead of with() maybe View::share can work.
$products = Product::all();
View::share('$products',$products);
return view('products.index');
And dont forget to import View class from Facades. Put this at the begining of page
use Illuminate\Support\Facades\View;

laravel rendering section no passing parameters data

i have a problem passing variable during the rendering of only a section
All works good but array of data passed to the section('sidebar') view create an error ($data doesn't exist)
My blade files are
Default.blade.php
..other html code before..
<body>
#include('includes.header')
<div class="container-fluid">
<div class="row">
#yield('sidebar')
<!-- main content -->
#include('includes.main')
</div>
<footer class="row">
#include('includes.footer')
</footer>
</div>
</body>
..other code after..
home.blade.php
#extends('layouts.default')
#section('sidebar')
#include('includes.sidebar')
#stop
sidebar.blade.php
..other html code before..
<h2>The current UNIX timestamp is {{ time() }}.</h2>
<ul>
#isset($data)
#foreach ($data as $item)
<li class="nav-item"> {{$item->polizza}}</li>
#endforeach
#endisset
</ul>
..other html code after..
Controller Method search
public function search(Request $request){
if ($request->ajax()) {
$data = Customers::select('id','contr_nom','email','targa','cliente')
->where('polizza',request('polizza'))
->get();
return view('pages.home',$data)->renderSections()['sidebar'];
}
//return json_encode($data);
}
I know that array $data is good because i try return just JSON and i know that just sidebar refresh because timestamp change.
But $data is not passed to sidebar section refreshed!!
Why?
Thks a lot
You have the right idea, you just need to send the variable in a form that will be recognized. I'll break it out to an extreme, to help understand the parts, but you can easily recombine for shorter code.
$view = view('pages.home', compact('data')); // Compact with the text name ('data') sends the variable through
$sections = $view->renderSections(); // returns an associative array of 'content', 'pageHeading' etc
return $sections['sidebar']; // this will only return whats in the sidebar section of the view
Using compact() should get your where you need, and is the key.

How can I get images under a blog for a user

What I actually want is, for a specific user, I'm trying to show every image under a single blog. What I'm getting is a single blog post images for every blog.
Controller
$user_id = Session::get('id');
$user = Users::find($user_id);
$blogs = Blog::where('user_id', $user_id)->paginate(10);
$blogImage = BlogImage::where('blog_id', $blogs->pluck('id'))->get();
return view('Users.userlayout', compact('user', 'blogCat', 'blogs', 'username', 'blogImage'));
View Page
#foreach($blogs as $blog)
<div class="post">
#foreach($blogImage as $img)
<img src="{{asset('storage/blog_img/'.$img->blog_img)}}" alt="Image"
class="img-responsive">
#endforeach
<p>
<?php $str = $blog->blog_desc; ?>
{{str_limit($str, 250, "...")}}
</p>
<a href="{{URL::to('/blog-details/'.$blog->id)}}" target="_blank" class="btn_1">
Read more
</a>
</div>
<hr>
#endforeach
This is because you're using where instead of whereIn.
If you try and pass an array or a collection to where it will only use the first value.
$blogImage = BlogImage::whereIn('blog_id', $blogs->pluck('id'))->get();
Since this will return all of the BlogImage's associated with the Blog's the in the paginated list I would imagine you'll need to do a check to make sure you're only displaying the images that are associated with the specific Blog. One way you can do this is by using `#continue():
#foreach($blogImage as $img)
#continue($blogImage->blog_id !== $blog->id)
<img src="{{asset('storage/blog_img/'.$img->blog_img)}}" alt="Image" class="img-responsive">
#endforeach
All of that being said I would recommend using a one-to-many relationship between Blog and BlogImage:
Blog
public function images()
{
return $this->hasMany(BlogImage::class);
}
BlogImage
public function blog()
{
return $this->belongTo(Blog::class);
}
Then in your controller you can Eager load the images and have something like:
$blogs = Blog::with('images')->where('user_id', $user_id)->paginate(10);
And your blade file would have:
#foreach($blog->images as $image)
<img src="{{asset('storage/blog_img/'.$image->blog_img)}}" alt="Image" class="img-responsive">
#endforeach
You could then apply the same one-to-many relationship logic between User and Blog as well.

Recursive display of data with blade, laravel

My Controller:
class Comments extends Controller {
public function GenerateComments($id){
$theme = DB::table('New_Themes')
->where('id', $id)
->get();
$Comments = NewTheme_Comment::where('id_theme', $id)->get();
return view('comments', ['Themes'=>$theme, 'Comments'=>$Comments]);
}
My Table(NewTheme_Comment):
id
parent_id
id_theme
user
text
upVotes
downVotes
My view(contains the recursive display of the tree of comments like the same in reddit), ......(data) contains the bootstrap media object, and the </div>'s things are used to round up (visually) the tree of comments as it should be:
<?php
tree($Comments, 0, 0);
$var = -1;
function tree($Comments, $parent_id = 0, $level=0, $c=0) {
global $var;
foreach($Comments as $Comment) {
if($Comment['parent_id'] == $parent_id) {
If ($level > $var) $var++; else {
for ($i = $var-$level+1; $i>0; $i--) { if ($c < 0) echo '</div> </div>'; else $c--; };
$var=$level;
};
echo '........(data)';
tree($Comments, $Comment['id'], $level+1,$c);
};
};
};
?>
The problem is that .........(data) should contain this stuff:
<div class="media">
<div class="media-left">
<img class="media-object" style="height:40px; width:40px;" src="{{ URL::asset("images/upVote.svg") }}" >
<div>{{$Comment->upVotes-$Comment->downVotes}}</div>
<img class="media-object" style="height:40px; width:40px;" src="{{ URL::asset("images/downVote.svg") }}" >
</div>
<div class="media-body">
<p class="media-heading">{{ $Comment->text }}</p>
<p class="media-heading">{{ $Comment->user }} / {{ $Comment->created_at }} </p>
And I am using the blade above this line | , which I can't integrate into that echo in view, replacing the ..........(data).
I have the intuition that the function I should integrate into the controller but I am broken(I spent to much time on recursive method of displaying comments) and I don't know how to take the data and print out it as whole unit recursively.
Any help is GREATLY appreciated to find a way out of this mess, thank you very much
Edit 1:
This is an example if i am filling with bootstrap media object in ........(data):
<div class="media">
<a class="media-left" href="#">
<img class="media-object" src="..." alt="...">
</a>
<div class="media-body">
<h4 class="media-heading">Media heading</h4>
Without 2 x </div>
You are approaching the views in a wrong way, as blade templates are not meant to use functions, it's better to follow the below recommendations.
The best way for that is to place the function code inside a blade file, for example recursive.blade.php:
recursive.blade.php
#foreach($comments as $comment)
//place your code here
#endforeach
Then in your main blade you can call it several times:
main.blade.php
<div>
#include('recursive', ['comments' => $comments])
</div>
The below example works for me and is the most widely used approach. remember the default value for parent_id is -1.
Model
public function children(){
return $this->hasMany(self::class,'parent_id','id')->with('children');
}
Controller
$comments = Comments::where('parent_id','=',-1)->get();
return view('comments',['comments'=> $comments]);
Blade (comments.blade.php)
<div class="tree">
#include('comment-list-widget',['comments' => $comment])
</div>
Blade (comment-list-widget.blade.php)
<ul>
#foreach($comments as $comment)
<li>
<a>{{$comment->text}}</a>
#if(!empty($comment->children) && $comment->children->count())
#include('comment-list-widget',['comments' => $comment->children])
#endif
</li>
#endforeach
</ul>

Resources