イントロダクションIntroduction
他のフレームワークのペジネーションは苦痛に満ちています。Laravelはこれを簡単にしました。現在のページ位置に基づいて賢い「ページ範囲」のリンクを生成します。生成されるHTMLはBootstrap CSSフレームワークへ適応しています。In other frameworks, pagination can be very painful. Laravel makes it a breeze. Laravel can quickly generate an intelligent "range" of links based on the current page, and the generated HTML is compatible with the Bootstrap CSS framework[http://getbootstrap.com/].
基本的な使用法Basic Usage
ペジネーションクエリービルダーの結果Paginating Query Builder Results
アイテムをページ分けするには多くの方法があります。一番シンプルな方法はクエリービルダーかEloquentクエリーに、paginate
メソッドを用いることです。Laravelが提供するpaginate
メソッドは、ユーザーに表示している現在のページに基づいて正しいアイテム数とオフセットを指定する面倒を見ます。デフォルトではHTTPリクエストの?page
クエリー文字列引数の値により現在ページが決められます。もちろんこの値はLaravelにより自動的に決められ、さらにペジネーターが挿入するリンクを自動的に生成します。There are several ways to paginate items. The simplest is by using the paginate
method on the query builder[/docs/{{version}}/queries] or an Eloquent query[/docs/{{version}}/eloquent]. The paginate
method provided by Laravel automatically takes care of setting the proper limit and offset based on the current page being viewed by the user. By default, the current page is detected by the value of the ?page
query string argument on the HTTP request. Of course, this value is automatically detected by Laravel, and is also automatically inserted into links generated by the paginator.
最初にクエリーに対するpaginate
メソッドの呼び出しに注目しましょう。以下の例ではpaginate
に一つだけ引数を渡しており、「ページごと」に表示したいアイテム数です。この例ではページごとに15
アイテムを表示するように指定しています。First, let's take a look at calling the paginate
method on a query. In this example, the only argument passed to paginate
is the number of items you would like displayed "per page". In this case, let's specify that we would like to display 15
items per page:
<?php
namespace App\Http\Controllers;
use DB;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* アプリケーションの全ユーザー表示
*
* @return Response
*/
public function index()
{
$users = DB::table('users')->paginate(15);
return view('user.index', ['users' => $users]);
}
}
注意: 現在
groupBy
メソッドを使用したペジネーション操作は、Laravelで効率よく実行できません。groupBy
を使用したペジネーションを使用する必要がある場合はデータベースクエリーを実行し、その結果を元にペジネーターを自前で作成してください。Note: Currently, pagination operations that use agroupBy
statement cannot be executed efficiently by Laravel. If you need to use agroupBy
with a paginated result set, it is recommended that you query the database and create a paginator manually.
シンプル・ペジネーション"Simple Pagination"
「次」と「前」のリンクだけのシンプルなペジネーションビューを表示したい場合はsimplePaginate
メソッドを使用し、より効率的にクエリーすべきでしょう。これはビューに正確なページ番号を表示する必要がない、巨大なデータセットを扱う場合に便利です。If you only need to display simple "Next" and "Previous" links in your pagination view, you have the option of using the simplePaginate
method to perform a more efficient query. This is very useful for large datasets if you do not need to display a link for each page number when rendering your view:
$users = DB::table('users')->simplePaginate(15);
ページ付けしたEloquentの結果Paginating Eloquent Results
さらにEloquentモデルもペジネーションできます。例としてUser
モデルの15
アイテムをページ付け表示してみましょう。ご覧の通り、クエリービルダー結果のペジネーションを行う記法はきれいでわかりやすいものです。You may also paginate Eloquent[/docs/{{version}}/eloquent] queries. In this example, we will paginate the User
model with 15
items per page. As you can see, the syntax is nearly identical to paginating query builder results:
$users = App\User::paginate(15);
もちろんwhere
節のような制約をクエリーに指定した後にpaginate
を呼び出すこともできます。Of course, you may call paginate
after setting other constraints on the query, such as where
clauses:
$users = User::where('votes', '>', 100)->paginate(15);
Elqouentモデルをページづけするときにも、simplePaginate
メソッドを使用できます。You may also use the simplePaginate
method when paginating Eloquent models:
$users = User::where('votes', '>', 100)->simplePaginate(15);
ペジネタ―の自前生成Manually Creating A Paginator
渡された配列を元にして、ペジネーションインスンタンスを作成したいこともあります。必要に応じてIlluminate\Pagination\Paginator
か、Illuminate\Pagination\LengthAwarePaginator
インスタンスを生成することで実現できます。Sometimes you may wish to create a pagination instance manually, passing it an array of items. You may do so by creating either an Illuminate\Pagination\Paginator
or Illuminate\Pagination\LengthAwarePaginator
instance, depending on your needs.
Paginator
クラスは結果にセットされているアイテムの総数を知る必要はありません。そのためクラスは最終ページのインデックスを取得するメソッドを持っていません。LengthAwarePaginator
はPaginator
とほとんど同じ引数を取りますが、結果にセットされているアイテム総数も指定する必要がある点が異なっています。The Paginator
class does not need to know the total number of items in the result set; however, because of this, the class does not have methods for retrieving the index of the last page. The LengthAwarePaginator
accepts almost the same arguments as the Paginator
; however, it does require a count of the total number of items in the result set.
言い換えれば、Paginator
はクエリービルダーとEloquentに対するsimplePaginate
メソッドに対応し、一方のLengthAwarePaginator
はpaginate
に対応しています。In other words, the Paginator
corresponds to the simplePaginate
method on the query builder and Eloquent, while the LengthAwarePaginator
corresponds to the paginate
method.
自前でペジネーターインスタンスを生成する場合、ペジネーターに渡す結果の配列を自分で"slice"する必要があります。その方法を思いつかなければ、array_slice PHP関数を調べてください。When manually creating a paginator instance, you should manually "slice" the array of results you pass to the paginator. If you're unsure how to do this, check out the array_slice[http://php.net/manual/en/function.array-slice.php] PHP function.
ビューでの結果表示Displaying Results In A View
クエリービルダーかEloquentクエリーでpaginate
やsimplePaginate
メソッドを呼び出す場合、Illuminate\Pagination\LengthAwarePaginator
のインスタンスを受け取ります。simplePaginate
メソッドを呼び出した場合はIlluminate\Pagination\Paginator
インスタンスを受け取ります。これらのオブジェクトは結果を表すたくさんのメソッドを提供しています。こうしたヘルパーメソッドに加え、ペジネーターインスタンスはイテレータでもあり、配列としてループ処理できます。When you call the paginate
or simplePaginate
methods on a query builder or Eloquent query, you will receive a paginator instance. When calling the paginate
method, you will receive an instance of Illuminate\Pagination\LengthAwarePaginator
. When calling the simplePaginate
method, you will receive an instance of Illuminate\Pagination\Paginator
. These objects provide several methods that describe the result set. In addition to these helpers methods, the paginator instances are iterators and may be looped as an array.
つまり結果を取得したら、その結果とページリンクをBladeを使い表示できます。So, once you have retrieved the results, you may display the results and render the page links using Blade[/docs/{{version}}/blade]:
<div class="container">
@foreach ($users as $user)
{{ $user->name }}
@endforeach
</div>
{!! $users->render() !!}
render
メソッドは他のページヘのリンクをレンダーします。それらの各リンクには?page
クエリー文字列変数が含まれています。render
メソッドが生成するHTMLはBootstrap CSSフレームワークと互換性があることを覚えておいてください。The render
method will render the links to the rest of the pages in the result set. Each of these links will already contain the proper ?page
query string variable. Remember, the HTML generated by the render
method is compatible with the Bootstrap CSS framework[https://getbootstrap.com].
注意: Bladeテンプレートで
render
メソッドを呼び出すときは、HTMLリンクがエスケープされないよう、確実に{!! !!}
記法を使ってください。Note: When calling therender
method from a Blade template, be sure to use the{!! !!}
syntax so the HTML links are not escaped.
ペジネーターURIのカスタマイズCustomizing The Paginator URI
setPath
メソッドにより、ペジネーターがリンクを生成するときに使用するURIをカスタマイズできます。たとえばペジネーターでhttp://example.com/custom/url?page=N
のようなリンクを生成したい場合、setPath
メソッドにcustom/url
を渡してください。The setPath
method allows you to customize the URI used by the paginator when generating links. For example, if you want the paginator to generate links like http://example.com/custom/url?page=N
, you should pass custom/url
to the setPath
method:
Route::get('users', function () {
$users = App\User::paginate(15);
$users->setPath('custom/url');
//
});
ペジネーションリンクの追加Appending To Pagination Links
ペジネーションリンクにクエリー文字列を付け加えたいときは、appends
メソッドを使います。たとえば&sort=votes
を各ペジネーションリンクに追加する場合には、以下のようにappends
を呼び出します。You may add to the query string of pagination links using the appends
method. For example, to append &sort=votes
to each pagination link, you should make the following call to appends
:
{!! $users->appends(['sort' => 'votes'])->render() !!}
ペジネーションのURLに「ハッシュフラグメント」を追加したい場合は、fragment
メソッドが使用できます。例えば各ペジネーションリンクの最後に#foo
を追加したい場合は、以下のようにfragment
メソッドを呼び出します。If you wish to append a "hash fragment" to the paginator's URLs, you may use the fragment
method. For example, to append #foo
to the end of each pagination link, make the following call to the fragment
method:
{!! $users->fragment('foo')->render() !!}
その他のヘルパーメソッドAdditional Helper Methods
さらに以下のようなペジネーターインスタンスのメソッドにより、追加のペジネーション情報へアクセスできます。You may also access additional pagination information via the following methods on paginator instances:
$results->count()
$results->count()
$results->currentPage()
$results->currentPage()
$results->hasMorePages()
$results->hasMorePages()
$results->lastPage() (simplePaginateでは使用不可)
$results->lastPage() (Not available when using simplePaginate)
$results->nextPageUrl()
$results->nextPageUrl()
$results->perPage()
$results->perPage()
$results->previousPageUrl()
$results->previousPageUrl()
$results->total() (simplePaginateでは使用不可)
$results->total() (Not available when using simplePaginate)
$results->url($page)
$results->url($page)
結果のJSON変換Converting Results To JSON
Laravelのペジネーター結果クラスはIlluminate\Contracts\Support\JsonableInterface
契約を実装しており、toJson
メソッドを提示しています。ですからペジネーション結果をJSONにとても簡単に変換できます。The Laravel paginator result classes implement the Illuminate\Contracts\Support\JsonableInterface
contract and expose the toJson
method, so it's very easy to convert your pagination results to JSON.
またルートやコントローラーアクションからシンプルにペジネーターインスタンスを返せば、JSONへ変換されます。You may also convert a paginator instance to JSON by simply returning it from a route or controller action:
Route::get('users', function () {
return App\User::paginate();
});
ペジネーターのJSON形式はtotal
、current_page
、last_page
などのメタ情報を含んでいます。実際の結果オブジェクトはJSON配列のdata
キーにより利用できます。ルートから返されたペジネーターインスタンスにより生成されるJSONの一例を見てください。The JSON from the paginator will include meta information such as total
, current_page
, last_page
, and more. The actual result objects will be available via the data
key in the JSON array. Here is an example of the JSON created by returning a paginator instance from a route:
ペジネーターJSONの一例Example Paginator JSON
{
"total": 50,
"per_page": 15,
"current_page": 1,
"last_page": 4,
"next_page_url": "http://laravel.app?page=2",
"prev_page_url": null,
"from": 1,
"to": 15,
"data":[
{
// 結果のオブジェクト
},
{
// 結果のオブジェクト
}
]
}