Pada tulisan ini saya akan membuat series mengenai pemrograman dengan Yii Framework. Series ini akan disusun untuk membuat sebuah program sederhana yang memanfaatkan fitur-fitur umum yang sangat mungkin digunakan di banyak kasus. Tulisan ini akan menggunakan Basic Template Yii2 (yang menurut saya penggunaannya sedikit lebih sulit daripada advance template Yii2)

Secara garis besar (dan mungkin akan bertambah sesuai keperluan yang mungkin terjadi) outline dari seri tulisan ini akan terdiri dari hal berikut.

  1. Prainstalasi
  2. Instalasi YiiFramework 2.0
  3. Login
  4. Login dengan Database pada Yii2
  5. Bekerja dengan Gii
  6. Module pada Yii2
  7. Layout dasar dan Manipulasinya pada Yii2
  8. Costum Asset dan Asset Bundle pada Yii2
  9. Alias pada Yii2
  10. Bekerja dengan Form
  11. Timestamp, Blameable, dan Sluggable Behavior pada Yii2
  12. Menggunakan Rich Text Input CkEditor dan Alternatifnya pada Yii2
  13. Gridview dan Listview
  14. SEO Friendly Url dengan slug
  15. Scenario pada Model Yii2
  16. Retrieve data pada Yii2
  17. Relasi Database pada Yii2
  18. Widget Kartik
  19. Select2 dengan Kartik Ekstension
  20. Dependent Dropdown pada Yii2
  21. Bekerja dengan Modals
  22. Membuat Costum Template untuk Gii
  23. Mengupload File
  24. Mengupload File dengan Kartik Widget
  25. Gridview atau Datatables?
  26. Session dan Cookie pada Yii2
  27. Menggunakan AdminLTE pada Yii2
  28. Membuat Themes pada Yii2
  29. Menggunakan GoogleMaps API pada Yii2
  30. Menggunakan Socket.io pada Yii2
  31. Handling Error
  32. Bekerja dengan AuthClient
  33. Menggunakan Amazon S3 pada Yii2
  34. Mengirim Email dengan Swiftmailer pada Yii2
  35. Middleware pada Yii2
  36. Mengenal RBAC pada Yii2
  37. Implementasi RBAC pada Yii2
  38. Notifikasi Real Time dengan Socket.io pada Yii2

Anda dapat mengunduh dan memantau progress dari series ini lewat repositori Github belajararief-yii2series. Silahkan bintangi (star) untuk dapat lebih mudah memantau perkembangan repositori.

Requirement

Untuk memudahkan anda dalam memahami petunjuk ini, maka beberapa hal yang perlu diperhatikan diantaranya:

  1. Sistem Operasi yang saya gunakan adalah Windows 10 64bit dengan terminal menggunakan powershell terminal (beberapa command seperti cd dapat berbeda dengan command prompt biasa), namun saya akan berusaha sebisa mungkin mencontohkan perintah pada sistem operasi lain jika memunkinkan.
  2. Stack yang digunakan adalah Wamp Server (Apache 2.2, MySQL, PHP 7).
  3. Yii yang digunakan adalah Yii 2.0 dengan catatan jquery yang digunakan bukan jquery3. Beberapa perintah jquery akan berbeda pada jquery3, dan beberapa extensions yang saya gunakan sepertinya belum mendukung jquery3

Apa Itu Asset?

Sebuah asset pada Yii adalah file-file yang menjadi referensi dari web-page. Dapat berupa file CSS, JS, gambar, video, dan referensi lainnya. Asset disimpan pada web-accessible directories (direktori yang dapat diakses web) dan dapat diakses oleh client.

Kita sering menerapkan asset secara programatikal. Sebagai contoh ketika kita menggunakan widget yii\jui\DatePicker dalam sebuah halaman di aplikasi, widget ini akan mengambil CSS dan JS yang dibutuhkan dan meregister CSS dan JS tersebut dihalaman dan menambahkan CSS dan JS tersebut dari vendor ke folder asset pada web-accessible directories. Dengan asset pengambilan file asset dapat dilakukan secara lazy-loading dan mudah sehingga pada halaman view kita tidak harus mencantumkan tiap file satu-per-satu.

Apa itu Client Script?

