a widget is a reusable client-side code, which contains html, css, and js. this code includes minimal logic and is wrapped in a yii\base\widget object. we can easily insert and apply this object in any view.
step 1 − to see widgets in action, create an actiontestwidget function in the sitecontroller with the following code.
public function actiontestwidget() { 
   return $this->render('testwidget'); 
}
in the above example, we just returned a view called “testwidget”.
step 2 − now, inside the views/site folder, create a view file called testwidget.php.
<?php use yii\bootstrap\progress; ?> <?= progress::widget(['percent' => 60, 'label' => 'progress 60%']) ?>
step 3 − if you go to http://localhost:8080/index.php?r=site/test-widget, you will see the progress bar widget.
using widgets
to use a widget in a view, you should call the yii\base\widget::widget() function. this function takes a configuration array for initializing the widget. in the previous example, we inserted a progress bar with percent and labelled parameters of the configuration object.
some widgets take a block of content. it should be enclosed between yii\base\widget::begin() and yii\base\widget::end() functions. for example, the following widget displays a contact form −
<?php $form = activeform::begin(['id' => 'contact-form']); ?> 
   <?= $form->field($model, 'name') ?> 
   <?= $form->field($model, 'email') ?> 
   <?= $form->field($model, 'subject') ?> 
   <?= $form->field($model, 'body')->textarea(['rows' => 6]) ?> 
   <?= $form->field($model, 'verifycode')->widget(captcha::classname(), [ 
      'template' =>
         '<div class="row">
            <div class = "col-lg-3">{image}</div>
            <div class = "col-lg-6">{input}</div>
         </div>', 
   ]) ?> 
   <div class = "form-group"> 
      <?= html::submitbutton('submit', ['class' => 'btn btn-primary',
         'name' => 'contact-button']) ?> 
   </div> 
<?php activeform::end(); ?> 
creating widgets
to create a widget, you should extend from yii\base\widget. then you should override the yii\base\widget::init() and yii\base\widget::run() functions. the run() function should return the rendering result. the init() function should normalize the widget properties.
step 1 − create a components folder in the project root. inside that folder, create a file called firstwidget.php with the following code.
<?php 
   namespace app\components; 
   use yii\base\widget; 
   class firstwidget extends widget { 
      public $mes; 
      public function init() { 
         parent::init(); 
         if ($this->mes === null) { 
            $this->mes = 'first widget'; 
         } 
      }  
      public function run() { 
         return "<h1>$this->mes</h1>"; 
      } 
   } 
?>
step 2 − modify the testwidget view in the following way.
<?php use app\components\firstwidget; ?> <?= firstwidget∷widget() ?>
step 3 − go to http://localhost:8080/index.php?r=site/test-widget. you will see the following.
step 4 − to enclose the content between the begin() and end() calls, you should modify the firstwidget.php file.
<?php
   namespace app\components;
   use yii\base\widget;
   class firstwidget extends widget {
      public function init() {
         parent::init();
         ob_start();
      }
      public function run() {
         $content = ob_get_clean();
         return "<h1>$content</h1>";
      }
   }
?> 
step 5 − now h1 tags will surround all the content. notice that we use the ob_start() function to buffer the output. modify the testwidget view as given in the following code.
<?php use app\components\firstwidget; ?> <?php firstwidget::begin(); ?> first widget in h1 <?php firstwidget::end(); ?>
you will see the following output −
important points
widgets should −
be created following the mvc pattern. you should keep presentation layers in views and logic in widget classes.
be designed to be self-contained. the end developer should be able to design it into a view.