2015-01-25 5 views
8

Ich habe ein einfaches Widget in meinem aktuellen Projekt gemacht. Es erstellt einfach eine Auswahlliste für alle jui-Themen und ermöglicht es dem Benutzer, das Thema zu ändern und es mithilfe von Cookies zu speichern.So erstellen Sie ein wiederverwendbares Widget in Yii2

Dieses Widget benötigt zwei Javascript-Dateien, - sie sind in run() registriert - einer von ihnen ist die Jquery Cookies Plugin. Ich frage nach dem Wesen des Weges, um die Integrität dieses Widgets und seiner js-Dateien zu bewahren, um es einfach zu machen, in anderen Yii2-Projekten wiederverwendet zu werden, ohne dafür alle notwendigen js-Dateien kopieren zu müssen.

<?php 
namespace common\libs; 

use yii; 
use yii\base\Widget; 
use yii\web\View; 
use yii\web\JqueryAsset; 
/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 

/** 
* Description of JuiThemeSelectWidget 
* 
* @author Said Bakr 
*/ 
class JuiThemeSelectWidget extends Widget 
{ 
    private $list; 
    private $script; 
    private static $juiThemeSelectId = 'JuiThemesList'; 
    public $themeListId; 
    public $label; 
    public function init() { 
    parent::init(); 
    if ($this->themeListId) self::$juiThemeSelectId = $this->themeListId; 
    $this->list = $this->createSelectList($this->getThemesList()); 
    $this->makeScript(); 
    } 
    public static function getThemesList() 
    { 
    $themesPath = dirname(Yii::$app->basePath).DIRECTORY_SEPARATOR."vendor".DIRECTORY_SEPARATOR."bower".DIRECTORY_SEPARATOR."jquery-ui".DIRECTORY_SEPARATOR."themes"; 
    $output = []; 
    foreach (scandir($themesPath) as $item){ 
     if (is_dir($themesPath.DIRECTORY_SEPARATOR.$item) && ($item != '.' && $item !='..')) $output[] = $item; 
    } 
    return $output; 
    } 

    public static function createSelectList($items) 
    { 
    $juiThemeSelectId = self::$juiThemeSelectId;  
    $output = ''; 
    $output .= "<select id=\"$juiThemeSelectId\">"."\n"; 
    foreach ($items as $item){ 
     $output .= "<option value='$item'>$item</option>\n"; 
    } 
    $output .= "</select>\n"; 
    return $output; 
    } 

    /** 
    * Making the client-side script for the list */ 

    private function makeScript() 
    { 

    $t = self::$juiThemeSelectId; 
    $this->script = <<<EOD 

<script> 
    var juiThemeSelectId = "$t" 
</script>   
EOD; 

    } 
    public function run() { 
    parent::run(); 
    $this->getView()->registerJsFile('/myjs/jquery.cookie.js', ['depends' => [JqueryAsset::className()]]); 
    $this->getView()->registerJsFile('/myjs/JuiThemeSelect.js', ['depends' => [JqueryAsset::className()]]); 
    return "$this->label $this->list \n $this->script"; 
    } 
} 
+0

In diesem Fall denke ich, Sie sollten es einfach auf GitHub/Bitbucket als Erweiterung veröffentlichen. – arogachev

+0

@arogachev Konnte es nicht lokal gemacht werden? Gibt es eine Möglichkeit, den Komponisten dazu zu bringen, es lokal zu produzieren? – SaidbakR

+1

Vielleicht Satis ist eine Option https://github.com/composer/satis. – arogachev

Antwort

11

Endlich habe ich die Lösung gefunden. Es kommt auf Yii2 Extensions und AssetBundles an. Die Geschichte ist einfach, machen Sie einfach alle Dateien in einem Ordner in einem der Standard-Yii2-Ordner, zum Beispiel: common, vendor.- Übrigens, Anbieter ist in beiden grundlegenden und erweiterten yii2 Anwendung Vorlage gefunden.

Zusätzlich zu allen Dateien, d. H. für meinen Fall, die Widget-Klasse PHP-Datei und die Javascripts-Dateien, müssen Sie YourWidgetNameAsset PHP-Klasse-Datei erstellen. Tatsächlich liegt der Hauptschlüssel der Lösung in dieser Klasse.

