I'm using Blade templates in Laravel 5.3. I want to render two lists - one of 'friends' and one of 'acquaintances'. The header and footer of the list is the same in both cases, but items rendered in the friends list have different formatting and fields from those rendered in the acquaintances list.
Here are two methods in my controller:
public function showFriends() {
return view('reports.friends', ['profiles' => $friends]);
}
public function showAcquaintances() {
return view('reports.acquaintances', ['profiles' => $acquaintances']);
}
Here are my blade templates:
// reports/acquaintances.blade.php
<div>Some generic header HTML</div>
<div class="container">
#each('reports.acquaintance', $profiles, 'profile')
</div>
<div>Some generic footer HTML</div>
// reports/acquaintance.blade.php
<div class="media">
<div>Some HTML formatting specific to acquaintance item</div>
{{ $profile->name }}
{{ $profile->job }}
</div>
// reports/friends.blade.php
<div>Some generic header HTML</div>
<div class="container">
#each('reports.friend', $profile, 'profile')
</div>
<div>Some generic footer HTML</div>
// reports/friend.blade.php
<div class="media">
<div>Some HTML formatting specific to friend item</div>
{{ $profile->name }}
{{ $profile->birthday }}
</div>
This doesn't seem to be a very efficient way to achieve what I want because the I've had to create two identical parent templates for my lists: friends.blade.php and acquaintances.blade.php. What I really need is the ability to have a generic parent template and then somehow to specify in my controller which template I want to use to render the list items. Is this possible? Is there another, more elegant way to implement this? I'm just starting to get my head around Blade and any pointers would be very appreciated.
You could break it into a generic persons_list and two custom items. Then use a conditional inside of the list:
public function showFriends() {
return view('reports.persons_list', ['profiles' => $friends, 'type' => 'friends']);
}
public function showAcquaintances() {
return view('reports.persons_list', ['profiles' => $acquaintances, 'type' => 'acquaintances']);
}
And blade:
// reports/persons_list.blade.php
<div>Some generic header HTML</div>
<div class="container">
#if ($type == 'friends')
#each('reports.friend', $profiles, 'profile')
#else
#each('reports.acquaintance', $profiles, 'profile')
#endif
</div>
<div>Some generic footer HTML</div>
Related
Is it possible to output to the same view from multiple controllers. I have one view called 'dashboard'. I have two variables: $users and $friends. I want to send data to these variables from different controllers. Do I need to add two controllers to the same route?
The view:
<div class="panel friendlist" id="friendlist">
<div class="panel-heading"><h3 class="panel-title">Result List</h3>
</div>
<div class="panel-body">
<ul class="list-group">
#foreach($friends as $friend)
<li class="list-group-item">{{ $friend->username }}
</li>
#endforeach
</ul>
</div>
</div>
</section>
<section class="row posts">
<div class="col-md-6 col-md-3-offset">
<header><h3>other posts</h3></header>
#foreach($posts as $post)
<article class="post">
<p>{{ $post->content }}</p>
<div class="info">Posted by {{ $post->user->username }} on {{ $post->created_at }}</div>
The post controller:
public function getDashboard()
{
$posts = Post::orderBy('created_at','desc')->get();
return view('dashboard',['posts' => $posts]);
}
The friend controller:
public function getFriends()
{
$friends = Auth::user()->friends()->where('status','accepted')->get();
return view('dashboard',['friends' => $friends]);
}
Current route:
Route::get('/dashboard',[
'uses' => 'PostController#getDashboard',
'as' => 'dashboard',
'middleware' => 'auth'
]);
#Amartya Barua, you can use view composer to share some variables to multiple views https://laravel.com/docs/5.8/views, Or you can create BaseService, and write reusable getters and inject BaseService to your controller, in this way you can able to access required getters to your Controller, if any question comment my answer
Simple thing you can do is
First create one Model and in this model create two functions for this two variable values.
In Controller where you want to use dashboard as view add model to your controller and simply pass call function of that model and pass this function values to view.
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!
I want to nest divs in a loop like this
<div>
Content
<div>
Content
<div>
Content
</div>
</div>
</div>
I am thinking of recursion but I am not sure how to implement it in blade.
You can use include to call the nested content in Blade:
example.blade.php:
<div>
{{ $content->data }}
#if ($content->hasNestedData())
#include('viewfolder.example', $content->nestedContent)
#endif
</div>
To check for nested content, you could implement a function in your model like this:
public function hasNestedData()
{
return $this->nestedContent !== null;
}
And set the nested content as an attribute, for example:
public function nestedContent()
{
return $this->belongsTo(Content::class, 'nested_content_id');
}
As you didn't post the code you already have, use this as the main idea.
I have a <h1> tag in my template blade, its duplicate in all pages of my website. I want to do a condition if the page is Homepage then use this <h1> else don't write it.
This is my header code
<div class="col-sm-7">
<div class="slogan">
<h1 id="h1" class="tlt">my h1 Tag</h1>
<span id="span" class="tlt">" {{$slogan[0]->text}} "</span>
</div>
</div>
Thanks
You can use Request::is('/'), given that the "homepage" is on this url. The is() method can also accept wildcards which can be useful for stuff like Request::is('admin/*');.
If you have a route name for your routes, you can do like this in your view:
Route:
Route::get('/', ['as'=>'home', 'uses'=>'HomeController#index']);
In view:
#if(request()->route()->getName() == 'home')
// <h1> Text for home page </h1>
#else
//text for other pages.
#endif
I'm using Laravel 4.2 and I have multiple bootstrap boxes on my page. I would like to put those in a file that I can include along with some arguments that will be inserted into it, so I don't need to repeat the same code for the boxes every time.
Controller
$box_options = array(
'icon_classes' => 'fa fa-pie-chart',
'box_title' => 'Browser Usage',
'box_footer_text' => 'View More Visitor Data'
);
return View::make('index')->with('box_options', $box_options);
box.blade.php (Include File)
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">
<i class="{{ $icon_classes }}"></i> {{ $box_title }}
</h3>
</div><!-- /.box-header -->
<div class="box-body">
<div class="row">
#include('includes.global.pie_chart', $browser_usage_pie_chart_options)
</div><!-- /.row -->
</div><!-- /.box-body -->
#if($box_footer_text)
<div class="box-footer text-center">
{{ $box_footer_text }}
</div><!-- /.box-footer -->
#endif
</div><!-- /.box -->
I need the contents of the box body to be dynamic, so it could be either a string or another include file or a combination of both of them. If it was only a string, I could easily pass it in with the controller as I have with the other variables, but I need it to be able to place an include file there as well, except that it could a number of different include files.
How can I pass an include as an argument for another include? Or is there another completely different way to do this that I haven't considered?
An #include() is like a php include ""; so the scope of the variables don't change, you can acces the variables of box.blade.php in includes.global.pie_chart without passing it.
because the scope doesn't change, you can do:
return view('box', "browser_usage_pie_chart_options" => $browser_usage_pie_chart_options):
in your view box.blade.php have:
#include('includes.global.pie_chart')
and in includes.global.pie_chart call it like:
{{ $browser_usage_pie_chart_options }}
i recomend if your includes are used many times and sometimes the variable doesn't exist, before print it check if exist #if(isset($browser_usage_pie_chart_options))
like this
#include("part.dateTemplate",["name" => "pr_date"])
// dateTemplate
{{ $name }} // pr_date