Yii2 Example: Create Yii2 Custom Widget - Basic Part

 ·  · 

A custom Yii2 widget class must be a subclass of yii\base\Widget, which should override the methods: yii\base\Widget::init() and/or yii\base\Widget::run().

The init method is used to initialize some properties of your customized widget.

The run method is the place where you return rendered view of your customized widget.

 

1 Create Widget Class

First of all, create a votewidget folder under your Yii2 app folder, for example:

$ cd frontend
$ mkdir votewidget

Then create a new PHP file named VoteWidget.php under the new folder votewidget.

<?php
// VoteWidget.php
namespace frontend\votewidget;

use yii\base\Widget;

class VoteWidget extends Widget
{
    public function init()
    {
        parent::init();
    }

    public function run()
    {
        return parent::run();
    }
}
?>

Your customized empty widget is ready now! You can use this widget in view file like this:

<?php
// Yii2 view file
use frontend\votewidget\VoteWidget;
?>

<?= VoteWidget::widget() ?>

Because there is no content echoed or returned in run method, nothing is rendered now.

 

2 Render Widget View

There are two ways to render widget view:

  • Return content enclosed within the begin() and end() methods of yii\base\Widget.
  • Directly echo or render a view template in run

2.1 Return Content Enclosed

To render the widget using enclosed content, we must use ob_start() and ob_get_clean() to capture the enclosed content in PHP's output buffer.

<?php
// VoteWidget.php
namespace frontend\votewidget;

use yii\base\Widget;

class VoteWidget extends Widget
{
    public function init()
    {
        parent::init();
        ob_start();
    }

    public function run()
    {
        $content = ob_get_clean();
        return $content;
    }
}
?>

Additionally, I'd like to render a up vote and a down vote icon using Font Awesome library. So register the library firstly in VoteWidget.php.

<?php
// VoteWidget.php
namespace frontend\votewidget;

use yii\base\Widget;

class VoteWidget extends Widget
{
    public function init()
    {
        parent::init();
        ob_start();
    }

    public function run()
    {
        $content = ob_get_clean();

        // register CSS file
        $fontawesome_url = 'https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css';
        $this->getView()->registerCssFile($fontawesome_url, [], 'VoteWidget-fontawesome');
        return $content;
    }
}
?>

Then just use the customized widget in your Yii2 view file and embed html content between the begin() and end() methods.

<?php
// Yii2 view file
use frontend\votewidget\VoteWidget;

// a faked model
$fakedModel = (object)['title'=> 'A Product', 'image' => 'http://placehold.it/350x150'];
?>

<?php VoteWidget::begin(); ?>
    <h4><?= $fakedModel->title ?></h4>
    <div>
        <img src="<?= $fakedModel->image ?>">
    </div>
    <div>
        <a class="up-vote"><i class="fa fa-thumbs-o-up"></i></a>
        &nbsp;&nbsp;&nbsp;&nbsp;
        <a class="down-vote"><i class="fa fa-thumbs-o-down"></i></a>
    </div>
<?php VotingWidget::end(); ?>

2.2 Directly Echo In run Method

Alternatively, the content of widget view can be echoed or returned in run method directly.

<?php
// VoteWidget.php
namespace frontend\votewidget;

use yii\base\Widget;

class VoteWidget extends Widget
{
    public $model;

    public function init()
    {
        parent::init();
    }

    public function run()
    {   
        // render title
        $html = '<h4>' . $this->model->title . '</h4>';

         // render image
        $html .= '<div>';
        $html .= '<img src="' . $this->model->image . '" />';
        $html .= '</div>';

         // render up and down icon
        $html .= '<div>';
        $html .= '<a class="up-vote"><i class="fa fa-thumbs-o-up"></i></a>';
        $html .= '&nbsp;&nbsp;&nbsp;&nbsp;';
        $html .= '<a class="down-vote"><i class="fa fa-thumbs-o-down"></i></a>';
        $html .= '</div>';

        // register fontawesome CSS
        $fontawesome_url = 'https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css';
        $this->getView()->registerCssFile($fontawesome_url, [], 'VoteWidget-fontawesome');

        // return html content for rendering
        return $html;
    }
}
?>

And it's quite simple to use in your Yii2 view.

<?php
use frontend\votewidget\VoteWidget;

// a faked model
$fakedModel = (object)['title'=> 'A Product', 'image' => 'http://placehold.it/350x150'];
?>

<?= VoteWidget::widget(['model' => $fakedModel]); ?>

That's all about the basic steps to create a customized Yii2 widget.