Pass data to included blade view - laravel

Let's say that I have the following main view:
<div>
<div>
#yield('content')
</div>
<div>
#include('sidebar')
</div>
<div>
#include('footer')
</div>
</div>
How would I make sure that the included views have their own data? For example, in the sidebar I want to display, let's say, new blog post comments. In the footer I want to display new users and blog posts. Maybe using #include is not the right way to accomplish this?

In your applications, app service providers boot method do something like
View::composer('sidebar',function($view){
$comments= Blog::latest()->comments;
$view->with('comments',$comments);
})
View::composer('footer',function($view){
$users= User::latest();
$view->with('users',$users);
})
//sidebar
Then in the view file do something like
#foreach($comments as $comment)
{{$comment->data}}
#endforeach`

You may want to use View Composers in such case.

Write your logic in View Composer then call it using a service provider, in the boot method
View::composer(
['partials.content', 'partials.sidebar', 'partials.footer], 'App\Http\ViewComposers\MyViewComposer'
);

I'm tried this and it's working with me :
#include('content',array("key"=>"value"))

Related

Laravel 5.6 - Code In view - best practice

I am new to the Laravel framework and I am finding that on many of my views, I need to have similar code as seen below. I am sure this is not best practice. Can someone advise me what would be the best practice approach on this?
<?php
use App\Song;
use App\Music;
$songArtist = Song::find('5b0a6a779a892025b869f552')->Artists()->get();
?>
<div class="form-group row">
...
</div>
I could then use the $songArtist variable... Note, I am using MongoDB on the backend.
You should read on the MVC or Model-View-Controller architecture. There are many arguments as to whether Laravel is an MVC Framework or not, but in this case, let's assume that it uses the said architecture.
The way you pull the data/logic is normally handled by the model. The controller will be handling the way the data will be transported into the view (html). Lastly, the view will serve as the user-interface. This should make your code cleaner and organized.
A typical example would be like this:
Controller
use App\Song;
use App\Music;
function getArtist()
{
$songArtist = Song::find('5b0a6a779a892025b869f552')->Artists()->get();
return view('myhtml')->with('songArtist', $songArtist);
}
View
<div class="form-group row">
<p> {{ $songArtist}} </p>
</div>

Is it recommended to make general partials for modals, drop-downs etc in Laravel Blade?

I am looking for a very general way to include bootstrap components in my blade view. For example let's say I need a drop down in my view, should I make a partial called dropdown.blade.php with code as follows:
<div class="dropdown">
<a href="#" class="dropdown-toggle" type="button" data-toggle="dropdown">
<span class="glyphicon glyphicon-chevron-down"></span></a>
<ul class="dropdown-menu">
#foreach ($options as $option)
<li>{{$option["name"]}}</li>
#endforeach
</ul>
</div>
and use it in my view in the following way:
#include('partials.dropdown',
array("options"=>array(
["href"=>"#", "name"=>"Profile"],
["href"=>"#", "name"=>"Report"],
)))
Even we can make it more generic by adding options for button name etc. Is it a good or preferable way to do it or should we use copy-paste method from bootstrap website to our views every time? Is there any package that is doing this sort of work? Can we make it in more elegant way?
This seems like a good idea if you are going to re-use the component a lot. I think the more elegant way to do it would be to create custom blade directives:
https://laravel.com/docs/master/blade#extending-blade
Then you could do, for instance:
#dropdown($options, 'btn-primary')
I would also provide an argument for a custom element ID or name, so you can reference it elsewhere on the page as needed.
This gets a little more complex with things like modals. I think you'd want to register multiple blade directives so you could do something like
#startmodal
#modaltitle('Title')
#startmodalbody
Some body content
#endmodalbody
#endmodal

Undefined variable in a child view

i have created a master layout and extending it to a child view this way:
master.blade.php (short version):
<body>
#section('content')
#foreach($articles as $article)
{{ $article->title }}
#endforeach
#show
</body>
Then a child view called child.blade.php:
#extends('master')
#section('content')
<p>Some static content</p>
#stop
However, when i am visiting a page with child.blade.php i am getting an error:
Undefined variable: articles (View: /app/views/master.blade.php)
Why am i getting this error? I don't have this variable in my child.blade.php, so i guess - child view inherits master's variables by default? But why? I didn't used #parent
What you really want is View Composer. This way you can share the data between several views without repeating yourself. In your case whenever your child.blade.php view will be rendered additional data you want to pass will be added.
Read more at docs: View Composers
If you don't want to use View composer you need to pass the articles to your child.balde.php

