تخصيص التّصفيح Pagination في Laravel


محمد أحمد العيل

يعدّ التصفيح Pagination (إعداد الصفحات) إحدى المهامّ الشائعة في مواقع الوِب، وهو ما دعا Laravel لتضمين هذه الوظيفة مبدئيا في إطار العمل. كانت تخصيص التصفيح في الإصدارات الأولى من Laravel بسهولة إعداد قالب Blade؛ إلا أن الأمر تغيّر في الإصدار 5.0، إذ عمل إطار العمل على تسهيل نظام التصفيح الذي يستخدمه لتمكن إعادة استخدامه في مشاريع لا تعتمد على إطار العمل Laravel. صاحب هذه العمليّة تعقيد في إمكانيّة تخصيص التصفيح.

3.png

يأتي الإصدار 5.3 لتصحيح هذه الوضعية وإعادة الأمور إلى نصابها.

تهيئة المشروع

سنهيّئ مشروع Laravel 5.3 للعمل عليه. نبدأ بالتثبيت:

 
composer create-project --prefer-dist laravel/laravel laravel53pagination "5.3.*"

يأتي المشروع مبدئيا بنموذج للمستخدم User، سنعمل من أجل الشرح على هذا النموذج. نبدأ بإعداد مسار للمستخدمين في ملف المسارات الخاصّ بالوِب routes/web.php:

Route::get('users', function () {
    return view('users.index')
        ->with('users', User::paginate(5));
});

يطلُب المسار users/ عند زيارته عرضَ القالب index.blade.php الموجود في المجلّد users ضمن مجلد القوالب resources/views. نمرّر للقالب المتغيّر users الذي يتلقّى نتيجة استدعاء الدالة paginate للحصول على المستخدمين المسجلين في قاعدة البيانات. ما يميّز هذه الدالة عن بقيّة الدوال الأخرى التي يمكن استدعاؤها في النموذج هي أنها توفّر إمكانية تطبيق الدالة links في قالب Blade من أجل إنشاء الصفحات، كما سنرى الآن.

ليس لدينا لحد الساعة المجلد users ولا الملف index.blade.php، ننشئ المجلد والملف بحيث يصبح مسار ملف القالب resources/views/users/index.blade.php ثم نفتحه ونضيف إليه المحتوى التالي:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"  >
<title> Document </title>
<link rel="stylesheet" href="/css/app.css">
<style type="text/css"> body { padding: 10em;}</style>
</head>
<body>
@foreach ($users as $user)
    <li>{{ $user->name }}</li>
@endforeach

{{ $users->links() }}
</body>
</html>

لدينا في أعلى الملف بضعة تعليمات للتنسيق، ثم تأتي في جسم المستند body التعليمة التكرارية foreach التي تمرّ على المستخدمين وتعرض أسماءهم، وفي الأخير الدالة links التي تحدثنا عنها أعلاه. يمكننا استدعاء هذه الدالة على المتغيّر users نظرا لأننا استخدمنا الدالة paginate في ملف المسارات للحصول على المستخدمين. تتكفّل الدالة links بإنشاء الصفحات عبر تقسيم المستخدمين على مجموعة من خمسة عناصر (مرّرنا المعطى 5 للدالة paginate في ملف المسارات).

بقي لنا بذر جدول المستخدمين حتى يمكننا تجربة ما أنجزناه لحد الآن:

 
php artisan make:seeder UsersTableSeeder

نستعين بمكتبة Faker لتوليد مستخدمين وهميين وبذر الجدول:

public function run()
{
  User::unguard();

  // نستخدم Faker لتوليد البيانات
  $faker = Faker\Factory::create();

  // إنشاء 20 مستخدما
  foreach(range(1, 20) as $index) {
      User::create([
          'name' => $faker->name,
          'email' => $faker->safeEmail,
          'password' => $faker->password,
      ]);
  }

  User::reguard();
}

لا تنس استيراد النموذج:

 
use App\User;

ثم نعدّل DatabaseSeeder لإضافة ملف البذر الذي أنشأناه للتو:

 
$this->call(UsersTableSeeder::class);

يمكننا الآن تنفيذ التهجيرات (تهجير المستخدم يأتي مبدئيا مع المشروع):

 
php artisan migrate

ثم بذر قاعدة البيانات:

 
php artisan db:seed