Pada aplikasi web modern selain data HTML juga ditampilkan data lain pada browser yang dapat terdiri dari JS yang digunakan untuk memodifikasi halaman pada browser dan terkadang CSS yang digunakan untuk mengatur tampilan yang ada pada browser. Beberapa client script tidak jarang bersifat khusus sehingga harus dirender pada posisi tertentu seperti bagian head, bagian body, atau pada bagian paling akhir dari kode setelah semua JS lain di load. Semua hal tersebut akan di atur pada Client Script Yii2.

Dengan abstraction pada client script kita tidak perlu mengatur skeleton pada layout kita untuk mengatur urutan tampilan pada hasil. Semua hal tersebut sudah diatur dengan perintah-perintah khusus pada Helpers yang ada pada views di Yii2.

Menambahkan JS dan CSS pada View dengan Client Script

File views, merupakan objek dari yii\web\View sehingga secara objek kita akan banyak berhadapan dengan API View. Ada 2 method yang dapat dimanfaatkan yang berkaitan dengan client script, yaitu script (dalam hal ini JS) dan CSS. Semua contoh berikut dituliskan pada file view anda.

Registering inline Script

Inline scripts bermanfaat untuk menambahkan script yang pada HTML biasanya berada dalam tag <script></script>. Cara penggunaan yang umum dari register inline script seperti dibawah.

....
$this->registerJs(<<<JS
$('#myButton').on('click', function() { alert('Button clicked!'); });
JS, View::POS_READY ,'my-button-handler'); ...

Pada contoh di atas kita membuat sebuah script pada registerJS dengan Jquery (karena Yii2 menggunakan Jquery secara default bersamaan dengan Bootstrap) untuk listening pada id "myButton". Script JS yang digunakan diinput pada parameter pertama dari registerJs dengan format string (dalam contoh saya menggunakan heredoc string). Parameter kedua dan ketiga adalah parameter opsional berupa posisi, dan key yang mengidentikasi blok kode js yang digunakan

Namun terkadang kita perlu memposisikan script tersebut pada bagian tertentu pada HTML. Posisi dapat diset pada parameter kedua registerJS. Beberapa posisi yang dapat digunakan pada registerJs antara lain:

Pada head View::POS_HEAD
Pada bagian pembukaan setelah <body> View::POS_BEGIN
Pada bagian Akhir sebelum penutupan </body> View::POS_END
Pada document.ready (secara default jika tidak terisi akan diset pada posisi ini View::POS_READY
Pada document.load View::POS_LOAD

Anda tidak perlu melakukan penyesuaian pada layout anda karena skeleton layout Yii2 akan menyesuaikan dengan layout anda.

Registering JS Script File

Pada beberapa kasus mungkin anda perlu melakukan register suatu script file secara lazy (seperti moment.js, atau datatables.js). View menyediakan method untuk meregister JS file pada halaman view anda. Bahkan apabila suatu script file bergantung dengan keberadaan script file lainnya (atau asset bundle tertentu) maka kita dapat menyebutkan dependency dari script file tersebut. Sebagai contoh kita akan menambahkan main.js yang akan bergantung pada jquery asset.

....
$this->registerJsFile(
'@web/js/main.js',
['depends' => [\yii\web\JqueryAsset::className()]]
); ...

Pada contoh di atas kita menambahkan file main.js yang berada pada folder \app\web\js\main.js dan file main.js tersebut bergantung pada JqueryAsset yang sudah dipaket menjadi AssetBundle pada Yii2. Tidak jarang AssetBundle tersebut bergantung juga dengan File lainnya, namun apabila dependency tersebut sudah diatur pada AssetBundle JqueryAsset, anda tidak perlu menambahkan setiap dependency pada saat registerJsFile.

@web pada contoh di atas merupakan alias, pembahasan mengenai alias akan kita bahas pada tulisan yang berbeda.

Namun praktik terbaik pada Yii2 lebih merekomendasikan penggunaan AssetBundle dibandingkan registerJsFile satu persatu. Karena AssetBundle lebih memberikan fleksibilitas yang lebih baik dan konfigurasi dependency yang lebih granular sehingga anda bisa mengkombinasikan dan mengkompresi data JS anda. Dan anda tidak perlu khawatir ketika folder web anda hilang, maka data yang ada pada folder web tersebut akan digenerate ulang oleh mekanisme assetBundle.

AssetBundle sungguh menarik bukan, mari kita bahas mengenai AssetBundle.

Manajemen Asset dengan Asset Bundle

Asset Bundle secara sederhana dapat dikatakan sekumpulan assets (baik css, js, gambar, atau video) yang berada pada suatu direktori. Cara kerja asset bundle adalah, begitu sebuah asset bundle di register pada view, maka Yii2 akan menduplikasi (publish) semua file (dan folder) pada folder tersebut pada \app\web\assets dengan format penamaan tertentu atau menambahkan assets tersebut pada halaman yang dibuka (jika merupakan web-accessible-directory). Pada saat assets tidak berada pada web-accessible directory, apabila terjadi perubahan pada file/folder sumber dari AssetBundle maka yii2 akan mendeteksi versi dari file dan folder pada \app\web\assets dan jika berbeda asset akan digenerate (publish) ulang sesuai versi yang baru.

Pada contoh ini kita akan membuat sebuah AssetBundle berupa ChartJs yang nantinya akan kita gunakan di halaman dashboard kita.

Mendefinisikan Asset Bundle

Sebuah aset bundle akan mengekstends yii\web\AssetBundle dan nantinya harus autoloadable . Berikut adalah salah satu contoh penggunaan AssetBundle yang ada pada Template Basic.

<?php

namespace app\assets;

use yii\web\AssetBundle;

class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.css',
['css/print.css', 'media' => 'print'],
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}

