Blade - (Sage 9) probem when multiple #yield/#section - php

We are new to sage9 / Blade framework and we are trying to create a template logic with ACF. Everything was working well with 1 block but when we add more block the first 1 echoes 2-3 times.
Here's how we did it:
We use the default layouts.app from sage9:
web/app/themes/[theme-name]/resources/views/layouts/app.blade.php
...
<div class="vy_main uk-offcanvas-content">
<header>
#yield('dispatch_banner')
</header>
<div class="wrap container" role="document">
<div class="content">
<main class="main">
#yield('dispatch') //The one we currently working on
</main>
...
In the layout we are calling #yield('dispatch'). Inside page.blade.php we are extending the layouts and we add the dispatch section.
web/app/themes/[theme-name]/resources/views/page.blade.php
#extends('layouts.app')
#section('dispatch_banner')
#layouts('banners')
{!! App::banners() !!}
#endlayouts
#endsection
#section('dispatch')
#layouts('sections')
{!! App::sections() !!} //This call a controller where we can select the correct section to display.
#endlayouts
#endsection
Inside the controller,
web/app/themes/[theme-name]/app/Controllers/App.php we return a template to use and passing configurations/variables to use. :
public static function sections(){
...
$return .= \App\template('sections.'.$sections, $config);
}
return $return;
...
}
We create a standard block. This block include by the dispatcher :
web/app/themes/[theme-name]/resources/views/sections/std.blade.php
Inside this template, we created a new layouts "base", because all sections will have the same base structure, we extend this base inside the template and put a section content in it like so:
web/app/themes/[theme-name]/resources/views/sections/std.blade.php
#extends('layouts.base')
#section('section-content')
#if ($image)
<div class="uk-grid uk-flex-middle" data-uk-grid>
<div class="{!! $class_image !!}">
<img src="{!! $image['url'] !!}" alt="{!! $image['alt'] !!}">
</div>
<div class="{!! $class_content !!}">
#endif
<div class="{!! $content_class_content !!}">
#layouts('content')
{!! App::content() !!}
#endlayouts
</div>
#if ($image)
</div>
</div>
#endif
#endsection
And here the layout
web/app/themes/[theme-name]/resources/views/layouts/base.blade.php
<section {{ (( $section_id )?'id='.$section_id:'') }} class="{!! $class_section !!}">
#if($has_container)
<div class="uk-container uk-container-{!! $container !!}" data-uk-scrollspy="cls: uk-animation-fade;">
#yield('section-content')
</div>
#else
#yield('section-content')
#endif
</section>
As I said, everything was working fine with 1 block but as soon as we add a second block the data just keep repeating BUT only the #yield('section-content') from the base, the variables use inside the layout aren't repeating.
Here what we have in the html from :
<section {{ (( $section_id )?'id='.$section_id:'') }} class="{!! $class_section !!}">
We get :
<section class="uk-section vy_std uk-section-primary uk-section-xlarge">
<section class="uk-section vy_accordion uk-section-transparant">
<section class="uk-section vy_std uk-section-transparant">
Where is the problem with our logic and we the content from #yield('section-content') keep repeating instead of using the right data send from the controller?
If this can help I can send all the code from the controller, it's not big but to me it's wasn't where the problem is so I cut this part out.
Thank for your time!

I manage to work this out by using components/slots instead of layouts. Now I get the base from a component like so:
#component('layouts.base', $config)
/*Section code*/
#endcomponent
And everything is working again!

Related

Laravel 8 - reusable code block, change variable depending on a page for charts?

I want to display multiple charts in a single page or different pages. How can I reuse the blade file instead of repeating/retyping the code?
I created a plain blade file _chart-widget.blade.php and I want the variable value to change depending on the page, or depending on what I want to set the variable in each <section> of a page
<!--begin::Charts Widget 1-->
<div class="card {{ $class ?? '' }}">
<!--begin::Header-->
<div class="card-header border-0 pt-5">
<!--begin::Title-->
<h3 class="card-title align-items-start flex-column">
<span class="card-label fw-bolder fs-3 mb-1">Recent Statistics</span>
<span class="text-muted fw-bold fs-7">More than 400 new members</span>
</h3>
<!--end::Title-->
<!--begin::Toolbar-->
<div class="card-toolbar">
<!--begin::Menu-->
<button type="button" class="btn btn-sm btn-icon btn-color-primary btn-active-light-primary" data-kt-menu-trigger="click" data-kt-menu-placement="bottom-end">
{!! theme()->getSvgIcon("icons/duotune/general/gen024.svg", "svg-icon-2") !!}
</button>
{{ theme()->getView('partials/menus/_menu-1') }}
<!--end::Menu-->
</div>
<!--end::Toolbar-->
</div>
<!--end::Header-->
<!--begin::Body-->
<div class="card-body">
<!--begin::Chart-->
<div id="kt_charts_widget_1_chart" style="height: 350px"></div>
<!--end::Chart-->
</div>
<!--end::Body-->
</div>
<!--end::Charts Widget 1-->
How can I make the code above dynamic and reusable when I #include it?
You can include views in Laravel blade template.
here you can read more.
Just use like this:
<div>
#include('_chart-widget')
</div>
If you need to pass data to your widget component, just give parameters as an array to your component:
#include('view.name', ['status' => 'complete'])
If you want variables to be different in each page simply pass vairables from Controller.If you are on the same page and including same blade multiple times this can help you:
#include('view.name', ['code' => 'complete'])
This will set different values for $code variable in different sections.
Check out documentation here.

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() }}

