ترقيم الصفحات Pagination في Laravel

من موسوعة حسوب
< Laravel
مراجعة 13:21، 23 أكتوبر 2018 بواسطة رؤيا-بنعطية (نقاش | مساهمات) (استبدال النص - '\[\[تصنيف:(.*)\]\]' ب'{{SUBPAGENAME}}')
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)
اذهب إلى التنقل اذهب إلى البحث
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

مقدمة

كثيرًا ما يكون ترقيم الصفحات في الأطر الأخرى متعبًا جدًا. هنا في Laravel، دُمج مُرقّم صفحات Laravel مع منشئ الاستعلامات و رابط الكائنات بالعلاقات Eloquent، وهو يوفّر ترقيم صفحات لنتائج قواعد البيانات سهل الاستخدام فورًا. يتوافق HTML المُنشئ بواسطة مُرقّم الصفحات مع إطار عمل Bootstrap CSS.

الاستخدام الأساسي

ترقيم نتائج صفحات منشئ الاستعلام

هناك عدّة طرق لترقيم العناصر. أبسطها باستخدام التابع paginate على منشئ الاستعلامات أو Eloquent الاستعلامات.

يهتم التابع paginate تلقائيًا بإعداد الحد و والإزاحة (offset) المناسبة استنادًا على الصفحة الحالية التي يشاهدها المستخدم. تُكتشف الصفحة الحاليّة افتراضيًّا بواسطة قيمة مُتغيّر سلسلة استعلام page النصيّة على الطلب HTTP. تُكتشف هذه القيمة تلقائيًا طبعًا بواسطة Laravel، وتُدرج أيضًا تلقائيًا في الروابط التي يُولّدها paginator.

المتغيّر الوسيط الوحيد الممرّر للتابع paginate في هذا المثال هو عدد العناصر التي تريد عرضها "لكل صفحة". فلنحدّد في هذه الحالة أننا نودّ عرض 15 عنصرًا في كل صفحة:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\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 مع مجموعة نتائج مرقّمة الصفحات.

"ترقيم الصفحات البسيط"

تستطيع استخدام التابع simplePaginate إن احتجت فقط لعرض روابط "التالي" و "السابق" البسيطة في عرض ترقيم الصفحات لتنفيذ استعلام أكثر كفاءة. هذا مفيد جدًا لمجموعات البيانات الضخمة عندما لا تحتاج لعرض رابط لكل رقم صفحة عند العرض:

$users = DB::table('users')->simplePaginate(15);

ترقيم النتائج Eloquent

تستطيع أيضًا ترقيم صفحات الاستعلامات Eloquent. سنرقّم في هذا المثال صفحات النموذج User مع 15 عنصرًا في الصفحة. صيغة الجملة كما ترى تُطابق تقريبًا نتائج ترقيم صفحات منشئ الاستعلامات:

$users = App\User::paginate(15);

تستطيع مناداة التابع paginate عند تحديد قيود أخرى على الاستعلام مثل البنود where:

$users = User::where('votes', '>', 100)->paginate(15);

تستطيع أيضًا استخدام التابع simplePaginate عند ترقيم النماذج Eloquent:

$users = User::where('votes', '>', 100)->simplePaginate(15);

إنشاء مُرقّم صفحات يدويًّا

قد ترغب أحيانًا في إنشاء نسخة ترقيم الصفحات يدويًا وتمريرها عبر مصفوفة من العناصر. تستطيع فعل هذا عن طريق إنشاء نسخة Illuminate\Pagination\Paginator أو Illuminate\Pagination\LengthAwarePaginator حسب الحاجة.

لا يحتاج الصنف Paginator لمعرفة العدد الإجمالي للعناصر في مجموعة النتائج؛ ولكن لهذا السبب لا يحتوي الصنف على أساليب لاسترداد فهرس الصفحة الأخير. يقبل LengthAwarePaginator تقريبًا نفس متغيّرات Paginator الوسيطة؛ باستثناء احتياجه للعدد الإجمالي لعناصر مجموعة النتائج.

أي بعبارة أخرى، Paginator يوافق التابع simplePaginate بمنشئ الاستعلامات و Eloquent في حين يوافق LengthAwarePaginator التابع paginate.

ملاحظة: يجب أن "تُقسّم" يدويًا مصفوفة النتائج التي تمررها لمرقّم الصفحات عند إنشاء نسخة منه يدويًا. اقرأ المزيد عن الدالّة array_slice إن كنت غير متأكّد من كيفيّة استعمالها.

عرض نتائج ترقيم الصفحات

ستتلقّى نسخة Illuminate\Pagination\LengthAwarePaginator عند مناداة التابع paginate. ستتلقّى عند مناداة التابع simplePaginate نسخة من Illuminate\Pagination\Paginator. توفّر هذه الكائنات عدّة توابع تصف مجموعة النتائج. إضافةً لهذه التوابع، نسخ paginator هي عناصر تكراريّة يمكن تدويرها في حلقة (loop) كمصفوفة.

وهكذا تستطيع عرض النتائج بمجرد استردادها، وعرض روابط الصفحات باستخدام Blade:

<div class="container">
    @foreach ($users as $user)
        {{ $user->name }}
    @endforeach