Class AssetBundle di atas biasa disimpan pada folder \app\assets namun bisa lebih fleksibel. Akan lebih baik jika anda membuat sebuah paket melalui vendor dengan membuat ekstension khusus untuk memanggil Asset tersebut.

Pada kode di atas nama Asset Bundle adalah AppAsset. Pada aset bundle tersebut diset beberapa properti seperti basePath, baseUrl, css, js, dan depends. Fungsi dari masing-masing properti tersebut antara lain

sourcePath string Menyatakan root direktori dari file asset bundle kita. sourcePath diset dalam hal sumber direktori kita bukan web-accessible directory. Yii2 nantinya akan melakukan asset publishing atas semua file dalam direktori tersebut. Jika file-file yang menjadi sumber asset bundle kita merupakan web-accessible directory maka kita menggunakan basePath dan baseUrl.
basePath string Menyatakan web-accessible directory dimana file asset sumber kita berada. Kita bisa menggunakan path alias disini.
baseUrl string Menyatakan URL yang berkaitan dengan basePath. Kita bisa menggunakan path alias disini.
css array Menyatakan daftar CSS files yang ada pada bundle. Gunakan "/" sebagai pemisah folder.
js array

Menyatakan daftar JS files yang ada pada bundle. Gunakan "/" sebagai pemisah folder. JS dapat dinyatakan dengan dua format yaitu:

  • Path relatif (contoh "js/main.js")
  • Absolute URL dari eksternal JS file. (contoh "http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js" atau "//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"
depends array  Daftar asset bundle lain dimana AssetBundle ini bergantung.
jsOptions array Options tambahan untuk JsFile, sama seperti options untuk registerJsFile pada sesi sebelumnya.
cssOptions array Options tambahan untuk CssFile, sama seperti options untuk registerCssFile pada sesi sebelumnya.
publishOptions array Options tambahan untuk Asset Bundle ini. Hanya digunakan jika kita akan mempublish dengan sourcePath.

 

Contoh Penggunaan Asset Bundle untuk Chart.Js

Dari contoh di atas kita akan mencoba membuat sebuah Asset Bundle yang akan menghandle asset untuk Chart.Js. Pertama kita unduh terlebih dahulu Chart.Js yang dapat diunduh pada release github Chart.Js pada paket chart.js.zip. Kemudian ekstrak pada folder \app\web\js\ChartJs.

Selanjutnya kita akan membuat file Asset pada \app\assets\ChartJsAsset.php dengan isian sebagai berikut.

<?php

namespace app\assets;

use yii\web\AssetBundle;

/**
 * ChartJs asset bundle.
 *
 * @author hoaaah
 */
class ChartJsAsset extends AssetBundle
{
    public $basePath = '@webroot/js/chartjs';
    public $baseUrl = '@web/js/chartjs';

    /**
     * We use min.js when in production
     * We don't have any css file here
     * We use chart.js only, because momentarily we don't need moment.js
     */

    public $css = [
    ];

    public $js = [
        YII_ENV_DEV ? 'Chart.js' : 'Chart.min.js',
    ];

    // public $depends = [
    //     'yii\web\YiiAsset',
    //     'yii\bootstrap\BootstrapAsset',
    // ];
}

Selanjutnya kita akan menggunakan Asset Bundle yang kita buat pada view di subseksi berikutnya.

Menggunakan Asset Bundle 

Setelah kita membuat Class untuk Asset Bundle maka kita akan menggunakannya pada view. Chart akan ditampilkan pada laman "administrator\blog\" dan menampilkan grafik batang jumlah blog yang dipublish setiap bulannya.

Pertama kita akan melakukan register Asset Bundle kita pada laman view. Oleh karena itu kita buka file app\modules\administrator\views\blog\index.php dan tamhakan baris berikut.

use app\assets\ChartJsAsset;

ChartJsAsset::register($this);

Baris di atas akan melakukan register semua CSS dan JS yang telah kita buat sebelumnya. Selanjutnya kita akan membuat query untuk membuat array untuk menampilkan jumlah blog yang disusun setiap bulannya. Ubah file \app\modules\administrator\controllers\BlogController.php dengan menambahkan bagian berikut pada actionIndex.

    public function actionIndex()
    {
        $year = date('Y');
        // create an array for count blog by year this year
        $blogCountByMonth = Blog::find()
        ->select(['MONTH(FROM_UNIXTIME(created_at)) month', 'count(id) AS count'])
        ->where("YEAR(FROM_UNIXTIME(created_at)) = $year")
        ->groupBy('MONTH(FROM_UNIXTIME(created_at))')->asArray()->all();

        $searchModel = new BlogSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
            'blogCountByMonth' => $blogCountByMonth,
        ]);
    }

