Tạo một package đơn gian với laravel 5

Một trong những điểm mạnh của Laravel mà người sử dụng nào cũng rất ưa thích đó là tính linh hoạt. Trong bài viết hôm nay tôi sẽ hướng dẫn các bác từng bước để có thể tạo được một package đơn gian cho Laravel.

Cấu trúc thư mục

Việc đầu tiên chúng ta cần làm là tạo một thư mục và name-spacing cho package theo chuẩn PSR-4. Hầu hết các package đều có thư mục như sau:

vendor/package-name

Trong đó:

  • vendor: là tên thư mục chứa package
  • package-name: là tên của package

Trong ví dụ này tôi sẽ đên tên package là "simple-admin". package này tôi sẽ đặt trong thư mục packages nằm trong thư mục gốc của Laravel. Bên trong thư mục simple-admin là thư mục src chưa toàn bộ source code. Các bạn có thể cụ thể hơn nữa đường dẫn tới package bằng việc đặt trong thư mục tên của mình. Như vậy package của chúng ta có đường dẫn như sau:

/packages/canhnv/simple-admin/src

Sử dụng Composer

Sau khi tạo xong cấu trúc thư mục, việc tiếp theo chúng ta cần làm là tạo file composer.json cho package. File này sẽ giúp package của chúng ta tong việc quản lý các dependencies (các package của laravel khác khi bạn muốn sử dụng chúng cho package của mình) và cho việc deloy package khi hoàn thiện.

Di chuyển đến thư mục packages/canhnv/simple-admin/src và chạy lệnh:

composer init

Sau một vài bước tùy chọn hiện ra trên terminal sẽ kết thúc bằng việc tạo ra file composer.json với nội dung như sau:

{
"name": "quandt/simple-admin",
"description": "A package which provides a simple UI for managing users",
"authors": [
{
"name": "QuanDT",
"email": "[email protected]"
}
],
"minimum-stability": "dev",
"require": {}
}

**Tạo namespace trỏ đến package **

Mở file composer.json tại thư mục gốc của laravel. Tìm đến dòng "psr-4". Tại đây bạn sẽ thấy Laravel định nghĩa sẵn một namespace cho thư mục app. Tôi sẽ thêm namespace cho package của mình như sau:

"psr-4": {
"App\\": "app/",
"CANHNV\\SimpleAdmin\\": "packages/quandt/simple-admin/src"
}

Sau đó chạy lệnh:

composer dumpautoload

tại thư mục gốc để Composer nhận namespace mới.

Tạo Service Provider

Service Provider cho Laravel biết tất cả về package của chúng ta và Laravel sẽ biết các dependencies nào cần bind và resolve từ IoC container. Trong terminal chạy lệnh:

php artisan make:provider SimpleAdminServiceProvider

Lệnh này sẽ tạo ra file SimpleAdminServiceProvider.php đặt tại thư mục app/providers. Copy file này vào thư mục “src” của package và nhớ đổi namespace ở dòng trên cùng. File SimpleAdminServiceProvider.php sẽ có nội dung như sau:

<?php

namespace CANHNV\SimpleAdmin;

use Illuminate\Support\ServiceProvider;

class SimpleAdminServiceProvider extends ServiceProvide {
    /**
    * Bootstrap the application services.
    *
    * @return void
    */
    public function boot()
    {
    //
    }

    /**
    * Register the application services.
    *
    * @return void
    */
    public function register()
    {
    //
    }
}

Cuối cùng chúng ta thêm Service Provider vào mảng providers trong file app/config.php như sau:

CANHNV\SimpleAdmin\SimpleAdminServiceProvider'  /*cho laravel 5

'CANHNV\SimpleAdmin\SimpleAdminServiceProvider::class' //cho laravel 5.1

Tạo controller cho package

Tôi sẽ tạo một controller cơ bản được đặt tại thư mục “src” của package như sau:

<?php

namespace CANHNV\SimpleAdmin;

use App\Http\Controllers\Controller;
use App\User;

class SimpleAdminController extends Controller {

      public function __construct() {
        $this->middleware('auth');
      }

