N
N
Nikolai Novosad2015-11-24 00:37:15
Yii
Nikolai Novosad, 2015-11-24 00:37:15

YII2 getting data from db in widget?

Hello.
To output and display data from the database in layouts main.php, as I understand it, you need to use widget.
Here is the simplest example of creating a widget:
New Widget

namespace app\components;

use yii\base\Widget;
use yii\helpers\Html;

class NewsWidget extends Widget
{
    public $message;

    public function init(){
        parent::init();
        if ($this->message === null){
            $this->message = 'News today';
        }
    }

    public function run(){
        return Html::encode($this->message);
    }
}

Displaying a Widget:
NewsWidget::widget(['message' => 'Good day']);
That's all there is to it. But to get and display data from the database?
Where to write request( init? )? How to properly pass the received data (return or render) ? How to display data in layouts?
Thanks in advance.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Andrew, 2015-11-24
@R0dger

Something strange... if I were you, I would do it a little differently... I would display cached news in the layout.
IMHO if the News is constantly on all pages .. IMHO it is better to cache and display, especially since this is not very critical information ..

L
link_irk, 2015-11-24
@link_irk

Use models. Widgets can also render view.

...
    public function run()
    {
        $model = News::find() -> limit(10) -> all();
        return $this -> render('news', ['news' => $model);
    }
...

Make a widget call in layout
<?php echo NewsWidget::widget(); ?>

M
matperez, 2015-11-24
@matperez

In widgets, it is better not to receive data at all, neither through models, nor through direct access to the database. Pass pure data there, as is done with breadcrumbs, for example, or at least some DataProvider that also hides the real data source.
I would override the yii\web\View class, add a news field to it to store a list of news, and explicitly pass it to the widget in the template. The data itself in the View can be customized in the controller, or if this data is needed everywhere, it can be done in the View class itself.
Something like this:

<?php
class NewsProvider 
{
    public function getNews()
    {
        return News::find()->all();
    }
}

class View extends yii\web\View 
{
    /**
     * @var NewsProvider
     */
    private $newsProvider;

    /**
     * @var array
     */
    private $news;
    
    public function __construct(NewsProvider $newsProvider, array $config = [])
    {
        $this->newsProvider = $newsProvider;
        parent::__construct($config);
    }
    
    public function getNews()
    {
        if (!$this->news) {
            $this->news = $this->newsProvider->getNews();
        }
        return $this->news;
    }
}

echo NewsWidget::widget(['items' => $this->getNews()]);

You need to create your own View class. Under no circumstances should you make changes to the vendor folder, this is not your code.
For example, you can create the app\components\View class and connect it in the config (make Yii use this class for the view component)
// в файле config/web.php 
  'components' => [
    'view' => 'app\components\web\View',
  ],

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question