Laravel view links and web.php routes messed up

I'm making a forum with themes and topics. If a user clicks on a theme, he/she gets to see all the topics within that theme. Here we encounter the first problem. In the theme.blade.php I have a title: <span class="card-title">{{ $theme->theme_title }} - Topics</span>. This title is supposed to show the title of the theme that the user clicked on. But it shows (just a wild guess) some random theme title from the database that is not even connected to this topic.
Now I made an extra view for the user. If the user clicks on a topic from the selected theme. He/she is supposed to redirect to the topic that he/she clicked on but instead its shows (again) some random topic from the database that is not connected to the topic/theme at all. Instead of the topic that the user clicked on. In this GIF http://imgur.com/a/vOQFT you can see the problem If u look at the profile picture and username. Maybe the problem is in the Web.phpor somewhere else, I don't know. Sorry for the long story but I couldn't figure out how say this in a better way. I think I switched some things up in the code.
Here is the every file of code where this problem may occur
Web.php
Route::get('/', 'ThemesController#index')->name('home');
Route::get('/theme/{theme_id}/topics', 'ThemesController#show')->name('showtheme');
Route::get('/theme/{theme_id}/topics/{topic_id}', 'TopicsController#show')->name('showtopic');
Route::group(['middleware' => 'App\Http\Middleware\AdminMiddleware'], function() {
//THEMES
Route::get('/theme/{theme_id}/edit', 'ThemesController#edit')->name('edittheme');
Route::patch('/theme/{theme_id}/edit', 'ThemesController#update')->name('updatetheme');
Route::get('/theme/create', 'ThemesController#create')->name('createtheme');
Route::post('/theme/create', 'ThemesController#save')->name('savetheme');
Route::delete('/theme/{theme_id}/delete', 'ThemesController#destroy')->name('deletetheme');
//TOPICS
Route::get('/theme/{theme_id}/topics/{topic_id}/edit', 'TopicsController#edit')->name('edittopic');
Route::patch('/theme/{theme_id}/topics/{topic_id}/edit', 'TopicsController#update')->name('updatetopic');
Route::get('/theme/{theme_id}/topics/create', 'TopicsController#create')->name('createtopic');
Route::post('/theme/{theme_id}/topics/create', 'TopicsController#save')->name('savetopic');
Route::delete('/theme/{theme_id}/topics/{topic_id}/delete', 'TopicsController#destroy')->name('deletetopic');
});
Route::get('user/profile', 'UserController#profile')->name('showprofile');
Route::post('user/profile', 'UserController#update_avatar');
Theme.blade.php (The list of every topic within the theme)
<div class="col s12">
<div class="card">
<div class="card-content"><span class="card-title">{{ $theme->theme_title }} - Topics</span>
<div class="collection">
#foreach($topics as $topic)
<a href="{{ route('showtopic', ['theme_id' => $theme->id, 'topic_id' => $topic->id ]) }}" class="collection-item avatar collection-link"><img src="/uploads/avatars/{{ $topic->user->avatar }}" alt="" class="circle">
<div class="row">
<div class="col s6">
<div class="row last-row">
<div class="col s12"><span class="card-title">{{ $topic->topic_title }}</span>
<p>{!! str_limit($topic->topic_text, $limit = 125, $end = '...') !!}</p>
</div>
</div>
<div class="row last-row">
<div class="col s12 post-timestamp">Posted by: {{ $topic->user->username }} op: {{ $topic->created_at }}</div>
</div>
</div>
<div class="col s2">
<h6 class="title center-align">Replies</h6>
<p class="center replies">{{ $topic->replies->count() }}</p>
</div>
<div class="col s2">
<h6 class="title center-align">Status</h6>
<div class="status-wrapper center-align"><span class="status-badge status-open">open</span></div>
</div>
<div class="col s2">
<h6 class="title center-align">Last reply</h6>
<p class="center-align"></p>
<p class="center-align">Tijd</p>
</div>
</div>
</a>
#endforeach
</div>
</div>
</div>
</div>
ThemesController.php (Only show method)
public function show($id)
{
$theme = Topic::find($id)->theme;
$topics = Theme::find($id)->topics;
return view('themes.theme')->with('topics', $topics)->with('theme', $theme);
}
TopicsController.php(Only show method)
public function show($id)
{
$theme = Theme::find($id);
$topic = Topic::find($id);
return view('topics.topic')->with('theme', $theme)->with('topic', $topic);
}
Thanks for looking at my code. This problem has been sitting here for quite a while and I want to move on. Thanks for your help!
Your controller code simply finds the theme with ID $id, and the topic (singular!) with ID $id. That particular topic may not appear in that particular theme at all. They likely have nothing to do with each other.
To find the topics belonging to the theme with ID $id, you would do this:
$theme = Theme::find($id)->with('topics');
(this assumes your model relationships are set up correctly, you have not show us those). See the docs on eager loading.
To access the topics in your view, do something like this:
#foreach ($theme->topics as $topic)
...
{{ $topic->user->username }}
...
While developing, you can simply
return $theme;
in your controller to see the structure of the data, so you can work out how to handle and iterate over it.