Mein Fall

Ich habe ein Widget JuiThemeSelectWidget Ich legte es in einem Ordner mit dem Namen saidbakr unter vendor Verzeichnis, so haben wir vendor\saidbakr Namespace benannt. Dieser Ordner enthält die folgenden vier Dateien:

  1. JuiThemeSelectWidget.php
  2. JuiThemeSelectAsset.php
  3. JuiThemeSelect.js
  4. jquery.cookie.js

Die Dateinummer 3 auf der abhängig Dateinummer 4 zum Erstellen von Cookies, um die letzte Benutzerauswahl zu speichern. Jetzt

können wir den Code der Datei Nummer 2 JuiThemeSelectAsset.php siehe:

<?php 
namespace vendor\saidbakr; 
use yii\web\AssetBundle; 

/* 
* It is free for use and modify with one simple rule: 
* regarding credits for the author either it modified or not 
* Author: Said Bakr. [email protected] 
* http://2index.net 
*/ 

/** 
* Description of Kabb 
* 
* @author Said 
*/ 
class JuiThemeSelectAsset extends AssetBundle 
{ 
    public $sourcePath = '@vendor/saidbakr'; 

    public $autoGenerate = true; 
    /** 
    * @inheritdoc 
    */ 
    public $js = ['jquery.cookie.js','JuiThemeSelect.js']; 
    public $depends = [ 
     'yii\jui\JuiAsset', 
    ]; 
} 

Hier definiert man AssetBundle für das Widget etwas ähnliches wie in this official source beschrieben.

Jetzt werden wir einen Blick auf die Header der Widget-Klasse nehmen sich selbst und seine run() Methode:

<?php 
namespace vendor\saidbakr; 

use yii; 
use yii\base\Widget; 
//use yii\web\View; 
//use yii\web\JqueryAsset; 
class JuiThemeSelectWidget extends Widget 
{ 
    // ...... Class code.... 

public function run() { 
    parent::run(); 
    JuiThemeSelectAsset::register($this->getView());  
    return "$this->label $this->list \n $this->script"; 
    } 
} 

Es ist klar, dass wir das Asset-Bündel verwendet, wie in this link beschrieben, aber hier haben wir $this->getView() statt $this, weil die Methode nicht aus einer Sicht aufgerufen wird.

Ich habe den Ordner mit dem Namen komprimiert saidbakr und hochgeladen es this location oder Kasse diese GitHub Repository, zu überprüfen, was habe ich gemacht, was sein Name ist Yii2 Erweiterung.Entpacken Sie einfach den Inhalt des Archivs in den Ordner mit dem Namen saybakr direkt unter Herstellerordner, So muss die Dateistruktur `vendor \ saidbakr '(die vier Dateien in der Liste oben betrachtet), und verwenden Sie das Widget in Ihren Ansichten etwa wie folgt :

<?php 
use yii\helpers\Html; 
use yii\widgets\ActiveForm; 
use yii\jui\DatePicker; 
use vendor\saidbakr\JuiThemeSelectWidget; 
?> 
<div> 
<?= JuiThemeSelectWidget::widget(['label' => 'Select New JUI Theme', 'themeListId' => 'fox']) ;?> 
<div class="profile-form"> 
</div> 
<h2>Testing Elements for the JUI</h2> 
<form> 
<select id="sel"> 
<option value="1">One</option> 
<option value="2">Two</option> 
<option value="3">Three</option> 
</select> 
</form> 
<?php $this->registerJs("$('#sel').selectmenu();") ;?> 
1

Widget hinzufügen in yii2 Komponenten erstellen Ordner im root directory.then pHP-Datei erstellen. Verwenden Sie Namespacekomponenten in dieser Datei (Namespace app \ components). enthalten Widget (verwenden Sie App \ Base \ Widget). Klasse erstellen, die die Widget-Klasse Namespace app \ components erweitert; Verwenden Sie yii \ base \ Widget; Erstellen Sie einen View-Ordner, der View-File-Aufrufe vom Widget enthält.