Included blade template repeating in each foreach loop iteration - php

I'm using Blade templating with Laravel and I'm trying to use a #foreach loop to display notifications. The problem is that if I have say 10 notifications, the first notification is repeated 10 times.
The code to output each notification:
#foreach ( Auth::user()->unreadNotifications as $notification )
{{ $notification->type->web_template }}
{{ $notification->id }}
#include($notification->type->web_template)
#endforeach
web_template will output a path to the template: notifications.web.user_alert
For each iteration of the loop the {{ $notification->type->web_template }} and {{ $notification->id }} will output what they're supposed to but #include($notification->type->web_template) will only output the first notification each time.
So the output will look like:
156 notification.web.new_message
You have a new message from Joe.
154 notification.web.user_alert
You have a new message from Joe.
145 notification.web.new_like
You have a new message from Joe.
I think it's some sort of cache issue maybe, but I couldn't find anyone with the same problem.
Any ideas?
UPDATE: Adding some code
Example notification view:
#extends('layouts.notification-wrapper')
#section('url', url('jobs/'.$notification->job_id.'#highlight'.$notification->bid_id))
#section('image', '/assets/img/no-photo.jpg')
#section('header', $notification->collector->firstname . ' ' . $notification->collector->secondname)
#section('description')
has placed a bid of €{{ number_format($notification->bid()->withTrashed()->first()->amount,0) }} on your job.
#stop
Notification wrapper:
<li #if(!$notification->read)
class="unread"
#endif>
<a href="#yield('url')" data-id="{{ $notification->id }}">
<div class="pull-left">
<img src="#yield('image')" class="img-circle" alt="user image">
</div>
<h4>
#yield('header')
<small><i class="fa fa-clock-o"></i> {{ $notification->created_at->diffForHumans()}}</small>
</h4>
<p> #yield('description')</p>
</a>
</li>

Answering my own question!
Found this: Laravel Blade Templates Section Repeated / cache error
Basically whatever way it works I need to overwrite my sections when looping and using #yield... I think. So I need to replace #stop with #overwrite in my views.

Related

Add a block field from a specific article

I have an article, each article has article_blocks, the blocks have a video_link field
And I need to display this field in the list of articles
This is how the article list output is roughly implemented
<div class="blog-list">
#foreach($articles as $article)
<div class="blog-article">
<div class="video-button video-modal-button-blog" data-video="https://www.youtube.com/embed/{{ $article_block->video_link }}">
<span>Watch video</span>
</div>
<h2 class="blog-article__title">{{ $article->title }}</h2>
<span>{{ date('d F Y', strtotime($article->published_at)) }}</span>
<span>{{ $article->getTotalViews() }} Views</span>
</div>
#endforeach
</div>
Each article has a button to open a video, but this video field itself is not in the article itself, but in the article blocks
I now take this field from the block and output it, it turns out like this
<?php
use App\Models\ArticleBlock;
$article_block = ArticleBlock::whereNotNull('video_link')->first();
?>
<div class="blog-list">
#foreach($articles as $article)
<div class="blog-article">
#if ($article_block->video_link !== 'null')
<div class="video-button video-modal-button-blog" data-video="https://www.youtube.com/embed/{{ $article_block->video_link }}">
<span>Watch video</span>
</div>
#endif
<h2 class="blog-article__title">{{ $article->title }}</h2>
<span>{{ date('d F Y', strtotime($article->published_at)) }}</span>
<span>{{ $article->getTotalViews() }} Views</span>
</div>
#endforeach
</div>
As a result, I get this field with video and it is displayed, but the same video is displayed for all articles in the list, and each article should have its own field and its own video. How can this be fixed?
I probably need to look for something like blocks by article id
$article_block = ArticleBlock::where('article_id', $article->id)->whereNotNull('video_link')->first();
But I can't get id
Cant write comment, under 25 rep :(
data-video="https://www.youtube.com/embed/{{ $article_block->video_link }}"
This looks wrong. You should eager load article blocks (eager loading is generally faster than lazy loading) for all articles with a with statement in your eloquent query see: https://laravel.com/docs/8.x/eloquent-relationships#eager-loading
Then if everything is correct you should be able to do just {{ $article->block->video_link }} or something similar.
Above is right if article has only one article block (one to one relationship).
But it seems that article has multiple blocks (one to many relationship) so you would need to iterate over each of the article block as well with another #foreach statement.
#foreach($articles as $article)
#foreach($article->article_blocks as $block)
<p>URL of video is: https://www.youtube.com/embed/{{ $block->video_link }}</p>
#endforeach
#endforeach
Now lets answer your question why video is same everywhere? Because you've coded it as so. You should NEVER write custom queries in your blade files.
Here i am referring to this part of your code:
<?php
use App\Models\ArticleBlock;
$article_block = ArticleBlock::whereNotNull('video_link')->first();
?>
Queries should be either in controllers/services or repositories.
$article_block = ArticleBlock::whereNotNull('video_link')->first();
will just give you first article block defined in ur database where video_link is not null. It won't guarantee that ArticleBlock belongs to given Article.
Lets hope that i put you on the right path ^.^

Using PHP template engine on Laravel blade

im calling v-for event on div tag to create <a> tag by every object on results array
Code attempt:
results array:
html (Laravel blade):
#verbatim
<div class="category-item" v-for="result in results" :value="result.id">
<a class="button-product-info-s" href="/product/{{ result.id }}"/>{{ result.name }}</a>
</div>
#endverbatim
brower output:
as you can see {{ result.name }}} is just working and {{ result.id }} is not outputing anything
i tried using .{{ result.id }}. but didn't work
Have you tried changing your href attribute to :href="'/product/'.result.id"?
Or with the + operator instead of .
Change your code to something like:
#verbatim
<div class="category-item" v-for="result in results" :value="result.id">
<a class="button-product-info-s" href="/product/#{{ result.id }}"/>#{{ result.name }}</a>
</div>
#endverbatim

