Indonesian (Bahasa Indonesia) translation by Andy Nur (you can also view the original English article)
Sulit untuk menyangkal fakta bahwa komunitas PHP sangat antusias dengan Laravel 4. Antara lain, framework yang memanfaatkan kekuatan Composer, yang berarti ia dapat memanfaatkan paket atau skrip dari Packagist.
Sementara itu, Laravel menawarkan "Bundel", yang memungkinkan kita untuk modularize kode untuk digunakan dalam proyek-proyek di masa mendatang. Direktori bundel penuh dengan skrip dan paket unggulan yang dapat kamu gunakan di aplikasimu. Dalam pelajaran ini, saya akan menunjukkan cara membangunnya dari nol!
Tunggu, Apa itu Bundel?
Bundel menawarkan cara mudah untuk mengelompokkan kode yang terkait. Jika kamu terbiasa dengan CodeIgniter, bundel sangat mirip dengan "Sparks". Ini terlihat saat kamu melihat struktur folder.



Membuat bundel cukup sederhana. Untuk mengilustrasikan prosesnya, kita akan membangun panel admin boilerplate yang bisa kita gunakan dalam proyek di masa mendatang. Pertama, kita perlu membuat direktori 'admin' di dalam folder 'bundles' kita. Cobalah untuk mereplikasi struktur folder dari gambar di atas.
Sebelum kita mulai menambahkan apapun pada bundel kita, kita perlu terlebih dahulu mendaftarkannya dengan Laravel. Hal ini dilakukan pada file bundles.php
aplikasimu. Begitu kamu membuka file ini, kamu akan melihat sebuah array yang dikembalikan; kita hanya perlu menambahkan bundel kita dan menentukan handle
. Ini akan menjadi URI dimana kita mengakses panel admin kita.
1 |
'admin' => array('handles' => 'admin') |
Di sini, saya menamai diri saya, 'admin', tapi jangan ragu untuk memanggilmu sesuai dengan keinginanmu.
Setelah kita mendapatkan pengaturan itu, kita perlu membuat file start.php
. Di sini, kita akan menyiapkan beberapa barang, seperti namespace kita. Jika kamu tidak terganggu oleh ini, maka kamu sebenarnya tidak memerlukan file awal agar bundelmu bekerja, seperti yang diharapkan.
Class autoloader Laravel memungkinkan kita melakukan beberapa hal: memetakan controller base kita, dan namespace autoload.
1 |
Autoloader::map(array( |
2 |
'Admin_Base_Controller' => Bundle::path('admin').'controllers/base.php', |
3 |
));
|
4 |
|
5 |
Autoloader::namespaces(array( |
6 |
'Admin\Models' => Bundle::path('admin').'models', |
7 |
'Admin\Libraries' => Bundle::path('admin').'libraries', |
8 |
));
|
Namespace akan memastikan bahwa kita tidak akan bertentangan dengan model atau library lain yang sudah termasuk dalam aplikasi kita. Kamu akan melihat bahwa kita tidak memilih untuk tidak namespace controller kita untuk membuat hal-hal sedikit lebih mudah.
Penerbitan Asset
Untuk panel admin, kita akan memanfaatkan Twitter Bootstrap, jadi ambil salinannya. Kita bisa memasukkan ini ke dalam folder public
di dalam paket kita untuk dipublikasikan ke aplikasi kita nanti.
Bila kamu siap mempublikasikannya, jalankan perintah berikut melalui artisan.
1 |
php artisan bundle:publish admin |
Ini akan menyalin struktur folder dan file ke direktori bundles
di folder public
kita, di dalam root instalasi Laravel. Kita kemudian bisa menggunakan ini di controller base bundel kita.
Mengatur Controller Base
Itu selalu menjadi ide cerdas untuk mengatur controller base, dan memperluasnya dari sana. Di sini, kita bisa mengatur controller restful, menentukan layout, dan menyertakan asset apa pun. Kita hanya perlu memanggil file ini, base.php
, dan memasukkannya ke direktori controller kita.
Pertama, ayo kita keluar rumah. Tentu saja kita ingin menggunakan controller restful Laravel.
1 |
public $restful = true; |
Dan kita akan menentukan layout yang akan kita buat segera. Jika kamu tidak terbiasa dengan tata letak controller, berarti kamu perlu memperlakukannya.
1 |
public $layout = 'admin::layouts.main'; |
Nama bundel, diikuti oleh dua titik dua, adalah paradigma di Laravel yang akan kita lihat lebih banyak di masa mendatang, jadi awasi.
Saat menangani aset di dalam paket kita, kita dapat melakukan hal-hal seperti yang diharapkan dan menentukan path dari root folder publik. Syukurlah, Laravel ada untuk membuat hidup kita lebih mudah. Dalam konstruksi kita, kita perlu menentukan bundelnya, sebelum menambahkan ke kontainer asset kita.
1 |
Asset::container('header')->bundle('admin'); |
2 |
Asset::container('footer')->bundle('admin'); |
Jika kamu tidak terbiasa dengan kontainer aset, jangan khawatir; mereka hanya bagian dari halaman di mana kamu ingin menempatkan asset-mu. Di sini, kita akan menyertakan stylesheet di header, dan script di footer.
Sekarang, dengan disingkirkannya, kita bisa memasukkan style bootstrap dan script kita dengan mudah. Controller base kita yang telah selesai akan terlihat seperti pada:
1 |
class Admin_Base_Controller extends Controller { |
2 |
|
3 |
public $restful = true; |
4 |
public $layout = 'admin::layouts.main'; |
5 |
|
6 |
public function __construct(){ |
7 |
|
8 |
parent::__construct(); |
9 |
|
10 |
Asset::container('header')->bundle('admin'); |
11 |
Asset::container('header')->add('bootstrap', 'css/bootstrap.min.css'); |
12 |
|
13 |
Asset::container('footer')->bundle('admin'); |
14 |
Asset::container('footer')->add('jquery', 'http://code.jquery.com/jquery-latest.min.js'); |
15 |
Asset::container('footer')->add('bootstrapjs', 'js/bootstrap.min.js'); |
16 |
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
* Catch-all method for requests that can't be matched.
|
21 |
*
|
22 |
* @param string $method
|
23 |
* @param array $parameters
|
24 |
* @return Response
|
25 |
*/
|
26 |
public function __call($method, $parameters){ |
27 |
return Response::error('404'); |
28 |
}
|
29 |
|
30 |
}
|
Kita juga membawa semua hasil tangkapan request dari controller base aplikasi untuk mengembalikan respons 404, jika halaman tidak ditemukan.
Sebelum kita melakukan hal lain, mari kita buat file layout itu, views/layout/main.blade.php
, jadi kita tidak menemukan error nantinya.
Mengamankan Bundel
Saat kita membangun panel admin, kita ingin mencegar orang keluar. Syukurlah, kita bisa menggunakan bawaan Laravel yang ada di class Auth
untuk mencapainya dengan mudah ..
Pertama, kita perlu membuat meja kita; Saya akan menggunakan 'admins' sebagai nama tabel saya, tetapi kamu bisa mengubahnya, jika kamu mau. Artisan akan menghasilkan migration, dan memasukkannya ke dalam direktori migration bundel kita. Jalankan saja perintah berikut di command line.
1 |
php artisan migrate:make admin::create_admins_table |
Membangun Skema
Jika kamu tidak terbiasa dengan schema builder, sebaiknya kamu melirik dokumentasinya. Kita akan menyertakan beberapa kolom:
- id - Ini akan otomatis bertambah dan menjadi kunci utama kita
- name
- username
- password
- role - Kita tidak akan mengambil manfaatnya pada hari ini, tetapi akan memungkinkanmu untuk memperluas bundelnya nanti.
Kita juga akan memasukkan timestamps default, untuk mengikuti praktik terbaik.
1 |
/**
|
2 |
* Make changes to the database.
|
3 |
*
|
4 |
* @return void
|
5 |
*/
|
6 |
public function up() |
7 |
{
|
8 |
Schema::create('admins', function($table) |
9 |
{
|
10 |
$table->increments('id'); |
11 |
$table->string('name', 200); |
12 |
$table->string('username', 32)->unique(); |
13 |
$table->string('password', 64); |
14 |
$table->string('email', 320)->unique(); |
15 |
$table->string('role', 32); |
16 |
$table->timestamps(); |
17 |
});
|
18 |
}
|
19 |
|
20 |
/**
|
21 |
* Revert the changes to the database.
|
22 |
*
|
23 |
* @return void
|
24 |
*/
|
25 |
public function down() |
26 |
{
|
27 |
Schema::drop('admins'); |
28 |
}
|
Sekarang setelah kita memiliki struktur database kita, kita perlu membuat model yang terkait untuk tabel. Proses ini pada dasarnya identik dengan bagaimana kita bisa melakukannya di aplikasi utama kita. Kita membuat file dan model, berdasarkan bentuk tunggal dari nama tabel kita - tetapi kita perlu memastikan bahwa namespace kita benar.
1 |
namespace Admin\Models; |
2 |
use \Laravel\Database\Eloquent\Model as Eloquent; |
3 |
|
4 |
class Admin extends Eloquent { |
5 |
}
|
Di atas, kita telah memastikan bahwa kita menggunakan namespace yang kita definisikan di start.php. Juga, jadi kita bisa mereferensi Eloquent
dengan benar, kita buat alias.
Memperluas Auth
Agar bundel kita sepenuhnya terkandung, kita harus memperluas auth
. Ini akan memungkinkan kita untuk mendefinisikan tabel hanya untuk login ke panel admin kita, dan tidak mengganggu aplikasi utama.
Sebelum membuat driver khusus kita, kita akan membuat file konfigurasi, di mana kamu dapat memilih apakah kamu ingin menggunakan kolom username
atau email
dari tabel database.
1 |
return array( |
2 |
'username' => 'username', |
3 |
'password' => 'password', |
4 |
);
|
Jika kamu ingin mengubah kolom yang akan kita gunakan, sesuaikan saja nilainya di sini.
Selanjutnya kita perlu membuat driver. Mari kita menyebutnya, "AdminAuth," dan sertakan di folder library kita. Karena kita memperluas Auth, kita hanya perlu menimpa beberapa metode untuk menyelesaikan semuanya, seperti yang kita inginkan.
1 |
|
2 |
namespace Admin\Libraries; |
3 |
use Admin\Models\Admin as Admin, Laravel\Auth\Drivers\Eloquent as Eloquent, Laravel\Hash, Laravel\Config; |
4 |
|
5 |
class AdminAuth extends Eloquent { |
6 |
|
7 |
/**
|
8 |
* Get the current user of the application.
|
9 |
*
|
10 |
* If the user is a guest, null should be returned.
|
11 |
*
|
12 |
* @param int|object $token
|
13 |
* @return mixed|null
|
14 |
*/
|
15 |
public function retrieve($token) |
16 |
{
|
17 |
// We return an object here either if the passed token is an integer (ID)
|
18 |
// or if we are passed a model object of the correct type
|
19 |
if (filter_var($token, FILTER_VALIDATE_INT) !== false) |
20 |
{
|
21 |
return $this->model()->find($token); |
22 |
}
|
23 |
else if (get_class($token) == new Admin) |
24 |
{
|
25 |
return $token; |
26 |
}
|
27 |
}
|
28 |
|
29 |
/**
|
30 |
* Attempt to log a user into the application.
|
31 |
*
|
32 |
* @param array $arguments
|
33 |
* @return void
|
34 |
*/
|
35 |
public function attempt($arguments = array()) |
36 |
{
|
37 |
$user = $this->model()->where(function($query) use($arguments) |
38 |
{
|
39 |
$username = Config::get('admin::auth.username'); |
40 |
|
41 |
$query->where($username, '=', $arguments['username']); |
42 |
|
43 |
foreach(array_except($arguments, array('username', 'password', 'remember')) as $column => $val) |
44 |
{
|
45 |
$query->where($column, '=', $val); |
46 |
}
|
47 |
})->first(); |
48 |
|
49 |
// If the credentials match what is in the database, we will just
|
50 |
// log the user into the application and remember them if asked.
|
51 |
$password = $arguments['password']; |
52 |
|
53 |
$password_field = Config::get('admin::auth.password', 'password'); |
54 |
|
55 |
if ( ! is_null($user) and Hash::check($password, $user->{$password_field})) |
56 |
{
|
57 |
return $this->login($user->get_key(), array_get($arguments, 'remember')); |
58 |
}
|
59 |
|
60 |
return false; |
61 |
}
|
62 |
|
63 |
protected function model(){ |
64 |
return new Admin; |
65 |
}
|
66 |
|
67 |
}
|
Sekarang setelah kita membuat driver, kita perlu memberi tahu Laravel. Kita bisa menggunakan metode extends
Auth untuk melakukan ini di file start.php
kita.
1 |
Auth::extend('adminauth', function() { |
2 |
return new Admin\Libraries\AdminAuth; |
3 |
});
|
Satu hal terakhir yang perlu kita lakukan adalah mengkonfigurasi Auth untuk menggunakan ini saat runtime. Kita bisa melakukan ini di konstruktor controller base kita dengan yang berikut.
1 |
Config::set('auth.driver', 'adminauth'); |
Route & Controller
Sebelum kita bisa melakukan route ke apa saja, kita perlu membuat controller. Mari buat controller dashboard kita, yang akan kita lihat setelah login.
Karena kita ingin ini muncul di root bundel kita (yaitu handle yang kita definisikan sebelumnya), kita perlu memanggil home.php
ini. Laravel menggunakan kata kunci 'home' untuk menetapkan apa yang ingin kamu tampilkan di root aplikasi atau bundelmu.
Perluas controller base-mu, dan buat view index. Untuk saat ini, cukup kembalikan 'Hello World' agar kita bisa memastikan semuanya berjalan dengan baik.
1 |
class Admin_Home_Controller extends Admin_Base_Controller { |
2 |
|
3 |
public function get_index(){ |
4 |
return 'Hello World'; |
5 |
}
|
6 |
|
7 |
}
|
Setelah controller kita diatur, kita bisa melakukan route-nya. Buat sebuah routes.php
dalam bundelmu, jika kamu belum melakukannya. Serupa dengan aplikasi utama kita, setiap bundel dapat memiliki file route sendiri yang bekerja identik.
1 |
Route::controller(array( |
2 |
'admin::home', |
3 |
));
|
Di sini, saya mendaftarkan controller home, yang secara otomatis ditetapkan oleh Laravel ke /
. Nantinya, kita akan menambahkan controller login kita ke array.
Jika kamu menuju ke /admin
(atau handle apa pun yang kamu tetapkan sebelumnya) di browser-mu, maka kamu seharusnya melihat 'Hello World'.
Membuat Form Login
Mari buat controller login, bagaimanapun, daripada memperluas controller base, kita malah akan memperluas controller utama Laravel. Alasan di balik keputusan ini akan segera terlihat.
Karena kita tidak memperluas, kita perlu mengatur beberapa hal sebelum memulai - yaitu layout restful, driver auth yang benar, dan asset kita.
1 |
class Admin_Login_Controller extends Controller { |
2 |
|
3 |
public $restful = true; |
4 |
|
5 |
public function __construct(){ |
6 |
|
7 |
parent::__construct(); |
8 |
|
9 |
Config::set('auth.driver', 'adminauth'); |
10 |
|
11 |
Asset::container('header')->bundle('admin'); |
12 |
Asset::container('header')->add('bootstrap', 'css/bootstrap.min.css'); |
13 |
|
14 |
}
|
15 |
|
16 |
}
|
Mari kita juga membuat view kita. Kita akan menggunakan Blade - Template Engine Laravel - untuk mempercepat banyak hal. Di dalam direktori view bundelmu, buatlah direktori 'login' dan file 'index.blade.php' di dalamnya.
Kita akan memunculkan struktur halaman HTML standar dan menampilkan asset.
1 |
<!DOCTYPE html>
|
2 |
<html lang="en"> |
3 |
<head>
|
4 |
<meta charset="utf-8"> |
5 |
<title>Login</title> |
6 |
{{Asset::container('header')->styles()}} |
7 |
<!--[if lt IE 9]>
|
8 |
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
9 |
<![endif]-->
|
10 |
</head>
|
11 |
<body>
|
12 |
|
13 |
</body>
|
14 |
</html>
|
Sekarang, mari kita pastikan bahwa view telah dibuat di controller. Karena kita menggunakan controller restful, kita dapat memanfaatkan kata kerja 'get' dalam metode kita.
1 |
public function get_index(){ |
2 |
return View::make('admin::login.index'); |
3 |
}
|
Mengagumkan! Kita sekarang siap untuk mulai membuat form kita, yang bisa kita buat dengan class Form
.
1 |
{{Form::open()}} |
2 |
|
3 |
{{Form::label('username', 'Username')}} |
4 |
{{Form::text('username')}} |
5 |
|
6 |
{{Form::label('password', 'Password')}} |
7 |
{{Form::password('password')}} |
8 |
|
9 |
{{Form::submit('Login', array('class' => 'btn btn-success'))}} |
10 |
|
11 |
{{Form::token()}} |
12 |
{{Form::close()}} |



Di atas, kita membuat form yang akan diposkan ke dirinya sendiri (sesuai dengan keinginan kita), bersama dengan berbagai elemen form dan label yang disertakan dengannya. Langkah selanjutnya adalah mengolah form.
Karena kita memposting form itu ke dirinya sendiri dan menggunakan controller restful, kita hanya perlu membuat metode post_index
dan menggunakannya untuk memproses login kita. Jika kamu belum pernah menggunakan Auth sebelumnya, pergilah dan pantau dokumentasinya sebelum melanjutkan.
1 |
public function post_index(){ |
2 |
|
3 |
$creds = array( |
4 |
'username' => Input::get('username'), |
5 |
'password' => Input::get('password'), |
6 |
);
|
7 |
|
8 |
if (Auth::attempt($creds)) { |
9 |
return Redirect::to(URL::to_action('admin::home@index')); |
10 |
} else { |
11 |
return Redirect::back()->with('error', true); |
12 |
}
|
13 |
|
14 |
}
|
Jika kredensialnya benar, pengguna akan diarahkan ke dashboard. Jika tidak, mereka akan diarahkan kembali dengan error yang dapat kita periksa di view login. Karena ini hanya data session, dan bukan kesalahan validasi, kita hanya perlu mengimplementasi pengecekan sederhana.
1 |
@if(Session::get('error')) |
2 |
Sorry, your username or password was incorrect. |
3 |
@endif |
Kita juga perlu log pengguna; jadi mari kita buat metode get_logout
, dan tambahkan berikut ini. Ini akan melakukan log pengguna yang keluar, dan kemudian mengarahkan mereka saat mengunjungi /admin/login/ogout
.
1 |
public function get_logout(){ |
2 |
Auth::logout(); |
3 |
return Redirect::to(URL::to_action('admin::home@index')); |
4 |
}
|
Hal terakhir yang harus kita lakukan adalah menambahkan controller login ke file route kita.
1 |
Route::controller(array( |
2 |
'admin::home', |
3 |
'admin::login', |
4 |
));
|
Pemfilteran route
Untuk menghentikan seseorang dari mem-bypass layar login kita, kita perlu memfilter route kita untuk menentukan apakah mereka pengguna yang berwenang. Kita bisa membuat filter di routes.php
kita, dan melampirkannya ke controller base kita, untuk memfilternya sebelum route ditampilkan.
1 |
Route::filter('auth', function() { |
2 |
if (Auth::guest()) return Redirect::to(URL::to_action('admin::login')); |
3 |
});
|
Pada titik ini, semua yang tersisa untuk dilakukan adalah memanggil ini di konstruktor controller base kita. Jika kita memperluas controller login kita dari base kita, maka kita akan memiliki pengulangan tak terbatas yang pada akhirnya akan keluar waktu.
1 |
$this->filter('before', 'auth'); |
Mengatur View
Sebelumnya, kita membuat layout main.blade.php
kita; Sekarang, kita akan melakukan sesuatu dengan itu. Mari kita membawa masuk halaman HTML dan asset kita.
1 |
<!DOCTYPE html>
|
2 |
<html lang="en"> |
3 |
<head>
|
4 |
<meta charset="utf-8"> |
5 |
<title>{{$title}}</title> |
6 |
{{Asset::container('header')->styles()}} |
7 |
<!--[if lt IE 9]>
|
8 |
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
9 |
<![endif]-->
|
10 |
</head>
|
11 |
<body>
|
12 |
<div class="container"> |
13 |
{{$content}} |
14 |
</div>
|
15 |
{{Asset::container('footer')->scripts()}} |
16 |
</body>
|
17 |
</html>
|
Kamu akan melihat bahwa saya juga telah menampilkan beberapa variabel: $title
dan $content
. Kita akan bisa menggunakan magic method dari controller kita untuk meneruskan data melalui ini. Saya juga telah memasukkan $content
ke dalam div
kontainer yang akan menyediakan styling untuk Bootstrap.
Selanjutnya, mari buat view untuk dashboard kita. Karena kita akan menjadikan ini bersarang, kita hanya perlu meletakkan konten yang ingin dimasukkan ke dalam kontainer kita.
1 |
<h1>Hello</h1> |
2 |
<p class="lead">This is our dashboard view</p> |
Simpan ini sebagai index.blade.php
dalam direktori views/dashboard
di dalam bundelmu.
Kita sekarang perlu mengatur controller kita untuk memanfaatkan layout dan file vuew yang baru saja kita buat. Dalam metode get_index
yang telah kita buat tadi, tambahkan berikut ini.
1 |
$this->layout->title = 'Dashboard'; |
2 |
$this->layout->nest('content', 'admin::dashboard.index'); |
title
adalah magic method yang kemudian bisa kita tampilkan sebagai variabel dalam layout kita. Dengan menggunakan nest
, kita bisa memasukkan view di dalam layout langsung dari controller kita.
Membuat Task
Untuk mempercepat segalanya, Laravel memberikan kita cara mudah untuk mengeksekusi kode dari command line. Ini disebut "Tasks"; Ini adalah ide yang bagus untuk menambahkan pengguna baru ke database dengan mudah.
Kita hanya perlu memastikan bahwa file tersebut mengambil nama task kita, dan memasukkannya ke dalam direktori task bundel kita. Saya akan memanggil setup.php
ini, karena kita akan menggunakannya hanya setelah menginstal bundel.
1 |
|
2 |
use Laravel\CLI\Command as Command; |
3 |
use Admin\Models\Admin as Admin; |
4 |
|
5 |
class Admin_Setup_Task { |
6 |
|
7 |
public function run($arguments){ |
8 |
|
9 |
if(empty($arguments) || count($arguments) < 5){ |
10 |
die("Error: Please enter first name, last name, username, email address and password\n"); |
11 |
}
|
12 |
|
13 |
Command::run(array('bundle:publish', 'admin')); |
14 |
|
15 |
$role = (!isset($arguments[5])) ? 'admin' : $arguments[5]; |
16 |
|
17 |
$data = array( |
18 |
'name' => $arguments[0].' '.$arguments[1], |
19 |
'username' => $arguments[2], |
20 |
'email' => $arguments[3], |
21 |
'password' => Hash::make($arguments[4]), |
22 |
'role' => $role, |
23 |
);
|
24 |
|
25 |
$user = Admin::create($data); |
26 |
|
27 |
echo ($user) ? 'Admin created successfully!' : 'Error creating admin!'; |
28 |
|
29 |
}
|
30 |
|
31 |
}
|
Laravel akan melewati serangkaian argumen array; kita bisa menghitung ini untuk memastikan bahwa kita mendapatkan apa yang kita inginkan. Jika tidak, kita akan menampilkan error. Kamu juga akan melihat bahwa kita menggunakan class Command
untuk menjalankan bundel:publish
. Ini akan memungkinkanmu untuk menjalankan task command line yang ada pada Laravel di dalam aplikasi atau bundelmu.
Hal utama dari task ini adalah mengambil argumen yang diajukan, password hash, dan memasukkan admin baru ke dalam tabel Admins
. Untuk menjalankan ini, kita perlu menggunakan perintah berikut di command line.
1 |
php artisan admin::setup firstname lastname username email@address.com password |
Sekarang Apa?
Pada tutorial ini, kita telah membuat panel admin boilerplate yang cukup mudah untuk diperluas. Misalnya, kolom roles
yang kita buat memungkinkanmu membatasi apa yang dapat dilihat oleh klienmu.
Bundel bisa berupa apa saja dari panel admin, seperti yang kita bangun hari ini, ke markdown parser - atau bahkan keseluruhan Zend Framework (saya tidak bercanda). Segala sesuatu yang kita bahas di sini akan menentukanmu dalam perjalanan untuk menulis bundel Laravel yang mengagumkan, yang dapat dipublikasikan ke direktori bundel Laravel.
Pelajari lebih lanjut tentang membuat bundel Laravel di sini di Nettuts+.