      /**
      * Display a listing of the resource.
      *
      * @return Response
      */
      public function index()
      {
        $users = User::all();

        return view('simpleAdmin::admin')->with('users', $users);
      }
}

Bạn thấy đấy, tạo một controller cho package rất đơn giản, chỉ có một lưu ý nhỏ là khi gọi đến view chúng ta phải sử dụng namespace phía trước “SimpleAdmin::admin”. Mục đích của việc này là để Laravel phân biệt view trong package của bạn với các view còn lại của ứng dụng để tránh bị xung đột.Namespace sử dụng cho view sẽ được thêm ở phần tiếp theo.

** Thêm view cho package **

Để đăng ký view cho package của bạn với Laravel, bạn có thể sử dụng hàm loadViewsFrom trong service provider. hàm này có 2 tham số là đường dẫn đến thư mục chứa các file view của package và tên package:

public function boot()
{
	$this->loadViewsFrom(__DIR__.'/views', 'SimpleAdmin');
}

Ghi đè view của package

Khi sử dụng hàm loadViewsFrom, Laravel sẽ đăng ký 2 vị trí cho view của package, một nằm tại resources/views/vendor và tại thư mục được chỉ định khi gọi hàm (thư mục view trong package). Laravel sẽ check view tại resources/views/vendor trước, nếu ko tồn tại file thì mới tìm đến thư mục được chỉ định khi gọi loadViewsFrom.

Xuất file view

Nếu bạn muốn copy file view của package vào thư mục resources/views/vendor thì bạn có thể sử dụng hàm publishes của service provider. Hàm publishes nhận đối số là một mảng các đường dẫn đến các file views của package và các đường dẫn tương ứng mà nó sẽ xuất tới. Ví dụ:

public function boot()
{
    $this->loadViewsFrom(__DIR__.'/views', 'SimpleAdmin');

    $this->publishes([
    __DIR__.'/views' => base_path('resources/views/vendor/SimpleAdmin'),
    ]);
}

Xuất file config

Bạn có thể sử dụng cách tương tự như đối với các file view để copy các file config vào đường dẫn mặc định của chúng như sau:

public function boot()
{
    $this->publishes([
        __DIR__.'/path/to/config/menu.php' => config_path(menu.php'),
    ]);
}

Khi chạy lệnh:

php artisan vendor:publish

tại thư mục gốc ứng dụng sẽ copy các file view và config của package vào đường dẫn được chỉ định.

Đến đây tôi sẽ tạo thư mục “views” nằm trong thư mục “src” và đặt vào đó file admin.blade.php. File này có nội dung như sau:

<div class="container">
	<h1>You have {{count($users)}} user(s)</h1>
    <div class="col-md-8">
        <ul class="list-group">
        @foreach($users as $user)
        	<li class="list-group-item">{{$user->name}}</li>

         @endforeach
        </ul>
    </div>
</div>

File view này sẽ list ra tất cả các user có trong database.

Tạo file route

Một package cần phải có route của riêng nó, Laravel cho phép bạn tạo route cho package khá đơn giản. Bạn chỉ cần tạo file routes đặt trong thư mục “src” và require nó trong hàm boot của service provider của package:

public function boot()
{
    if (! $this->app->routesAreCached()) {
        require __DIR__.'/routes.php';
    }
}

File routes của tôi chỉ gồm một dòng:

Route::get('admin', 'CANHNV\SimpleAdmin\[email protected]');

Đến đây bạn có thể truy cập vào đường dẫn /admin trên trình duyệt và bạn sẽ thấy một danh sách các users có trong database. Vậy là package đã hoàn thành! 😄

** Tóm tắt **

Tôi xin tóm tắt các bước tạo một package cho Laravel như sau:

  • Tạo cấu trúc thư mục của package
  • Tạo file composer.json của package
  • Tạo namespace trỏ đến package
  • Tạo service provider của package và thêm nó vào config/app.php
  • Tạo controller cho package và truy vấn các user trong DB
  • Tạo view hiển thị danh sách các user
  • Tạo route trỏ đến controller.

All Rights Reserved