Pagination Link

What is the correct way to call the "Links" function after this "Foreach"?
I don't know how to handle the variable to put in function.
#inject('usuarios', 'App\User')
#foreach($usuarios->getIndicados() as $user)
#endforeach
<div class="row">
<div class="col-12 text-center">
{{ $usuarios->getIndicados()->links() }}
</div>
</div>
Maybe it's just an editing error, but in your output the -tags don't seem to be closed again. Also, there should be no space like < a> at the beginning of the tag. And < a hr_ef= ... is obviously wrong.
In order to style them, you can add a class attribute to the tags while building the string and do the style-stuff in css.
This is what laravel document provides. You need to add links in the collection.
<div class="container">
#foreach ($users as $user)
{{ $user->name }}
#endforeach
{{ $users->links() }}

Get custom post type fields through a repeater

I'm in a WP project. I created a custom post type called Team Members
I also created a custom field block with a field called contact_members which is a repeater and has two sub-fields called location_map and member. This member sub-field is related with the custom post type team member.
I have no issues with getting the location_map.
The issue is that I can't get the post type fields. (coming from contact_members->member->post type
<?php
$members = get_field('contact_members');
?>
#foreach($members as $member)
<div class="member {{ $member['location_map'] }}">
<img class="map" src="{{ get_the_post_thumbnail_url($member['member']->ID) }}">
<h3>{{ get_the_title($member['member']->ID) }}</h3>
<p class="position">{{ $member['member']->position }}</p>
<p class="location">{{ $member['member']->location }}</p>
Contact
</div>
#endforeach
On a first look i cant see any problems with your code. What i consider the most possible senario is ( since that i guess you are using the ACF plugin ) the $member['meber'] variable holds the (int) post_id and not the Post Object. Have you tried var_dump() ?
Cheers!
I found the answer, I should put [0] after $member['member'], in order to reach the array's first element and after that I can finally go after what I want from the object, so:
<?php $members = get_field('contact_members'); ?>
#foreach($members as $member)
<div class="member {{ $member['location_map'] }}">
<img class="member-image" src="{{ get_the_post_thumbnail_url($member['member'][0]->ID) }}">
<h3 class="member-name">{{ $member['member'][0]->post_title }}</h3>
<p class="position">{{ $member['member'][0]->position }}</p>
<p class="location">{{ $member['member'][0]->location }}</p>
Contact
</div>
#endforeach

laravel blade template variables

In working with laravel blade templates, what's the approved way to manage variables in output?
For example, I'm working on a view that shows upcoming chores / tasks for each farmer. The pivot table holds a due_at datetime field for the task, and I'd like to change the class of the item depending on whether it's overdue, done, etc.
#foreach ($farmer->tasks as $task)
#if ($task->pivot->due_at) < date(now))
$style = 'alert alert-danger';
#elseif ($task->pivot->due_at) > date(now))
$style = 'alert alert-success';
#else
$style = '';
#endif
<div class="list-group-item {{ $style }}">{{$task->name}} <span class="glyphicon glyphicon-calendar"> {{ $task->pivot->due_at }}</span> <span class="glyphicon glyphicon-pencil"></span><span class="glyphicon glyphicon-trash"></span></div>
#endforeach
This example throws an error: Undefined variable: style (View: /home/vagrant/Code/app/views/farmers/show.blade.php)
I don't see an obvious way to do simple code blocks to set variables like I'd do in a "normal" PHP view to define the class to apply to the task item by doing some basic calculations on the due_at value.
Should this logic be moved to a helper function or something?
Assume due_at is a timestamp.
#foreach ($farmer->tasks as $task)
#if (Carbon::parse($task->pivot->due_at) < Carbon::now())
<?php $style = 'alert alert-danger'; ?>
#elseif (Carbon::parse($task->pivot->due_at) > Carbon::now())
<?php $style = 'alert alert-success'; ?>
#else
<?php $style = ''; ?>
#endif
<div class="list-group-item {{ $style }}">{{$task->name}} <span class="glyphicon glyphicon-calendar"> {{ $task->pivot->due_at }}</span> <span class="glyphicon glyphicon-pencil"></span><span class="glyphicon glyphicon-trash"></span></div>
#endforeach
#Anam Your answer works, but I will use following method.
#user101289 Assuming that you have default layout and it yields content section. So to declare and use variables I would suggest you use vars section in your inner template file and declare all your variables all at once on the top. And then use it. Since we will not yield the section vars, it will not going to print it.
This will help you to keep track of variables used and its standard method to declare all variables on top and use in rest of the program:
#extends('layouts.default') /* Your default layout template file. */
#section("vars")
{{ $yourVar = 'Your value' }}
#endsection
#section("content") /* The content section which we will print */
// Your other HTML and FORM code and you can use variables defined in **vars** section
#endsection
#stop

Categories