ثم تشغيل خادوم التطوير:

 
php artisan serve

تظهر عند زيارة الرابط http://localhost:8000/users قائمة بالمستخدمين مقسّمة على صفحات من خمسة مستخدمين.

01_pagination.png

عند النقر على رقم الصّفحة ينقلك إلى مجموعة جديدة من المستخدمين.

تخصيص التصفيح في Laravel

يوجد القالب المبدئي لروابط الصفحات على المسار vendor/laravel/framework/src/Illuminate/Pagination/resources/views إن أردت تخصيصه فسيتوجّب عليك نشره بالأمر التالي:

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

وستجد بضعة قوالب على المسار ressources/views/vendor/pagination.
يستخدم اثنان من هذه القوالب (bootstrap-4.blade.php وsimple-boostrap-4.blade.php) الإصدار 4 من Bootstrap والذي ما زال قيد التطوير؛ أما الآخران فأحدهما هو القالب المبدئي default.blade.php والآخر (simple-default.blade.php) نسخة مبسّطة منه لا تحوي سوى أزرار سابق ولاحق للتنقل بين الصفحات.

أدناه الشفرة الخاصّة بالقالب المبدئي:

@if ($paginator->hasPages())
    <ul class="pagination">
        {{-- Previous Page Link --}}
        @if ($paginator->onFirstPage())
            <li class="disabled"><span>«</span></li>
        @else
            <li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">«</a></li>
        @endif

        {{-- Pagination Elements --}}
        @foreach ($elements as $element)
            {{-- "Three Dots" Separator --}}
            @if (is_string($element))                    <li class="disabled"><span>{{ $element }}</span></li>
            @endif

            {{-- Array Of Links --}}
            @if (is_array($element))
                @foreach ($element as $page => $url)
                    @if ($page == $paginator->currentPage())
                        <li class="active"><span>{{ $page }}</span></li>
                    @else
                        <li><a href="{{ $url }}">{{ $page }}</a></li>
                    @endif
                @endforeach
            @endif
        @endforeach

        {{-- Next Page Link --}}
        @if ($paginator->hasMorePages())
            <li><a href="{{ $paginator->nextPageUrl() }}" rel="next">»</a></li>
        @else
            <li class="disabled"><span>»</span></li>
        @endif
    </ul>
@endif
  • تتيح الدالة hasPages التحقق من وجود صفحات لعرضها.
  • نتحقّق بالدالة onFirstPage من أننا على الصفحة الأولى.
  • يمكن بالدالة hasMorePages معرفة ما إذا كان لدينا مزيد من الصفحات لعرضها.
  • تطبع الدالتان previousPageUrl وnextPageUrlعلى التوالي رابطي الصفحة السابقة واللاحقة للصفحة الحالية التي نحصل عليها بالدالة currentPage.

سنعدّل الآن القالب بحيث نضع كلمة Previous (السابق) مكان الرمز »، على ألا تظهر عندما نكون على الصفحة الأولى.

02_pagination.png

نضع بنفس الطريقة كلمة Next (التالي) مكان «، على ألا تظهر عندما نكون على الصفحة الأخيرة.

03_pagination.png

نحصُل على الشفرة التاليّة:

@if ($paginator->hasPages())
    <ul class="pagination">
        {{-- Previous Page Link --}}
        @if (!$paginator->onFirstPage())
            <li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">Previous</a></li>
        @endif

        {{-- Pagination Elements --}}
        @foreach ($elements as $element)
            {{-- "Three Dots" Separator --}}
            @if (is_string($element))
                <li class="disabled"><span>{{ $element }}</span></li>
            @endif

            {{-- Array Of Links --}}
            @if (is_array($element))
                @foreach ($element as $page => $url)
                    @if ($page == $paginator->currentPage())
                        <li class="active"><span>{{ $page }}</span></li>
                    @else
                        <li><a href="{{ $url }}">{{ $page }}</a></li>
                    @endif
                @endforeach
            @endif
        @endforeach

        {{-- Next Page Link --}}
        @if ($paginator->hasMorePages())
            <li><a href="{{ $paginator->nextPageUrl() }}" rel="next">Next</a></li>
        @endif
    </ul>
@endif

احفظ التعديلات ثم أعد تنزيل الصفحة للحصول على نتيجة مشابهة لتلك الظاهرة في الصورتين أعلاه.





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن