Laravel: Passing data to default.blade.php from base controller
Asked Answered
P

2

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

Pronounce answered 16/4, 2013 at 9:4 Comment(4)
Do you want your tweets rendered in your layout, or always nested within the content?Boudicca
Either to be honest. I'm just rendering them in the view currently until I find a better/cleaner way of doing itPronounce
But you'd want to find a space in your layout for them instead? I'm asking because it will help me write the better answer for you :)Boudicca
That's right yes. Thanks Phil :)Pronounce
B
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');
    }

}
Boudicca answered 16/4, 2013 at 10:13 Comment(5)
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!Pronounce
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. CheersPronounce
Hi @Pronounce I completely forgot a step, you need to include the composers.php file, you can do this in application/start.phpBoudicca
Thanks Phill. I can't seem to see any includes already in start.php?Pronounce
I updated my answer, I realised there are not any includes in there already. Add at the bottom: include path('app').'composers.php';Boudicca
E
6
View::share('key', 'value');

in you view use (Blade syntax)

{{$key}}

or (PHP syntax)

echo $key;
Extraneous answered 16/4, 2013 at 9:34 Comment(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 variableBoudicca

© 2022 - 2024 — McMap. All rights reserved.