Laravel Blade not pushing to stack when view rendered in function

The problem
When rendering a view with blade, I call a function which generate a form (with the Laravel Form Builder). This all works like a charm! For my project I need a custom form and a custom form field. After some puzzeling also a success, still no problem huray! Now I need a way to push a link to a list in my parent view.
parentview.blade.php
<div class="panel-body">
<ul class="wizard_steps">
#stack('category_steps')
</ul>
{!! form($form) !!}
</div>
customForm.blade.php
#push('category_steps')
<li>
<a href="#{{$options['real_name']}}">
<span class="step_no"></span>
<span class="step_descr">
<?php if ($showLabel && $options['label'] !== false && $options['label_show']): ?>
{{ $options['label'] }}
<?php endif; ?>
</span>
</a>
</li>
#endpush
<div id="#{{$options['real_name']}}">
{!! form_rest($options['field_form']) !!}
</div>
And here is the problem. The list item is not added to the stack in the parent.
Steps to reproduce
I've narrowed the problem down to {!! form($form) !!} that. So to reproduce:
make a file home.blade.php and paste text:
home.blade.php
<?php
/** #return string */
function test()
{
return view('test')->render();
}
?>
#stack('moreTest')
{!! test() !!}
now the file test.blade.php and paste text:
test.blade.php
#push('moreTest')
<p>This is not pushed</p>
#endpush
Anybody an idea how to fix this problem?
Thanks!
P.S.:Working with laravel 5.4.23

Laravel - passing data from master blade to partial doesn't work for all views

I am trying to pass data from my master blade to the partial depending where it is open. This is part of my master blade:
<div id="main-section">
#section('topBar')
#include('customer.layouts.partials.top-bar')
#show
#section('header')
#include('customer.layouts.partials.header')
#show
#section('carousel')
#include('customer.layouts.partials.carousel', ['function' => 'drawer'])
#show
</div>
<div id="drawer">
<div id="item-detail">
</div>
<div id="item-detail-carousel">
#section('carousel')
#include('customer.layouts.partials.carousel', ['function' => 'itemDetail'])
#show
</div>
</div>
So, as you can see I am using customer.layouts.partials.carousel in two places.
I am receiving data in my partial like this:
<div class="swiper-container {{ $function }}">
<div class="swiper-wrapper">
#foreach($issues as $issue)
<div class="swiper-slide">
<img
src="/imagecache/large/{{ $issue->first()->image }}"
onclick="{{ $function }}(
'{{ $issue->first()->magazine->id }}',
'{{ $issue->first()->magazine->name }}',
'{{ $issue->first()->magazine->summary ?: '' }}',
'{{ $issue->first()->magazine->image ?: '' }}',
'{{ $issue->first()->image }}'
)"
>
</div>
#endforeach
</div>
</div>
Div #drawer is hidden first, has display:none, and it is shown on click on an image in the slider in the main-section. And then #drawer gets slides over the main-section. But when I inspect the elements in the chrome I see that both in the main-section and in the drawer section, data that was passed is drawer. The #drawer didn't get data ['function' => 'drawer'] as I thought it would.
How can I achieve that?
I think you're misunderstanding how the #section directive is meant to work.
For starters, you shouldn't have multiple #section directives with the same name (think of it like ids with HTML - there should only be one with that name). Also, if your not going to be extending files with #extend there isn't much point in using #section at all.
If you remove the #section directives from around your #include('...') then they should work fine.
Hope this helps!

Categories