本文原連接來自個人博客,地址: Laravel Composer Package 開發實戰 toastr-for-laravel5 javascript
在Laravel的文檔中有Package Development,對於入門開發人員來講仍是比較抽象,由於開發一個包須要瞭解 Service Providers,Service Providers 和 Facade 已經夠抽象的了對剛接觸Laravel的開發人員來講,因此我來寫一個簡單的Laravel 包開發的實例教程吧。 php
toastr.js是一個很方便的通知效果,最近剛發佈了laravel 5.2,因此就來開發一個toastr for laravel 5的包吧,主要用toastr結合laravel的flash session來實現頁面的一次性消息提醒,其實這個在咱們平常開發中頁面操做提醒仍是很經常使用到的業務。 css
通常的laravel 包開發過程是這樣的,開發好之後打包push到gitlab,而後在packagist上提交,下面咱們就來一步一步實現這個過程。 html
1.在新建的laravel項目中創建以下目錄 packages/yuansir/toastr/src ,packages 目錄和 app 目錄同級。咱們開發包的代碼都放在這個src目錄中,yuansir和toastr徹底自定義。 java
2.修改項目的composer.json,設定PSR-4命名空間: laravel
"autoload": { "classmap": [ "database" ], "psr-4": { "App\\": "app/", "Yuansir\\Toastr\\": "packages/yuansir/toastr/src/" } },
別忘了執行autoload git
$ cd pacages/yuansir/toastr/src
3.爲咱們的包初始化一個composer.json文件,熟悉composer的應該都知道這玩意是幹嗎的了 github
$ cd pacages/yuansir/toastr/src按照提示填寫相關信息,有些信息能夠不用填寫,後面本身在composer.json中添加就能夠了,生成的示例以下:
{ "name": "ryan/toastr-for-laravel", "description": "toastr.js for laravel5", "authors": [ { "name": "Ryan", "email": "yuansir@live.cn" } ], "require": {} }
4.開始開發,新建Service Provider web
php artisan make:provider ToastrServiceProvider
將生成的app/Providers/ToastrServiceProvider.php文件移動到咱們的packages/yuansir/toastr/src 目錄下面,並註冊ToastrServiceProvider到config/app.php 的providers 中。 shell
'providers' => [ /* * Laravel Framework Service Providers... */ ...... /* * Application Service Providers... */ ...... Yuansir\Toastr\ToastrServiceProvider::class, ],
5.新建packages/yuansir/toastr/src/config/toastr.php 來保存toastr.js的options,options配置還蠻多的,具體能夠看它的demo。
<?php return [ 'options' => [] ];
關於這個配置在咱們包中如何調用的,咱們過會來講.
6.新建Toastr類,來實現toastr 的info,success,error,warning的相關實現,代碼仍是很簡單的,packages/yuansir/toastr/src/Toastr.php:
<?php namespace Yuansir\Toastr; use Illuminate\Session\SessionManager; use Illuminate\Config\Repository; class Toastr { /** * @var SessionManager */ protected $session; /** * @var Repository */ protected $config; /** * @var array */ protected $notifications = []; /** * Toastr constructor. * @param SessionManager $session * @param Repository $config */ public function __construct(SessionManager $session, Repository $config) { $this->session = $session; $this->config = $config; } public function render() { $notifications = $this->session->get('toastr:notifications'); if(!$notifications) { return ''; } foreach ($notifications as $notification) { $config = $this->config->get('toastr.options'); $javascript = ''; $options = []; if($config) { $options = array_merge($config, $notification['options']); } if($options) { $javascript = 'toastr.options = ' . json_encode($options) . ';'; } $message = str_replace("'", "\\'", $notification['message']); $title = $notification['title'] ? str_replace("'", "\\'", $notification['title']) : null; $javascript .= " toastr.{$notification['type']}('$message','$title');"; } return view('Toastr::toastr', compact('javascript')); } /** * Add notification * @param $type * @param $message * @param null $title * @param array $options * @return bool */ public function add($type, $message, $title = null, $options = []) { $types = ['info', 'warning', 'success', 'error']; if(!in_array($type, $types)) { return false; } $this->notifications[] = [ 'type' => $type, 'title' => $title, 'message' => $message, 'options' => $options ]; $this->session->flash('toastr:notifications', $this->notifications); } /** * Add info notification * @param $message * @param null $title * @param array $options */ public function info($message, $title = null, $options = []) { $this->add('info', $message, $title, $options); } /** * Add warning notification * @param $message * @param null $title * @param array $options */ public function warning($message, $title = null, $options = []) { $this->add('warning', $message, $title, $options); } /** * Add success notification * @param $message * @param null $title * @param array $options */ public function success($message, $title = null, $options = []) { $this->add('success', $message, $title, $options); } /** * Add error notification * @param $message * @param null $title * @param array $options */ public function error($message, $title = null, $options = []) { $this->add('error', $message, $title, $options); } /** * Clear notifications */ public function clear() { $this->notifications = []; } }
7.咱們看到view(‘Toastr::toastr’, compact(‘javascript’));,那麼就是須要一個視圖文件了,關於Toastr::toastr是什麼鬼咱們過會來講,新建 packages/yuansir/toastr/src/views/toastr.blade.php 視圖文件:
<link href="http://cdn.bootcss.com/toastr.js/latest/css/toastr.min.css" rel="stylesheet"> <script src="http://cdn.bootcss.com/toastr.js/latest/js/toastr.min.js"></script> <script type="text/javascript">{!! $javascript !!}</script>8.創建Facade,新建packages/yuansir/toastr/src/Facades/Toastr.php 就是引入了tastr插件,輸出咱們render方法中的$javascript
<?php namespace Yuansir\Toastr\Facades; use Illuminate\Support\Facades\Facade; class Toastr extends Facade { protected static function getFacadeAccessor() { return 'toastr'; } }
9.修改ToastrServiceProvider:
<?php namespace Yuansir\Toastr; use Illuminate\Support\ServiceProvider; class ToastrServiceProvider extends ServiceProvider { /** * Bootstrap the application services. * * @return void */ public function boot() { $this->loadViewsFrom(__DIR__ . '/views', 'Toastr'); $this->publishes([ __DIR__.'/views' => base_path('resources/views/vendor/toastr'), __DIR__.'/config/toastr.php' => config_path('toastr.php'), ]); } /** * Register the application services. * * @return void */ public function register() { $this->app['toastr'] = $this->app->share(function ($app) { return new Toastr($app['session'], $app['config']); }); } /** * Get the services provided by the provider. * * @return array */ public function provides() { return ['toastr']; } }
$this->loadViewsFrom(__DIR__ . ‘/views’, ‘Toastr’); 就是表示Toastr命名空間的視圖文件衝當前目錄的views目錄中渲染,因此咱們上面用 return view(‘Toastr::toastr’, compact(‘javascript’));
$this->publishes 在執行php artisan vendor:publish 時會將對應的目錄和文件複製到對應的位置
10.測試下是否可行,修改 config/app.php 添加以下:
/* |-------------------------------------------------------------------------- | Class Aliases |-------------------------------------------------------------------------- | | This array of class aliases will be registered when this application | is started. However, feel free to register as many as you wish as | the aliases are "lazy" loaded so they don't hinder performance. | */ 'aliases' => [ ...... 'Toastr' => Yuansir\Toastr\Facades\Toastr::class, ],
寫個控制器放進去試試:
<?php namespace App\Http\Controllers; use App\Http\Requests; use Illuminate\Http\Request; use Toastr; class HomeController extends Controller { /** * Create a new controller instance. * * @return void */ public function __construct() { //略 } /** * Show the application dashboard. * * @return \Illuminate\Http\Response */ public function index(Request $request) { Toastr::error('你好啊','標題'); return view('home'); } }
11.修改命名空間到包的composer.json,由於別人安裝這個包的時候不可能也去改項目composer.json的PSR-4的autoload,因此咱們把PSR-4的命名空間加到這個包的composer.json中去,修改packages/yuansir/toastr/src/composer.json 以下:
{ "name": "ryan/toastr-for-laravel", "description": "toastr.js for laravel5", "authors": [ { "name": "Ryan", "email": "yuansir@live.cn" } ], "require": {}, "autoload": { "psr-4": { "Yuansir\\Toastr\\": "src/" } } }
12.創建Github項目
將代碼push到項目中去:
$ cd packages/yuansir/toastr/ $ git init $ git add . $ git commit -m "add package source files." $ git remote add origin git@github.com:yuansir/toastr-for-laravel5.git $ git push -u origin master $ git tag -a 1.0.0 -m "version 1.0.0" $ git push --tags13.提交到Packagist,打開到 packagist.org,登錄後點擊右邊上角的 submit,並填入git的項目地址git@github.com:yuansir/toastr-for-laravel5.git 點擊 check 就OK了
到此結束,大功告成,這樣一個Laravel 的 composer 包就開發完成了。
這個教程的源碼和這個包的安裝使用方法詳見github https://github.com/yuansir/toastr-for-laravel5
若有問題歡迎指正!