イントロダクション
パッケージはLaravelに機能を追加する一番重要な方法です。パッケージとして何でも動作させることができます。たとえば日付ライブラリーであるCarbonや、振る舞い駆動開発(BDD)テストフレームワークのBehatなどです。
もちろんパッケージには色々な種類が存在しています。スタンドアローンで動作するパッケージがあります。動作させるのにLaravelに限らず、どんなフレームワークも必要としません。CarbonもBehatもスタンドアローンパッケージの例です。Laravelと一緒に使用するにはcomposer.json
ファイルでただ使用を指定するだけです。
逆にLaravelと一緒に使用することを意図したパッケージもあります。こうしたパッケージはLaravelアプリケーションを高めることを特に意図したルート、コントローラー、ビュー、設定を持つことでしょう。このガイドはLaravelに特化したパッケージの開発を主に説明します。
サービスプロバイダー
サービスプロバイダーはパッケージとLaravelを結びつけるところです。サービスプロバイダーは何かをLaravelのサービスコンテナと結合し、ビューや設定、言語ファイルのようなリソースをどこからロードするかをLaravelに知らせる責務を持っています。
サービスプロバイダーはIlluminate\Support\ServiceProvider
クラスを拡張し、register
とboot
の2メソッドを含んでいます。ベースのServiceProvider
クラスは、illuminate/support
Composerパッケージにあります。
サービスプロバイダーの構造と目的について詳細を知りたければ、ドキュメントを調べてください。
ルーティング
パッケージのルートを定義するには、パッケージのサービスプロバイダーのboot
メソッドからルートファイルをrequire
するだけです。ルートファイルの中は典型的なLaravelアプリケーションと同様にRoute
ファサードを使いルートを登録します。
/**
* サービス初期処理登録後の処理
*
* @return void
*/
public function boot()
{
if (! $this->app->routesAreCached()) {
require __DIR__.'/../../routes.php';
}
}
リソース
ビュー
パッケージのビューをLaravelへ登録するには、ビューがどこにあるのかLaravelに知らせる必要があります。そのためにはサービスプロバイダーのloadViewsFrom
メソッドを使用してください。loadViewsFrom
メソッドは2つの引数を取ります。ビューテンプレートへのパスと、パッケージの名前です。たとえばパッケージ名が"courier"であれば、以下の行をサービスプロバイダーのboot
メソッドに追加してください。
/**
* サービス初期処理登録後の処理
*
* @return void
*/
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}
パッケージのビューはダブルコロンを使うpackage::view
記法を使い参照します。ですからcourier
パッケージのadmin
ビューをロードするには、次のように書きます。
Route::get('admin', function () {
return view('courier::admin');
});
パッケージビューのオーバーライド
loadViewsFrom
メソッドを使用する場合、Laravelはビューの2つの場所を実際には登録します。一つはアプリケーションのresources/views/vendor
ディレクトリーで、もう一つは皆さんが指定したディレクトリーです。ではcourier
の例を使って確認しましょう。パッケージのビューがリクエストされると、Laravelは最初にresources/views/vendor/courier
の中にカスタムバージョンのビューが開発者により用意されていないかチェックします。カスタムビューが用意されていなければ、次にloadViewsFrom
の呼び出しで指定したパッケージビューディレクトリーを探します。この仕組みのおかげで、パッケージのビューがエンドユーザーにより簡単にカスタマイズ/オーバーライドできるようになっています。
ビューの公開
パッケージのビューをresources/views/vendor
ディレクトリーで公開したい場合は、サービスプロバイダーのpublishes
メソッドを使ってください。publishes
メソッドはパッケージのビューパスと対応する公開場所の配列を引数に取ります。
/**
* サービス初期処理登録後の処理
*
* @return void
*/
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
$this->publishes([
__DIR__.'/path/to/views' => base_path('resources/views/vendor/courier'),
]);
}
これであなたのパッケージのユーザーがLaravelのvendor::publish
Artisanコマンドを実行すると、パッケージのビューは指定された場所へコピーされます。
言語ファイル
パッケージに言語ファイルを含んでいる場合は、loadTranslationsFrom
メソッドでLaravelへどのようにロードするのかを知らせてください。たとえばパッケージ名がcourier
であれば、以下の行をサービスプロバイダーのboot
メソッドに追加します。
/**
* サービス初期処理登録後の処理
*
* @return void
*/
public function boot()
{
$this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
}
パッケージの言語行はダブルコロンを使うpackage::file.line
記法を使い参照します。ですからcourier
パッケージのmessages.php
ファイルからwelcome
行をロードする場合、次のようになります。
echo trans('courier::messages.welcome');
翻訳の公開
パッケージの翻訳をアプリケーションのresources/lang/vendor
ディレクトリーへ公開したい場合は、サービスプロバイダーのpublishes
メソッドを使ってください。publishes
メソッドはパッケージパスと対応する公開位置の配列を受け取ります。たとえば例のcourier
パッケージの翻訳ファイルを公開してみましょう。
/**
* サービスの起動登録後に実行
*
* @return void
*/
public function boot()
{
$this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
$this->publishes([
__DIR__.'/path/to/translations' => base_path('resources/lang/vendor/courier'),
]);
}
これでパッケージのユーザーが、Laravelのvendor:publish
Artisanコマンドを実行すると、パッケージの翻訳が指定した場所へ公開されます。
設定
通常、あなたのパッケージの設定ファイルをアプリケーション自身のconfig
ディレクトリーへ公開したいことでしょう。これにより、あなたのデフォルト設定オプションをユーザーに簡単にオーバーライドしてもらえるようになります。設定ファイルを公開するには、サービスプロバイダーのboot
メソッドで、publishes
メソッドを使用するだけです。
/**
* サービス初期処理登録後の処理
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/path/to/config/courier.php' => config_path('courier.php'),
]);
}
これであなたのパッケージのユーザーがLaravelのvendor:publish
コマンドを実行すると、ファイルが指定された場所へコピーされます。もちろん設定ファイルが一度公開されると、他の設定ファイル同様に設定内容へアクセスできるようになります。
$value = config('courier.option');
デフォルトパッケージ設定
もしくはあなたのパッケージ設定ファイルをアプリケーションのファイルへマージすることを選ぶこともできます。これにより設定の公開済ファイルの中で、実際にオーバーライドしたいオプションだけを含めてもらう指定方法をユーザーに取ってもらえます。設定ファイルをマージする場合はサービスプロバイダーのregister
メソッドで、mergeConfigFrom
メソッドを使います。
/**
* コンテナ結合の登録
*
* @return void
*/
public function register()
{
$this->mergeConfigFrom(
__DIR__.'/path/to/config/courier.php', 'courier'
);
}
公開アセット
パッケージにはJavaScriptやCSS、画像などのアセットを含むと思います。アセットを公開するには、サービスプロバイダーのboot
メソッドでpublishes
メソッドを使用してください。次の例では、関連するアセットをまとめて公開するためにpublic
アセットグループタグも追加指定しています。
/**
* サービス初期処理登録後の処理
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/path/to/assets' => public_path('vendor/courier'),
], 'public');
}
これにより、皆さんのパッケージのユーザーは、vendor:publish
コマンドを実行できるようになりました。実行すれば皆さんのファイルは指定された場所へコピーされます。通常、パッケージがアップデートされる度に、アセットを上書きする必要があります。--force
フラッグが使用できます
php artisan vendor:publish --tag=public --force
公開アセットをいつも確実にアップデートしたい場合は、このコマンドをcomposer.json
ファイルのpost-update-cmd
リストへ追加します。
ファイルグループの公開
アセットとリソースのパッケージグループを別々に公開したいこともあるでしょう。たとえばパッケージのアセットの公開を強要せずに設定ファイルを公開したい場合です。publishes
メソッドの呼び出し時の「タグ指定」で行えます。例としてパッケージのサービスプロバイダーのboot
メソッドで2つの公開グループを定義してみましょう。
/**
* サービス初期処理登録後の処理
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/../config/package.php' => config_path('package.php')
], 'config');
$this->publishes([
__DIR__.'/../database/migrations/' => database_path('migrations')
], 'migrations');
}
これでユーザーはvendor::publish
Artisanコマンドを使用するときにタグ名を指定することでグループを別々に公開できます。
php artisan vendor:publish --provider="Vendor\Providers\PackageServiceProvider" --tag="config"