اذهب إلى المحتوى

سمير عبود

الأعضاء
  • المساهمات

    3473
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    34

كل منشورات العضو سمير عبود

  1. الكلمة المحجوزة let تُستخدم عند التصريح عن متغير جديد، مثلها مثل var و const، يمكنك الإطلاع على المساهمة التالية لمعرفة الفروقات بينها: كما يُمكنك الإطلاع على المقال التالي الذي يشرح المتغيرات في جافاسكربت: ما يتم كتابته بين أقواس الدوال عند التصريح عنها يُسمى معاملات أو وسائط الدالة و تستخدم لتنوب و تستقبل البيانات التي تُمرر لاحقاً للدالة عند إستدعائها الدرس التالي يشرح عن الدوال و قواعد التصريح عنها بالتالي هذا من قواعد اللغة نفسها التي يجب إحترامها، عند التصريح عن دالة بمعاملات، و إستدعاء تلك الدالة و تمرير قيم للمعاملات سيتم تلقائيا من اللغة نفسها تعريف متغيرات محلية بتلك الأسماء و تمرير تلك القيم لها، و يكون نطاق التعرف على تلك المتغيرات هو الدالة نفسها بحيث لا يمكن التعرف على تلك المتغيرات خارج نطاق الدالة.
  2. إستخدم التابع JSON.stringify لتحويل المصفوفة إلى قيمة نصية و إرسالها عبر Ajax بالشكل التالي: data: JSON.stringify(data), ثم في المتحكم يمكنك إعادة تحويل البيانات الى مصفوفة من خلال الدالة json_decode بالشكل التالي: $PostRequest = json_decode($request->getContent()); ثم معالجتها الطلب كما تريد.
  3. السبب في ذلك أنه عند الوصول للعلاقة كخاصية فإن الراجع هو كائن من النوع Collection (مجموعة كائنات) في حالتك سيتم إرجاع كافة طلبات العضو (أي مجوعة كائنات من الصنف Order كل كائن يعبر عن طلب) ، و التابع exists غير متاح كتابع للصنف Collection. يُمكنك الوصول للعلاقة كتابع بالشكل ()orders حينها يمكنك إستخدام التابع exists كما يلي: auth()->user()->orders()->where('user_id', $product->id)->exists() أو يمكنك استخدام حلول بديلة للتابع exists مع المجموعات Collections، كالتابع contains: auth()->user()->orders->contains('user_id', $product->id) أو إستخدام التابع count الذي يُعيد عدد العناصر المطابقة، و بعده يمكنك مقارنة الراجع مع العدد 0 بالشكل التالي: @if(auth()->user()->orders->where('user_id', $product->id)->count() > 0)
  4. الخطأ بسبب: <?php namespace Tests; use PHPUnit\Framework\TestCase as BaseTestCase; // use Illuminate\Foundation\Testing\TestCase as BaseTestCase; abstract class TestCase extends BaseTestCase تقوم بعمل extends للصنف: use PHPUnit\Framework\TestCase as BaseTestCase; هذا الصنف لا يحتوي على توابع التفاعل مع طلبات http مثل get، post، put و غيرها. الصنف المهيأ مُسبقاً لعمل ذلك هو: use Illuminate\Foundation\Testing\TestCase as BaseTestCase; لأنه يستعمل ال Trait: Illuminate\Foundation\Testing\Concerns\MakesHttpRequests; الذي يتيح استعمال تلك التوابع. ويقوم بوراثة الصنف: use PHPUnit\Framework\TestCase as BaseTestCase; مُسبقاً، و يضيف عليه أشياء أخرى. فالحل فقط بتغيير الصنف الذي ترث منه أصناف الإختبار: <?php namespace Tests; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; //use PHPUnit\Framework\TestCase as BaseTestCase; abstract class TestCase extends BaseTestCase
  5. Eloquent يفترض أن إسم الجدول الخاص بالنموذج Utilizador هو utilizadors لكن الإسم لديك هو utilizador إما تتبع العُرف و تُعيد تسمية الجدول بالشكل المطلوب، أو تقوم بضبط اسم الجدول من خلال الخاصية table في النموذج بالشكل التالي: <?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Utilizador extends Model { /** * The table associated with the model. * * @var string */ protected $table = 'utilizador'; // وضع اسم الجدول الخاص بك }
  6. يُمكنك إنشاء خاصية إفتراضية بداخل النموذج بالشكل التالي عن طريق إستخدام الموصلات (Accessors): public function getTitleBodyAttribute() { return $this->title . ' ' . $this->body; } في النُسخ الحديثة يُمكنك إستخدام الطريقة أعلاه أو الطريقة التالية: use Illuminate\Database\Eloquent\Casts\Attribute; protected function titleBody(): Attribute { return Attribute::make( get: fn () => $this->title . ' ' . $this->body, ); } بعد جلب البيانات ستتمكن من الوصول للخاصية title_body من الكائن لكن لن تظهر مع البيانات، إن أردت ذلك يجب إضافتها إلى المصفوفة appends: protected $appends = [ 'title_body' ];
  7. أنت تستخدم في مشروعك الإصدار الخامس من مكتبة بوتستراب بينما في المثال الذي أرفقته يستخدمون الإصدار الرابع، هناك بعض الإختلافات في النافذة المنبثقة، في الإصدار الرابع يستخدمون data-toggle بينما في الإصدار الخامس يستخدمون data-bs-toggle نفس الشيء بخصوص data-target لذلك حتى تعمل النافذة المنبثقة بشكل صحيح عليك إستبدال التالي في الروابط التشعبية a التي تحيط الصور: data-toggle="modal" بـ: data-bs-toggle="modal" و: data-target="#image-gallery" بـ: data-bs-target="#image-gallery" نفس الشيء بخصوص زر إخفاء النافذة المنبثقة: data-bs-dismiss="modal" و أيضاً عليك تغيير الصنف float-left إلى float-start حتى تتموضع أيقونات الأسهم بشكل صحيح.
  8. من خلال الصورة التي أرفقتها يظهر أن ملف الفيديو يتواجد في نفس المسار الذي يتواجد به ملف ال html يُمكنك إستخدام مسار نسبي بالشكل التالي: <video controls> <source src="fd.mp4" type="video/mp4"> Your browser does not support the html video tag. </video> قم بحفظ الملف و حدث الصفحة.
  9. يُمكنك إستخدام خطوط google بعد إختيار الخط الذي تريد إستعماله، تدخل لصفحة الخط و تُحدد الأحجام التي تريدها بعد ذلك من القائمة الجانبية ستجد قائمة للخطوط التي أخترتها مثلاً خط Cairo و ستجد طريقتين إما عبر وسم link من خلال html أو عبر import من خلال css: <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Cairo:wght@200;500&display=swap" rel="stylesheet"> تضع الأسطر في وسم ال head ثم تستخدم الخط من خلال الخاصية font-family و تحدده للعناصر التي تريدها: font-family: 'Cairo', sans-serif; نفس الشيء إن أردت إستخدام import في أعلى ملف css تستدعي ملف الخط: @import url('https://fonts.googleapis.com/css2?family=Cairo:wght@200;500&display=swap'); ثم تستخدم الخط بنفس الطريقة. هناك طريقة أخرى و هي إستعمال قاعدة font-face في css إن كنت تملك ملفات الخطوط التي تريد إستعمالها و قمت مسبقاً بتنزيلها الطريقة كالآتي: @font-face { font-family: myFirstFont; src: url(sansation_light.woff); } نُحدد إسم الخط من خلال font-family و من خلال src نضع مسار ملف الخط، ثم نستعمل الإسم على العناصر التي نريد تطبيق الخط فيها. ستجد أسفله بعض المصادر عن كيفية تضمين خطوط خارجية في مشروعك: القاعدة font-face على موسوعة حسوب
  10. أهلاً بك، بخصوص سؤالك الأول فالمطلوب أن ترفع المشاريع التي تُنجزها خلال الدورة إلى حسابك في github، هناك مسارات في الدورة تتعلق بالأساسيات، و مسارات أخرى تطبيقية نقوم فيها بإنجاز مشاريع تدريبية، تلك المشاريع ستُنجزها مع المُدرب من خلال الدروس، و هي ما ستقوم برفع ملفاتها على github. بخصوص مُشكلتك الثانية فتحتاج إلى إتباع الخُطوات المطلوبة لإنشاء الحساب، ستُدخل معلوماتك البريد و كلمة المرور و اسم المُستخدم، بعدها سيطلب منك إثبات أنك لست روبوت، سيُعطيك مهمة عن طريق صور بعد تجاوزها سيطلب منك ادخال كود قد أرسله لك في بريدك الذي أدخلته للتحقق من أنك مالك لذلك البريد.
  11. إذا قمت بكل شيء كما شرحت، ربما التطبيق يعمل بالكاش حاول مسحه عن طريق تنفيذ الأمر php artisan optimize:clear
  12. يبدو أنك لم تنتبه إلى الإجابة ما كتبته في الخاصية href هنا: <a class="dropdown-item" href="{{route('categories.create')}}"> Create </a> ذلك يُشير إلى الإسم الذي أعطيته للمسار هنا: Route::get('categories/create', [CategoriesController::class, 'create'])->name('categories.create'); لاحظ في التابع name هناك نُحدد إسم المسار. أما الموجود هنا: return view('categories.create'); فذلك يعني إرجاع صفحة العرض create.blade.php الموجودة في المجلد categories في مجلد ال views. و التي ذكرت أنه يجب إنشاؤها هنا:
  13. تُستخدم with لتحميل العلاقات بشكل حثيث لتقليل عدد الاستعلامات و يُسمى المصطلح باللغة الإنجليزية Eager loading يُمكنك الإطلاع على: التحميل الحثيث Eager loading لفهم المغزى من إستخدام with، و الهدف كما قلت هو معالجة مشكلة (N+1) خصوصاً عند الوصول للعلاقة على شكل خاصية في الحلقات يوجد في الرابط أعلاه مثال لنموذج الكتاب (Book) و نموذج الكاتب (Author) و العلاقة واحد لكثير. عند جلب كافة الكتب ثم في الحلقة نصل لإسم الكاتب عبر العلاقة بالشكل التالي: $books = Book::all(); foreach ($books as $book) { echo $book->author->name; } ذلك يعني إستعلام واحد لجلب كافة الكتب، ثم في الحلقة من أجل كل كتاب إستعلام إضافي لجلب الكاتب. و هذا النوع من التحميل يُسمى التحميل الكسول و هنا مُشكلة الإستعلامات (N + 1)، أما بإستخدام with نقوم بتحميل العلاقة بشكل مُسبق مع الإستعلام الأولي. ( أي إستعلام لجلب كافة الكتب و إستعلام واحد فقط إضافي لجلب الكُتاب)
  14. لديك بعض الأخطاء في تعريف العلاقات، عندما نتحدث عن السعر فهو ينتمي لمنتج و ينتمي لمتجر: ProductPrice: belongsTo Product belongsTo Store أما عندما نتحدث عن المنتج فنقول أن المنتج لديه عدة أسعار، و موجود في عدة متاجر: Product hasMany ProductPrice belongsToMany Store أما عندما نتحدث عن المتجر فنقول أنه يبيع عدة منتجات و لديه عدة أسعار: Store: hasMany ProductPrice belongsToMany Product العلاقة بين المتجر و المنتج هي كثير لكثير و الجدول الوسيط هو product_prices. توابع العلاقات نُعرفها عامة public و ليس protected، أيضاً عند تعريفك للمفاتيح الأولية لم تتبع العُرف لارافل يستخدم id و عليه يجب عليك إعادة تعريف خاصية المفتاح الأولي لكل نموذج و وضع اسم العمود، مثلا في النموذج Product: protected $primaryKey = 'product_id'; و في النموذج Store: protected $primaryKey = 'store_id'; و في النموذج ProductPrice: protected $primaryKey = 'productPrice_id'; و نفس الأمر بالنسبة للبقية. عليه عند تعريف العلاقات في النموذج ProductPrice نكتب: public function product() { return $this->belongsTo(Product::class, 'product_id', 'product_id'); } public function store() { return $this->belongsTo(Store::class, 'store_id', 'store_id'); } يجب تمرير أسماء الحقول الثانوية في المعاملات (الثاني و الثالث) لأنك غيرت و لم تتبع العرف في التسمية و إن لم تمرر الأسماء الصحيحة ستحدث أخطاء. في النموذج Product: public function prices(){ return $this->hasMany(ProductPrice::class, 'product_id', 'product_id'); } public function stores() { return $this->belongsToMany(Store::class, 'product_prices', 'product_id', 'store_id'); } أما بالنسبة للنموذج Store: public function prices(){ return $this->hasMany(ProductPrice::class, 'store_id', 'store_id'); } public function products() { return $this->belongsToMany(Product::class, 'product_prices', 'store_id', 'product_id'); } أخيراً في المتحكم يُمكنك جلب البيانات بالشكل الذي تريد مثلاً: $products = Product::with('prices', 'prices.store')->get(); $stores = Store::with('prices', 'prices.product')->get(); return view('test', compact('products', 'stores')); في ملف العرض يُمكنك الوصول للبيانات بالشكل التالي: <h2>Products</h2> <ol> @foreach($products as $product) <li> {{ $product->productName }} <ul> @foreach($product->prices as $price) <li> <strong>Store: </strong> {{ $price->store->storeName }} / <strong>Price: </strong> {{ $price->productPrice }} </li> @endforeach </ul> </li> @endforeach </ol> <hr> <h2>Stores</h2> <ol> @foreach($stores as $store) <li> {{ $store->storeName }} <ul> @foreach($store->prices as $price) <li> <strong>Product: </strong> {{ $price->product->productName }} / <strong>Price: </strong> {{ $price->productPrice }} </li> @endforeach </ul> </li> @endforeach </ol> قمت ببذر بعض البيانات و كانت النتيجة كالتالي: ركزت فقط على النماذج الثلاثة Product و ProductPrice و Store و الحالة التي ذكرتها، بقية النماذج عليك تعريف العلاقات فيها بنفس الشكل.
  15. في ملف app.blade.php لديك القائمة المنسدلة التالية: <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Posts me </a> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="{{route('post.create')}}"> Create </a> <a class="dropdown-item" href="#" > Anouther action</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#"> Something else here </a> </div> </li> تقوم بنسخها و تُعدل عليها بالشكل التالي: <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Posts me </a> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="{{route('post.create')}}"> Create </a> <a class="dropdown-item" href="#" > Anouther action</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#"> Something else here </a> </div> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Categories </a> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="{{route('categories.create')}}"> Create </a> <a class="dropdown-item" href="#" > Anouther action</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#"> Something else here </a> </div> </li> ثم في ملف web.php ستقوم بإضافة مسارين أحدها لعرض إستمارة الإضافة و الثاني لإستقبال الطلبية و معالجتها: Route::get('categories/create', [CategoriesController::class, 'create'])->name('categories.create'); Route::post('categories', [CategoriesController::class, 'store'])->name('categories.store'); و في الأعلى تستدعي صنف المتحكم: use App\Http\Controllers\CategoriesController; في التابع create نقوم بإرجاع صفحة العرض: public function create() { return view('categories.create'); } ثم نقوم بإنشاء ملف العرض create.blade.php في المسار views/categories و نضع بداخله: @extends('layouts.app') @section('content') {{-- هنا تضع محتوى الإستمارة و الحقول التي تريدها و عرض رسائل التحقق و ما إلى ذلك --}} @endsection يمكنك إستنساخ الإستمارة من إستمارة انشاء منشور لديك و تُعدل عليها. و أيضاً توجه الطلب بعد الإرسال إلى المسار الثاني أي أنك في الخاصية action ستكتب: action="{{ route('categories.store') }}" تحتاج أيضاً إلى تحديد حقول القسم في ملف التهجير الخاص بالأقسام، أي الأعمدة في جدول بيانات الأقسام و تقوم بتهجير الملف لتظهر الأعمدة في جدول الأقسام و تحتاج أيضاً إلى معالجة الطلب في التابع store الخاص بالمتحكم Categories. الأمر بسيط لكن يتوجب فهم بالأساسيات الخاصة بلغة HTML و أساسيات إطار لارافل.
  16. يرجي إرفاق مجلد المشروع كاملاً على شكل ملف مضغوط لنتمكن من مساعدتك
  17. ما هي المشكلة الآن، و ما الخطأ الذي يظهر لك
  18. سيكون لديك رابط تشعبي، في html نصف العُنصر بـ a لذلك سيكون مشابه للشكل التالي: <a href="/categories/create">Create</a> بحيث لما تضغط على الرابط يُحولك لل uri: domain.test/categories/create هي عبارة عن إستمارة (form) بها الحقول الخاصة بالقسم. يجب أن يكون لديك معرفة بسيطة بالوسوم الخاصة بـ HTML
  19. يمكنك التواصل مع مركز المساعدة وشرح الأمر لهم وسيساعدونك ويوضحوا لك كل ما تريده بهذا الخصوص
  20. هل المُشكلة لديك في إظهار القائمة المنسدلة أم في التوجيه إلى صفحة إنشاء القسم. إظهار القائمة المنسدلة أمر بسيط كما فعلت في القائمة المنسدلة الأولى تنسخها و تغير النصوص، و تحتاج أن تغير الرابط الخاص بـ create إلى الرابط الذي يقود إلى صفحة إنشاء القسم، مثلاً في الخاصية href تضع: /categories/create ثم تعرف ذلك المسار في ملف web: Route::get('/categories/create', [CategoriesController::class, 'create']); بشرط أن يكون لديك متحكم بالإسم CategoriesController أو ضع المتحكم الذي أنشأته لا أدري كيف قمت بتسميته. بداخل المتحكم قم بإنشاء تابع بالإسم create و قم بإرجاع صفحة العرض الخاصة بإنشاء القسم: public function create() { return view('categories.create'); } أعلاه يعني تواجد ملف create.blade.php بداخل مجلد categories و الموجود بداخل مجلد views. بداخل الملف قم ببناء الإستمارة الخاصة بإنشاء القسم.
  21. سؤالك غير واضح يُرجى بذل مجهود أكبر حتى يفهم المدرب ما الذي تريد فعله، سأعطي بعض الإرشادات على حسب ما فهمت: إذا كنت تريد الوصول إلى ترتيب العُنصر داخل الحلقة يمكنك إستخدام فهرس الحلقة i إذا كنت تريد الوصول لترتيب العُنصر بعد الحلقة، يُمكنك الإستعلام مجدداً إذا كان ما تبحث عنه مخزن ضمن عمود في جدول ما فقط قم بصياغة الإستعلام و تحديد الشرط الموافق لما تريد. أما إن كنت تريد إستخدام نتيجة الإستعلام الأول فيُمكنك حفظ النتيجة في مصفوفة (ثم البحث بداخلها عن البند الذي تريده بعد الوصول للصف الموافق قم بإرجاع قيمة المفتاح الموافق للترتيب) أما إن كانت نتيجة الإستعلام لا تحتوي على ذلك الترتيب كقيمة (أي أنه لا يوجد حقل يوافق ترتيب البند في نتيجة الإستعلام) يُمكنك إنشاء دالة تستقبل مصفوفة و العنصر الذي تبحث عنه كمعاملات، ثم من خلال الحلقات تمر على عناصر المصفوفة و تبحث عن العنصر إن تم إيجاد العنصر توقف الحلقة و تعيد الفهرس الذي تم الوصول له. إن لم تجد العُنصر تُعيد -1 دلالة على أنه غير موجود. تستخدم الدالة و تمرر لها نتيجة الإستعلام و البند. أعطيت عدة إحتمالات لأني لا أعرف إن كان ما تريد الوصول له مُخزن في حقل ضمن جدول ما أو فقط ترتيب ضمن إستعلام.
  22. هناك العديد من الأفكار التي بإمكانك التطبيق عليها بإستعمال لغات الويب الأساسية HTML و CSS و لاحقاً عندما تتعلم جافاسكربت مثل: صفحات شخصية، صفحات البورتفوليو صفحات هبوط لمنتجات صفحات تعريفية لشركات. لوحات تحكم و غيرها العديد ستجد أثناء بحثك و تطبيقك العديد من الأفكار فقط أكتب في البحث: html css free templates سيظهر لك في البحث عدة مواقع توفر قوالب مجانية يُمكنك الدخول على إحداها و إختيار قالب و تحميل ملفاته، إستعراض النتيجة و محاولة تقليد الصفحات. إبدأ بالتصاميم البسيطة ثم تدرج في الأصعب.
  23. لقد قمت بتجربة المشروع و بالضبط خاصية رفع الصور لم تُقابلني أية مشاكل قمت بالتعديل على بائع و غيرت صورة المتجر و تم تغييرها بنجاح، أيضاً من الإعدادات غيرت شعار الموقع و تم تغييره بنجاح. رُبما الطرف الآخر لم يقم بإستيراد قاعدة البيانات، أو أنه لم يحقق شروط الإتصال بقاعدة البيانات تلك في ملف الإتصال. من الممكن أيضاً أنه يعمل على نظام مغاير حيث توجد صلاحيات على نظام الملفات و المجلدات أي لا يُمكن الكتابة بداخلها، و في هذه الحالة يجب عليه ضبط الصلاحيات على تلك المجلدات حتى يتسنى للسكربت نقل الصور لها. من الأفضل أيضاً إنشاء ملف يتضمن طريقة و خطوات تشغيل المشروع على سيرفر محلي، و إرسالها له.
  24. بخصوص التصميم و الواجهة فليس لدي خبرة كبيرة لكن هناك بعض النقاط لفتت إنتباهي، يجب عليك وضع عنوان مناسب للصفحة، الجزء الذي يأتي بعد الترويسة الصورة فيه تأخذ حجم كبير جداً من الأفضل تقليل الحجم الذي تأخذه على الصفحة إرتفاع القسم كبير جداً، محتاج تعمل تمرير للشريط حتى تتصفح ذلك القسم، قسم المقالات جيد ممكن تضيف زر أو رابط للذهاب إلى قسم المقالات، قسم الشريط المتحرك محتاج شغل أفضل، ممكن تكبير لأزرار التنقل و تعطيها نفس اللون الرئيسي، أيضاً محتاج تبرز عنوان للقسم، قسم الأسعار جيد لكن هناك بعض اللخبطة في السعر، يُمكن أن تقوم بتطويره بشكل أكبر بحيث تُبرز الخُطة الأفضل للإشتراك الأمر يعود لك. جزء الفوتر به مساحات فارغة بشكل كبير، يُمكنك تقليل الهوامش و الحشوات، أيضاً تحتاج لتفعيل الأزرار و الروابط، يُمكن أيضاً تغيير لون العناوين الرئيسية و تكبيرها قليلاً و لون الأيقونات للون الرئيسي في ذلك القسم. يُمكن إضافة جزء مثلاً ماذا قالو عنا و تضع ردود العملاء بخصوص الأشياء الديناميكية في الموقع فأنت كمُبرمج واجهات محتاج تعمل صفحات كنموذج مثلاً صفحة المقال و كل روابط المقالات تقود لتلك الصفحة، الصفحة تكون عبارة عن قالب و المحتوى يكون محتوى تجريبي لكن التصميم أنت من يقوم به، مبرمج الواجهات الخلفية مهمته جلب البيانات المتغيرة و عرضها، لكن التصميم أنت من يقوم به، الصفحة ستكون صفحة واحدة، نفس الأمر بخصوص صفحة المقالات إن كانت موجودة و هي صفحة تُعرض بها كل المقالات، تضع عُنصر مقال واحد و تُكرره أكثر من مرة و تضع في الأسفل pagination (أزرار الترقيم) أو زر لتحميل المزيد، نفس الأمر بخصوص صفحة إتصل بنا و صفحة معلومات عنا.
×
×
  • أضف...