A view composer is exactly what you're looking for. A view composer allows you to tell your application do x when view y is rendered. For example when pages.buy is rendered anywhere in my application attach $articles
.
Let's say that you have a view that lists all of your articles and this view is included in various other views, that view is called "widgets.articles.recent".
View::composer('widgets.articles.recent', function ($view)
{
$articles = Article::all();
$view->with('all_articles', $articles);
});
Now whenever Laravel detects that you have requested the widgets.articles.recent
view it will look up all of the articles and attach them to the view as $all_articles
, within widgets.articles.recent
you can iterate through your articles without the need for the controller to know anything about the articles.
You can place your view composers anywhere in your application, for example in start.php
or even routes.php
if you're so inclined. app/composers
is a good place, eg: app/composers/article.php
. The full code might look like this:
app/composers/article.php:
View::composer('widget.articles.recent', function ($view)
{
$articles = Article::all();
$view->with('all_articles', $articles);
});
app/views/widgets/articles/recent.blade.php:
<div class="articles">
<ul>
@foreach ($articles as $article)
<li>{{ $article->title }}</li>
@endforeach
</lu>
</div>
app/views/home/index.blade.php
<div id="sidebar">
@include('widgets.articles.recent')
</div>
app/views/buy/index.blade.php
<div id="sidebar">
@include('widgets.articles.recent')
</div>
This might be a stupid question, but you said that: Let's say that you have a view that lists all of your articles and this view is included in various other views, that view is called "widget.articles.recent".
I'm not quite sure I understand what you mean. I created the composer file and called it articles.php, then what file should it route to for it to work properly? I tried with View::composer('pages.home', However, that does not work, and I think it's because I don't understand how the views are connected.
This is what currently loads my articles inside my views:
@foreach ($articles as $article)
<div class="column third">
<div class="article-item">
<span class="article-title"><h2>{{ $article->title }}</h2></span>
<span class="short-description"><p>{{ $article->description }}</p></span>
<p>{{ $article->price }}</p>
</div>
</div>
@endforeach
Thanks so far!
Ohh, I didnt see that you edited your answer! Now I definitely know how to do this! Thank you so much citrics, you are a huge help! :)
It doesn't seem to work. I created a file called articles.php and placed it inside app/composers. I then created a file called articles.blade.php and placed it inside a folder called widgets.
I added the following code to my articles.php file:
<?php
View::composer('widgets.articles', function ($view)
{
$articles = Article::all();
$view->with('all_articles', $articles);
});
In my articles.blade.php I have:
@foreach ($articles as $article)
{{ $article->title }}
{{ $article->description }}
{{ $article->price }}
@endforeach
And I then include this in my views:
@include('widgets.articles')
However I still get a Undefined variable: articles. Do I miss something here?
Sorry my mistake, I forgot to include the final step: you need to register the view composers with your application. To do this you can simply include the file directly into your start/global.php
file, at the very bottom add:
require app_path().'/composers/articles.php';
I tried all these methods you wrote above ,but still i get message:'Undefined variable : data ' in my home.blade.php , how to solve these problem ?
First paramater is path of file. If your template file is app/views/pages/index.blade.php, it should be pages.index. Also you can use wildcard to share data with all files under pages folder. Use pages.*
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community