Selanjutnya kita akan menggenerate data tersebut pada view. Tambahkan bagian registerScript  berikut pada view anda.

use yii\helpers\Json;
....
<canvas id="blogCountByMonthChart"></canvas>
....
<?php // first with convert our php array object to json $blogCountByMonthJson = Json::encode($blogCountByMonth); // then register our Js $this->registerJs(<<<JS // we create function for generate count per month first function generateDataCount(month, blogCount){ var result = blogCount.find(o => o.month == month); if(result == null) return 0; return result.count; } var blogCount = $blogCountByMonthJson; // blogCount json var ctx = document.getElementById('blogCountByMonthChart').getContext('2d'); //ctx, you can replace it with jQuery if you have one // Then we generate data with some simple looping var i = 0; data = []; while(i < 12) { data[i] = generateDataCount(i+1, blogCount); i++; } // and then generate to chartJs var chart = new Chart(ctx, { type: 'bar', data: { labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], datasets: [{ label: "Blog Count By Month", backgroundColor: 'rgb(255, 99, 132)', borderColor: 'rgb(255, 99, 132)', data: data, }] }, options: {} }); JS ); ?>

Dan dengan contoh di atas maka kita dapat melihat grafik ChartJs pada halaman administrator/blog kita. 

Asset Bundle yang Umumnya Digunakan

Ada beberapa Asset Bundle yang umum di gunakan pada Yii2. Asset Bundle tersebut tersedia langsung (pada Yii2.0, dan mungkin akan dibuat terpisah pada Yii2.1) dan langsung bisa kita panggil melalui depends parameter. Asset Bundle tersebut antara lain sebagai berikut

yii\web\YiiAsset Asset ini berisi file yii.js yang secara default digunakan dan dipanggil pada banyak widget di yii. Termasuk yang paling khas dari yii.js ini adalah data-method dan data-confirm untuk memudahkan dalam menentukan behavior dari sebuah link apakah GET, POST, PUT, DELETE, atau konfirmasi tanpa harus bersusah payah menyusun FORM (jika kita menggunakan POST).
yii\web\JqueryAsset Asset ini berisi jquery.js yang berasal dari JQuery Bower package.
yii\bootstrap\BootstrapAsset Asset ini berisi CSS file dari Twitter Bootstrap Framework. Library CSS default yang digunakan pada Yii2.0
yii\bootstrap\BootstrapPluginAsset Asset ini berisi JS file dari Twitter Bootstrap Framework. Library CSS default yang digunakan pada Yii2.0
yii\jui\JuiAsset Asset ini berisi CSS dan JS dari jQuery UI Library. Jui harus diinstall tambahan pada Yii2.0 sebagai ekstension tambahan.

 


Demikian tulisan ini dibuat, semoga bermanfaat bagi anda dalam memanajemen Asset pada aplikasi Yii2 anda. Sebenarnya ada fitur lain yang sangat menarik di Asset Bundle yaitu Asset Conversion dan Asset Compresion (WebPack Yeah!) yang akan kita bahas pada tulisan terpisah mengingat hal tersebut sedikit advance dari tulisan ini. Semoga bermanfaat dan Happy Coding!