Blade: extending a template in multiple subviews

I am using Blade to include multiple sub-views into a single set of tabs in a blade app. All of the sub-views have the same overall structure (a sidebar and a main section). Because of this, I have created a template and each sub-view extends the template. Here is the structure:
Main.blade.php
<div id="tabs">
<ul>
#foreach($views as $view)
<li>{{$view}}</li>
#endforeach
</ul>
#foreach($views as $view)
<div id="{{$view}}">
#include($view)
</div>
#endforeach
</div>
template.blade.php
{{-- formatting stuff --}}
#yield('content 1')
{{-- more formatting stuff --}}
#yield('content-2')
{{-- more formatting stuff --}}
tab-*.blade.php
#extends('template')
#section('content-1')
This is tab [whatever number]
#stop
#section('content-2')
Lorem Ipsum
#stop
The obvious problem here is that, as each sub-view extends the same template, the #yield('content') exists 3 times, and all 3 included sub-views have their own #section('content'). What appears to be happening is that the first sub-view's implementation of the content section is getting placed in all 3 yields.
My intent here is obvious. I want each included sub-view to implement it's own instance of the template, place it's content in the content section, THEN get pulled into the main page. Can this be done?
If I flatten the tab-*.blade.php files and stop using the template, it works fine. The problem here is that I end up with a lot of code repetition that would be better placed in a template. This is an emergency option, but I'd like to do it the "proper" way.
NOTE
I have tried to redesign this to avoid the problem, but I really can't come up with another solution. While #include is typically used to pull in small, static pieces (a header, a footer, etc.), I have not read anything that states this as a restriction. It seems to me that the best approach is to store each view once and pull them into the main page when needed, so that's how I've designed it.
Try using the #overwrite command instead of #stop
Example:
#extends('template')
#section('content-1')
Stuff goes here...
#overwrite
#section('content-2')
More stuff goes here...
#overwrite
Source: https://github.com/laravel/framework/issues/1058#issuecomment-17194530
I came up with a hack that seems to work. In template.blade.php, I use the following:
{{-- formatting stuff --}}
#yield(isset($tab) ? "content-1-$tab" : 'content-1')
{{-- more formatting stuff --}}
#yield(isset($tab) ? "content-2-$tab" : 'content-2')
{{-- more formatting stuff --}}
Then, in main.blade.php, I execute #include('view', ['tab'=>$view]). This seems to cause each instance of content-1 and content-2 do be named distinctly, allowing the 2 subviews to implement the sections separately. This also should allow any other views that implement this template to continue to function without having to change anything.

Poedit translations are not translated when using angular ng-include

I want to have my text translated and I am using poedit to translate my text.
I am working in ZF2.
I do have my translation file (created with poedit) in place. And that is working.
For example: in this view example the "Sign in" is translated.
(1) {{'Sign in' | trans}}
No I want to add the login view with ng-include, like this:
(2) <div ng-include="'/account/login'"></div>
That works fine too, my login view is there.
But: none of the translations do work in this view. In the login view, this:
(3) <span>{{ 'Password' | trans }}</span>
is not translated. If I add that (3) code however directly after (1), the translation works.
My Question is: how can I ensure that the translations do work when I use a ng-include to add other views?
Hope my question makes sense and that someone knows what to do.
Thanks!
I found a way to solve this.. I think one of the solution is for example:
<div ng-controller="LoginCtrl">
<span>{{ Password }}</span>
</div>
and then on your LoginCtrl should look like this:
app.controller('LoginCtrl', ['$scope', '$translate', function ($scope, $translate) {
// expose translation via `$translate` service
$translate('Password').then(function (password) {
$scope.Password = password;
});
}]);
you may go to this article for more info http://angular-translate.github.io/docs/#/guide/03_using-translate-service#using-$translate-service_things-to-keep-in-mind

Resources