</div>

{{ $users->links() }}

سيعرض التابع links الروابط لبقية الصفحات في مجموعة النتائج. يحتوي كل من هذه الروابط متغيّر سلسلة استعلام page النصيّة المناسب مسبقًا. تذكّر أن HTML الذي يُنشئه التابع links يوافق إطار العمل Bootstrap CSS.

تخصيص رابط المرقِّم Paginator URI

يسمح لك التابع withPath بتخصيص الرابط URI المُستخدم من طرف مرقّم الصفحات عند إنشاء الروابط. إن أردت مثلًا أن ينشئ المرقّم ارتباطات مثل http://example.com/custom/url?page=N يجب تمرير custom/url للتابع withPath:

Route::get('users', function () {
    $users = App\User::paginate(15);

    $users->withPath('custom/url');

    //
});

إلحاق ارتباطات الصفحات

تستطيع إلحاق (append) سلسلة الاستعلام النصيّة لروابط ترقيم الصفحات باستخدام التابع appends. كي تُلحق sort=votes مثلًا بكل رابط ترقيم صفحات، يجب استدعاء appends كما يلي:

{{ $users->appends(['sort' => 'votes'])->links() }}

تستطيع استخدام التابع fragment إن رغبت في إلحاق "جزء شفرة" بعناوين مرقّم الصفحات URL. استدعِ التابع fragment كما يلي لإلحاق foo# مثلًا بنهاية كل رابط ترقيم الصفحات:

{{ $users->fragment('foo')->links() }}

تحويل النتائج إلى JSON

تُنفّذ أصناف نتائج مرقّم الصفحات عقود الواجهة Illuminate\Contracts\Support\Jsonable وتعرض التابع toJson، لذلك يسهل تحويل نتائج ترقيم الصفحات إلى JSON. تستطيع أيضًا تحويل نسخة مرقّم الصفحات إلى JSON عبر ردّه من مسار أو إجراء وحدة تحكّم (controller action):

Route::get('users', function () {
    return App\User::paginate();
});

سيشمل JSON مرقّم الصفحات معلوماتًا وصفيّةً مثل total last_page current_page و last_page والمزيد. ستكون كائنات النتائج الفعلية متاحة عبر المفتاح data في المصفوفة JSON. في ما يلي مثال على JSON أُنشئ عن طريق رد نسخة مرقّم صفحات من مسار:

{
   "total": 50,
   "per_page": 15,
   "current_page": 1,
   "last_page": 4,
   "first_page_url": "http://laravel.app?page=1",
   "last_page_url": "http://laravel.app?page=4",
   "next_page_url": "http://laravel.app?page=2",
   "prev_page_url": null,
   "path": "http://laravel.app",
   "from": 1,
   "to": 15,
   "data":[
        {
            // Result Object
        },
        {
            // Result Object
        }
   ]
}

تخصيص عرض مرقّم الصفحات

توافق العروض المستخدمة لعرض روابط ترقيم الصفحات مع إطار العمل Bootstrap CSS افتراضيًّا. ولكن تستطيع في حال لم تستخدم Bootstrap تعريف عروضك بنفسك لعرض هذه الروابط. مرّر عند مناداة التابع links في نسخة مرقّم صفحات اسم عرض كأوّل متغيّر وسيط بالتابع:

{{ $paginator->links('view.name') }}

// تمرير المعطيات للعرض...
{{ $paginator->links('view.name', ['foo' => 'bar']) }}

يظل تصدير عروض (views) مرقّم صفحاتك للمجلّد resources/views/vendor باستخدام الأمر vendor:publish أسهل طريقة لتخصيصها:

php artisan vendor:publish --tag=laravel-pagination

سيضع هذا الأمر العروض في المجلّد resources/views/vendor/pagination. يوافق الملف bootstrap-4.blade.php داخل هذا المجلّد عرض ترقيم الصفحات الافتراضي. تستطيع تعديل هذا الملف لتعديل ترقيم الصفحات HTML. تستطيع استخدام تابعي مرقّم الصفحات الافتراضيين defaultView و defaultSimpleView في AppServiceProvider إن أردت تعيين ملف مختلف كعرض ترقيم الصفحات الافتراضي:

use Illuminate\Pagination\Paginator;

public function boot()
{
    Paginator::defaultView('pagination::view');

    Paginator::defaultSimpleView('pagination::view');
}

توابع نُسخ مرقّم الصفحات

تُوفّر كل نُسخ مرقّم الصفحات معلومات إضافية عن ترقيم الصفحات عبر التوابع التالية:

  •  ()‎$results->count
  •  () ‎  $results->currentPage
  •  () ‎  $results->firstItem
  •  () ‎   $results->hasMorePages
  •  () ‎   $results->lastItem
  •  () ‎   $results->lastPage (غير متوافرة عند استخدام simplePaginate)
  •  ()  ‎  $results->nextPageUrl
  •   () ‎  $results->onFirstPage
  •   () ‎  $results->perPage
  •  () ‎  $results->previousPageUrl
  •   () ‎  $results->total (غير متوافرة عند استخدام simplePaginate)
  •   (‎  $results->url($page

مصادر