5

I have a base controller with a method to return a twitter feed to my view.

I want to move this in the view from the page view to the default blade to reduce redundancy as it will be appearing site wide. How do I pass data from the base controller to blade?

I can send it to my view from the page controller like so:

public function get_index()
{
    ..................
    $this->layout->nest('content', 'home.index', array(
        'tweets' => $this->get_tweet()
    ));
}

and in the view, output it like this:

if ($tweets)
{
    foreach ($tweets as $tweet)
    {
        ..............

I want to do all this from within default.blade.php and my Base_Contoller:

<?php
class Base_Controller extends Controller {
    /**
     * Catch-all method for requests that can't be matched.
     *
     * @param  string    $method
     * @param  array     $parameters
     * @return Response
     */
    public function __call($method, $parameters)
    {
        return Response::error('404');
    }

    public function get_tweet()
    {
        ...........
        return $tweets;
    }
}

How is this possible?

//////////////////////UPDATE/////////////////////////////

application/models/tweets.php

<?php
class Tweets {
    public static function get($count = 3)
    {
        Autoloader::map(array(
        'tmhOAuth'     => path('app').
                'libraries/tmhOAuth-master/tmhOAuth.php',
            'tmhUtilities' => path('app').
                'libraries/tmhOAuth-master/tmhUtilities.php'
        ));
        $tmhOAuth = new tmhOAuth(array(
            'consumer_key'        => 'xxx',
            'consumer_secret'     => 'xxx',
            'user_token'          => 'xxxxx',
            'user_secret'         => 'xxxxx',
            'curl_ssl_verifypeer' => false
        ));
        $code = $tmhOAuth->request('GET',
        $tmhOAuth->url('1.1/statuses/user_timeline'), array(
            'screen_name' => 'xxx',
            'count' => $count
        ));
        $response = $tmhOAuth->response['response'];
        $tweets = json_decode($response, true);
        return $tweets;
    }
}

application/views/widgets/tweets.blade.php

@foreach ($tweets)
    test
@endforeach

application/views/layouts/default.blade.php

....
{{ $tweets }}
....

application/composers.php

<?php
View::composer('widgets.tweets', function($view)
{
    $view->tweets = Tweets::get();
});
View::composer('layouts.default', function($view)
{
    $view->nest('tweets', 'widgets.tweets');
});

application/controllers/base.php

<?php
class Base_Controller extends Controller {

    /**
     * Catch-all method for requests that can't be matched.
     *
     * @param  string    $method
     * @param  array     $parameters
     * @return Response
     */
    public $layout = 'layouts.default';

    public function __call($method, $parameters)
    {
        return Response::error('404');

    }

}

application/controllers/home.php

<?php
class Home_Controller extends Base_Controller {

    public $layout = 'layouts.default';

    public $restful = true; 

    public function get_index()
    {
        Asset::add('modernizr', 'js/thirdparty/modernizr.js');
        Asset::add('jquery',
            'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');
        Asset::add('scripts', 'js/scripts.js');

        $this->layout->title = 'title';
        $this->layout->nest('content', 'home.index', array(
            //'data' => $some_data
        ));
    }
}

Is giving me an

Undefined variable: tweets

error

Fraser
  • 14,036
  • 22
  • 73
  • 118

2 Answers2

12

Step 1 - Make a view just for your tweets, let's call it widgets/tweets.blade.php, that will accept your $tweets data. This makes it very easy to cache the tweets view in the future if you want a little more performance. We also want a model that will generate the tweet data for you.

Step 2 - Pass the tweet data into your tweets view, let's use a View Composer for this so the logic is kept with (but outside) the view.

Step 3 - Create your default layout, let's call this layout/default.blade.php. This will accept $content and $tweets. We'll nest the tweets view with another View Composer. You can nest the $content in your controller actions.

Step 4 - Set the $layout on your Base_Controller.

Step 5 - Profit!

Note - If these are your first view composers then you'll need to include them in application/start.php


// application/models/tweets.php
class Tweets {
    public static function get($count = 5)
    {
        // get your tweets and return them
    }
}

// application/views/widgets/tweets.blade.php
@foreach ($tweets)
    {{-- do something with your tweets --}}
@endforeach

// application/views/layouts/default.blade.php
<section class="main">{{ isset($content) ? $content : '' }}</section>
<aside class="widget widget-tweets">{{ $tweets }}</aside>

// application/composers.php
View::composer('widgets.tweets', function($view)
{
    $view->tweets = Tweets::get();
});
View::composer('layouts.default', function($view)
{
    $view->nest('tweets', 'widgets.tweets');
});

// application/start.php (at the bottom)
include path('app').'composers.php';

// application/controllers/base.php
class Base_Controller extends Controller {
    public $layout = 'layouts.default';
}

// application/controllers/home.php
class Home_Controller extends Base_Controller {

    public $restful = true;

    public function get_index()
    {
        $this->layout->nest('content', 'home.welcome');
    }

}
Phill Sparks
  • 20,000
  • 3
  • 33
  • 46
  • Awesome. Thank you very much for taking the time on this. It's very much appreciated. I've only recently started out on Laravel but loving it! – Fraser Apr 16 '13 at 10:44
  • Hi,Thanks again for the above. I've tried implementing it but am getting undefined variable:tweets from default.blade. Any ideas? I've updated my post above with my code. Cheers – Fraser Apr 16 '13 at 12:56
  • Hi @Fraser I completely forgot a step, you need to include the composers.php file, you can do this in `application/start.php` – Phill Sparks Apr 16 '13 at 12:58
  • Thanks Phill. I can't seem to see any includes already in start.php? – Fraser Apr 16 '13 at 13:04
  • I updated my answer, I realised there are not any includes in there already. Add at the bottom: `include path('app').'composers.php';` – Phill Sparks Apr 16 '13 at 13:06
6
View::share('key', 'value');

in you view use (Blade syntax)

{{$key}}

or (PHP syntax)

echo $key;
Muhammad Usman
  • 12,439
  • 6
  • 36
  • 59
  • 1
    Don't always fall back on `View::share()` - it's a great solution for some things but in many cases it's as bad as a [global variable](http://c2.com/cgi/wiki?GlobalVariablesAreBad) – Phill Sparks Apr 16 '13 at 09:36