Laravel: 从基础控制器向default.blade.php传递数据

5
我有一个基础控制器,其中包含一种方法来向我的视图返回 Twitter 消息源。
我想将其从页面视图中移动到默认的 blade 视图中,以减少冗余,因为它将在整个站点上显示。如何从基础控制器传递数据到 blade?
我可以通过以下方式从页面控制器将其发送到视图:
public function get_index()
{
    ..................
    $this->layout->nest('content', 'home.index', array(
        'tweets' => $this->get_tweet()
    ));
}

然后在视图中,像这样输出:

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

我希望能够在default.blade.php和我的Base_Controller中完成所有这些操作:
<?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;
    }
}

这怎么可能实现呢?

//////////////////////更新/////////////////////////////

应用程序/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
        ));
    }
}

出现了错误:

未定义变量:tweets


你想要你的推文呈现在你的布局中,还是始终嵌套在内容中? - Phill Sparks
说实话,目前我只是在视图中呈现它们,直到我找到更好/更清洁的方法为止。 - Fraser
但是您想在布局中为它们找到一个空间吗?我问这个问题是因为它会帮助我更好地为您撰写答案 :) - Phill Sparks
没错,是的。谢谢Phil :) - Fraser
2个回答

12

步骤1 - 创建一个专门用于你的推文的视图,将其命名为widgets/tweets.blade.php,该视图将接受你的$tweets数据。如果你想要更好的性能表现,这样做可以很容易地将推文视图缓存起来。我们还需要一个模型来为你生成推文数据。

步骤2 - 将推文数据传递到你的推文视图中,我们可以使用视图组件(View Composer)来实现,以便逻辑与(但不属于)视图保持一致。

步骤3 - 创建你的默认布局,将其命名为layout/default.blade.php。它将接受$content$tweets。我们将使用另一个视图组件(View Composer)嵌套推文视图。你可以在控制器操作中嵌套$content

步骤4 - 在Base_Controller上设置$layout

步骤5 - 利润!

注意 - 如果这是你的第一个视图组件,则需要在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');
    }

}

太棒了。非常感谢您抽出时间来做这件事。我非常感激。我最近才开始接触Laravel,但我很喜欢它! - Fraser
嗨,再次感谢您的帮助。我尝试了实现它,但却从default.blade中得到了未定义的变量:tweets。有什么想法吗?我已经在上面更新了我的代码。谢谢。 - Fraser
嗨@Fraser,我完全忘记了一步,你需要包含composers.php文件,你可以在application/start.php中完成这个步骤。 - Phill Sparks
谢谢Phill。我似乎在start.php中没有看到任何包含文件? - Fraser
我更新了我的答案,我意识到里面没有任何包含。在底部添加:include path('app').'composers.php'; - Phill Sparks

6
View::share('key', 'value');

在你的视图中使用(Blade语法)

{{$key}}

或者(PHP语法)
echo $key;

1
不要总是依赖于View::share() - 它对于某些事情来说是一个很好的解决方案,但在许多情况下它和全局变量一样糟糕。 - Phill Sparks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接