المحتوى عن 'todo'.



مزيد من الخيارات

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المُحتوى


التصنيفات

  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • نصائح وإرشادات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • التجارة الإلكترونية
  • الإدارة والقيادة
  • مقالات ريادة أعمال عامة

التصنيفات

  • PHP
    • Laravel
    • ووردبريس
  • جافاسكريبت
    • Node.js
    • jQuery
    • AngularJS
    • Cordova
  • HTML
    • HTML5
  • CSS
  • SQL
  • سي شارب #C
    • منصة Xamarin
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • Sass
    • إطار عمل Bootstrap
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • برمجة أندرويد
  • لغة Swift
  • لغة R
  • لغة TypeScript
  • سير العمل
    • Git
  • صناعة الألعاب
    • Unity3D
  • مقالات برمجة عامة

التصنيفات

  • تجربة المستخدم
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
    • كوريل درو
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • نصائح وإرشادات
  • مقالات تصميم عامة

التصنيفات

  • خواديم
    • الويب HTTP
    • قواعد البيانات
    • البريد الإلكتروني
    • DNS
    • Samba
  • الحوسبة السّحابية
    • Docker
  • إدارة الإعدادات والنّشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • مقالات DevOps عامة

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • التسويق بالرسائل النصية القصيرة
  • استسراع النمو
  • المبيعات
  • تجارب ونصائح

التصنيفات

  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • مقالات عمل حر عامة

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
  • أندرويد
  • iOS
  • macOS
  • ويندوز

التصنيفات

  • شهادات سيسكو
    • CCNA
  • شهادات مايكروسوفت
  • شهادات Amazon Web Services
  • شهادات ريدهات
    • RHCSA
  • شهادات CompTIA
  • مقالات عامة

أسئلة وأجوبة

  • الأقسام
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة البرمجة
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات
    • أسئلة الشهادات المتخصصة

التصنيفات

  • ريادة الأعمال
  • العمل الحر
  • التسويق والمبيعات
  • البرمجة
  • التصميم
  • DevOps

تمّ العثور على 6 نتائج

  1. تعرّفنا في الجزء السّابق على Asana والخصائص التي توفرها لإدارة عمل فرق العمل عن بعد، التواصل فيما بينهم، وتسهيل رؤية نتائج العمل. كما تعرّفنا على كيفية إنشاء حساب Asana وبعض الأمور التي تتعلّق بالحساب. في هذا الجزء سنتعرّف على واجهة Asana بجميع أقسامها، كما سنأتي إلى شرح اختصارات لوحة المفاتيح التي ستوفّر عليك الوقت الكثير وتساعدك في تسريع تدفّق العمل. الواجهة تُقسم واجهة Asana إلى خمسة أقسام: الشريط الجانبي Sidebar.الشريط العلوي Top Bar.الترويسة Header.اللوحة الرئيسيّة Main Pane.اللوحة اليمنى. Right Pane.وكما موضّحة في الصورة أعلاه. أولا: الشريط الجانبي تستطيع من خلال الشريط الجانبي: الوصول لوحة التحكم My Dashboard.الوصول إلى مفضلتك Favorites، من المشاريع، الأشخاص (قوائم مهامهم)، الوسوم، وغيرها، والتي تتمثّل بأيقونة النجمة.الوصول إلى الأنشطة المشاريع، الأشخاص، الوسوم التي قمت باستعراضها مؤخرًا، Recents، والتي تتمثّل بأيقونة الساعة.الوصول إلى محادثات الفريق Team Conversations.الوصول إلى تقويم الفريق Team Calendar.الوصول إلى فريقك (وهذا في حالة "المؤسسات Organizations" فقط)، أو مشاريع "مساحة العمل Workspace" الخاصّة بك.استعراض الفرق التي تنتمي إليها والانضمام إلى فرق أخرى في "مؤسستك".لوحة التحكم Dashboardتوفّر لوحة التحكم نظرة أوسع وأشمل حول حالات المشاريع التي تعمل عليها وتعرض الرسوم البيانية التي توضّح تقدم تلك المشاريع. وبذلك تستطيع إدارة العمل دون أن تضطر إلى مغادرة الصفحة. انقر على My Dashboard وسيتم إظهارها في اللوحة الرئيسيّة. المشاريع Projectsالمشروع هو عبارة عن مجموعة من المهام. يستخدم المشروع لتحقيق الهدف النهائي بتقسيمه إلى عدة مهام يتم توكيلها إلى أفراد الفريق لتحقيق ذلك الهدف. يعرض الشريط الجانبي مشاريعك في فريقك أو في "مساحة العمل" الخاصّة بك. انقر على اسم المشروع وسيتم إظهاره في اللوحة الرئيسيّة. ملاحظة: تشير أيقونة القفل في الصورة أعلاه إلى أنّ المشروع خاص Private Project، وهذا أحد خيارات خصوصية المشاريع التي هي: Private you: خاص بك؛ أي لا أحد غيرك يمكنه مشاهدة المشروع.Private to Members: خاص بأعضاء المشروع فقط.Public: عام، ويستطيع كل شخص في الفريق أو "مساحة العمل" الوصول إليه ورؤيته.خيارات المشروعمرر الفأرة فوق اسم المشروع وانقر على أيقونة الثلاث نقاط لاستعراض بعض خيارات المشروع. انقر على السهم للوصول إلى الخيارات التالية: Highlight Color: لتغيير لون المشروع.الإضافة إلى/ الحذف من المفضلة.(Use as a Template (Copy Project: لنسخ المشروع.Archive: لأرشفة المشروع.Delete: لحذف المشروع.كما تستطيع الوصول إلى المزيد من الخيارات عند فتح المشروع. سحب المشروع وإسقاطه Drag & Drop وتستخدم هذه الخاصية لغرض ترتيب المشاريع في الشريط الجانبي. المفضلات Favoritesتستطيع تأشير المشاريع، الأشخاص (قوائهم مهامهم)، الوسوم، أو البحث المخصّص Search Views كمفضلة لحفظها في الشريط الجانبي وتسهيل الوصول إليها. وسيظهر ما قمت بتفضيله لك فقط، حيث أنّ كل شخص لديه قائمة من المفضلات الخاصّة به. ستظهر المفضلات في موضع ثابت في الجزء العلوي من الشريط الجانبي وعلى جانبها أيقونة النجمة. ويمكنك إعادة ترتيب المفضلات عن طريق السحب والإسقاط. الإضافة إلى/الحذف من المفضلةانقر على أيقونة النجمة في الترويسة لإضافة مشروع ما إلى المفضلة، وستلاحظ تغير لون النجمة إلى الأصفر وظهور المشروع في الجزء العلوي من الشريط الجانبي. وإذا قمت بالنقر على أيقونة النجمة من جديد سيتم إزالة المشروع من المفضلة بتغيّر لون النجمة إلى الأبيض واختفاء المشروع من الشريط الجانبي. الأنشطة الحديثة Recentsيتيح لك هذا الخيار الانتقال السريع إلى المشاريع، الأشخاص، أو الوسوم التي قمت باستعراضها مؤخرًا. وستظهر الأنشطة الحديثة تلقائيًا أسفل المفضلات مباشرةً، وبجانبها أيقونة الساعة. إخفاء وإظهار الشريط الجانبيبإمكانك إخفاء الشريط الجانبي عن طريق النقر على علامة X في الجزء العلوي منه إذا كنت تريد توسيع مساحة المركز واللوحة اليمنى. ولإظهاره من جديد، انقر على زر الخطوط الثلاثة. ثانيا: الشريط العلوي تستطيع من خلال الشريط العلوي: الوصول إلى قائمة مهامك My Tasks.الوصول إلى صندوق الوارد My Inbox.استخدام زر الإضافة السريعة Quick Add المتمثل بأيقونة + لإنشاء مهمّة، مشروع، محادثة، أو دعوة المزيد من الأشخاص.إجراء بحث عن المهام، المشاريع، المحادثات، الوسوم، أو الأشخاص.الوصول إلى المساعدة Help.الوصول إلى إعدادات الملف الشخصي، إعدادات "مساحات العمل" أو "المؤسسات"، أو التبديل بين "مساحات العمل" أو "المؤسسات" الخاصّة بك.مهامي My Tasksستظهر المهام التي أوكلت إليك في كل "مؤسسة" أو "مساحة عمل" في قائمة My Tasks، وعادةً ما تكون قائمة مهامك هي محطتك الأولى في Asana يوميًا. وستظهر هذه القائمة في اللوحة الرئيسيّة عند النقر على My Tasks. صندوق الوارد My Inboxيمكن اعتبار صندوق الوارد بمثابة مركز التنبيهات/الإشعارات في Asana، حيث يُستخدم للاطلاع على آخر التحديثات من قبل زملائك في الفريق. التحديثات التي تصلك إلى صندوق الوارد هي: المهام التي أوكلت إليك.المهام التي تقوم بمتابعتها.المشاريع التي تشارك فيها.المحادثات التي تم إشراكك بها. زر الإضافة السريعة Quick Add يتيح لك زر الإضافة السريعة (+) سهولة: إنشاء مهمّة.إنشاء مشروع.بدء محادثة.دعوة عضو جديد إلى "مساحة العمل" أو "المؤسسة" الحالية الخاصّة بك.البحث Searchاستخدم البحث للعثور على المهام، المشاريع، المحادثات، الوسوم، أو الأشخاص. قم بالنقر داخل حقل البحث واكتب النص الذي تريد البحث عنه ثم اضغط Enter. أو اختر "البحث المتقدّم" Advanced Search لإنشاء بحث مخصّص Search View. البحث المخصّص Search Viewالبحث المخصّص هو عبارة عن قائمة من المهام التي تطابق المعايير التي تحددها عند البحث. استخدم البحث المخصص للعثور على أي مجموعة محددة من المهام. بإمكانك إنشاء بحث يتضمن أي مجموعة كانت من الأشخاص الذين أوكلت إليهم المهام assignees، المشاريع، الوسوم، تواريخ انتهاء المشاريع due dates، وغيرها الكثير. ستشاهد في نافذة البحث المتقدم العديد من المتغيّرات التي يمكنك استخدامهم لتخصيص البحث عن المهام أو المحادثات. كما يمكنك استخدام متغيرات أخرى عن طريق الخيار Search by Another Field في أسفل نافذة البحث المتقدم. المساعدة Help تستطيع الوصول إلى نافذة المساعدة والحصول على الكثير من الموارد المفيدة عن طريق النقر على زر علامة الاستفهام في الشريط العلوي. القائمة المنسدلة للشريط العلوي انقر على صورة الملف الشخصي في الشريط العلوي لإظهار القائمة المنسدلة التي تستطيع من خلالها: التبديل بين "مساحات العمل" و"المؤسسات" الخاصّة بك.ترقية "مساحة العمل" أو "المؤسسة" الحاليّة إلى الخدمة المدفوعة Premium.الوصول إلى إعداد "مساحة العمل" أو "المؤسسة" الحالية.إنشاء "مساحة عمل" جديدة.مغادرة "مساحة العمل" أو "المؤسسة" الحالية.الوصول إلى إعدادات الملف الشخصي.تسجيل الخروج.لاحظ أنّ علامة الصح في الصورة أعلاه تشير إلى "مساحة العمل" أو "المؤسسة" التي تشاهدها حاليًا. ثالثا: الترويسة تستطيع من خلال الترويسة: تأشير المشروع، المهمّة، أو البحث المخصص الذي تستعرضه حاليًا كمفضّل عن طريق أيقونة النجمة.الوصول إلى خيارات المشروع، المهام، أو البحث المخصّص الذي تستعرضه حاليًا عن طريق أيقونة السهم المتجه إلى الأسفل.تغيير طريقة عرض المشروع، المهام، أو البحث المخصص الذي تستعرضه حاليًا.عرض قائمة أعضاء المشروع.خيارات القائمة المنسدلة في الترويسة تتيح لك القائمة المنسدلة عن النقر على السهم الوصول إلى الخيارات التالية: Edit Name & Description: لتعديل اسم ووصف مشروعك.Sync to Calendar: لمزامنة مهامك وتواريخ انتائها إلى تقويم خارجي، كتقويم جوجل، Outlook، iCal أو أي تقويم آخر يتيح لك الاشتراك بواسطة العناوين URL.Add Tasks by Email: يوفر هذا الخيار عنوان بريد إلكتروني يمكن استخدامه لإنشاء مهام عن طريق إرسال بريد إلكتروني داخل Asana.Print: لطباعة المشروع.(Use as Template (Copy Project: لنسخ المشروع (تكريره).Move to Another Team: لنقل المشروع إلى فريق آخر في مؤسستك، علمًا أنّ هذا الخيار مُتاح في "المؤسسات" فقط.Highlight Color: لتغيير لون المشروع.Export: لتصدير المشروع أو "مهامي My Tasks" كملف CSV أوJSON.Archive: لأرشفة المشروع.Delete: لحذف المشروع.طرق عرض المشروع Views بإمكانك التبديل بين خمس طرق عرض مختلفة للمشروع عن طريق الترويسة: List: وهذا هو الخيار الافتراضي لعرض المشروع الذي يعرض قائمة من المهام.Conversations: تتيح لك طريقة العرض هذه بدء المحادثات مع زملائك في المشروع نفسه، وهذا الخيار مُتاح في المشاريع فقط.Calendar: في طريقة العرض هذه تتم تصفية المهام فقط مع تواريخ انتهائها وعرضها على شكل تقويم.Progress: لعرض المعلومات حول المشروع وتقدّمه، بما في ذلك تحديثات الحالة ومخطط التقدّم، وهذا الخيار أيضًا مُتاح في المشاريع فقط.Files: لتصفية المهام مع المرفقات attachments، وهذا الخيار مُتاح في المشاريع و"مهامي My Tasks".إخفاء وإظهار الترويسةتستطيع إخفاء الترويسة لتوسيع مساحة المركز واللوحة اليمنى عن طريق أيقونة السهم المزدوج في اليسار. ولعرضها مجددًا، قم بالنقر على أيقونة السهم المزدوج نفسها. رابعا: اللوحة الرئيسيةعندما تقوم بتحديد مشروع، وسم، أو شخص ما من الشريط الجانبي، ستظهر قائمة المهام ذات الصلة بما قمت بتحديده في اللوحة الرئيسيّة. كما أنّها المكان الذي ستشاهد فيه نتائج بحثك، التنبيهات الواردة، بطاقات لوحة تحكّم المشروع، ومشاركات المحادثة. من خلال اللوحة الرئيسيّة تستطيع: إضافة مهمّة جديدة.فرز وتصفية قائمة المهام.تأشير المهمّة كمنتهية أو غير منتهية.عرض وتعديل اسم المهمّة.تحديد المشاريع أو الوسوم الأخرى التي ترتبط بها المهمّة.مشاهدة عدد "القلوب"* التي حصلت عليها المهمّة.تحديد تاريخ انتهاء المهمّة due date.تحديد الشخص المسؤول عن إنجاز المهمّة assignee.يستخدم زر "القلب" للتعبير عن اهتمامك بالمهمّة أو تحمّسك لها، إبداء الموافقة على تعليق أحدهم، أو التعبير الامتنان لإنجاز مهمّة ما. خامسا: اللوحة اليمنىاللوحة في الجانب الأيمن من المتصفح هي المكان التي تظهر فيه تفاصيل المهمّة التي يتم تحديدها في اللوحة الرئيسيّة. من خلال اللوحة اليمنى تستطيع: توكيل المهمّة إلى شخص في الفريق.تعيين تاريخ ووقت انتهاء المهمّة.التعبير عن الاهتمام بالمهمّة عن طريق زر "القلب".تحديد المشروع الذي تنتمي إليه المهمّة.تأشير المهمّة كمنتهية أو غير منتهية.إضافة وصف للمهمّة لتوضيح المزيد من التفاصيل.بناء قائمة من المهام الفرعية.إرفاق الملفات.إضافة تعليق على المهمّة.متابعة، أو إلغاء متابعة المهمّة.إخفاء وإظهار اللوحة اليمنىتستطيع إخفاء اللوحة اليمنى لتوسيع مساحة المركز عن طريق النقر على أيقونة X. ولإعادة اظهارها مجددًا، انقر على زر السهم الأيمن. وضع ملء الشاشة بإمكانك استخدام وضع ملء الشاشة إذا رغبت في التركيز على مهمّة محددة وذلك عن طريق: النقر على أيقونة الثلاث نقاط في أعلى اللوحة اليمنى.اختيار Full Screen. اختصارات لوحة المفاتيحتفيد اختصارات لوحة المفاتيح في تسريع تدفق العمل وتسهيل تنفيذ بعض الأوامر دون الحاجة إلى استخدام الفأرة. الاختصارات الأساسية موضحة أدناه لنظام Windows. أما بالنسبة لنظام Mac فهي نفسها، قم فقط استبدال مفتاح Ctrl بمفتاح Cmd. ويرجى ملاحظة أنّ بعض الاختصارات قد لا تعمل على لوحات المفاتيح الدولية. الاختصارات الخاصة بالمهامEnter: إنشاء مهمّة جديدة.Tab+ BKSP: مسح المهمّة/ المهام المحددة (أو BKSP عندما يكون اسم المهمّة فارغًا).Ctrl+ Enter: تأشير المهمّة/المهام المحددة كمنتهية.Ctrl+ السهم الأعلى/ Ctrl+السهم الأسفل: التحرّك إلى الأعلى/إلى الأسفل.Ctrl+ Shift+ السهم الأعلى/ Ctrl+ Shift+ السهم الأسفل: للانتقال إلى القسم section التالي الأعلى/الأسفل.Ctrl+ C: نسخ المهام المحددة.Ctrl+ V: لصق المهام المحددة (واحدة لكل سطر).Tab+ M: تعيين نفسك كمسؤول عن إنجاز المهمّة المحددة.Tab+ H: إعطاء "قلب" للمهمّة المحددة.Tab+ Y: تأشير المهمّة لإنجازها اليوم Today.Tab+ U: تأشير المهمّة كالمهمّة القادمة Upcoming.Tab+ L: تأشير المهمّة لإنجازها لاحقًا Later.: اكتب النقطتين في نهاية اسم المهمّة لإنشاء قسم جديد.Tab+ Z: أرشفة المهام المكتملة.Tab+ C: التعليق على المهمّة المحددة.Tab+ A: توكيل المهمّة المحددة إلى أحد أعضاء المشروع.Tab+ D: تعيين تاريخ انتهاء المهمّة Due Date.Tab+ F: إضافة مُتابع للمهمّة.Tab+ S: إنشاء مهمّة فرعية Subtask.Tab+ /: البحث عن مشروع، وسم، شخص، أو مهمّة.Tab+ Enter: الانتقال إلى قائمة المهام.الاختصارات الخاصة بالتحديدالسهم الأعلى/السهم الأسفل: تغيير التحديد.Shift+ زر الفأرة الأيسر: تحديد مجموعة من المهام المتجاورة.Shift+ السهم الأعلى/السهم الأسفل: تحديد مجموعة من المهام المتجاورة للأعلى/للأسفل.Ctrl+ زر الفأرة الأيسر: لتحديد عدد من المهام المتفرقة غير المتجاورة.الاختصارات الخاصة بصندوق الواردJ/K: التحرّك إلى الأعلى/ الأسفل.H: إخفاء أرشيف التنبيهات (الانتقال إلى تبويب صندوق الوارد).S: إظهار أرشيف التنبيهات (الانتقال إلى تبويب الأرشيف).F: متابعة أو إلغاء متابعة.I: أرشفة التنبيه المحدد.U: لإرسال الأرشيف المحدد إلى صندوق الوارد.Ctrl+ /: عرض اختصارات لوحة المفاتيح.Tab: فتح التفاصيل.ESC: غلق التفاصيل.Tab+ X: وضع التركيز.Tab+ Q: الإضافة السريعة.Tab+ Enter: نشر تعليق (من حقل التعليقات).Tab+ B: What it sounds like.بعد أن تعرّفت على Asana، واجهتها، وكيفية إنشاء الحساب، حان الوقت لتتعرف على كيفية استخدامها ودعوة فريقك، وهذا ما سنستعرضه في الجزء الثالث من هذه السلسة. ترجمة وبتصرف لأدلة المساعدة لخدمة asana.
  2. هل تريد تتبع تقدم عمل فريقك؟ هل تواجه صعوبة في جمع أفراد الفريق في مكان واحد؟ هل تعبت من استخدام البريد الإلكتروني لغرض إجراء المحادثات حول العمل وتبادل الأفكار؟ هل تريد أن تشاهد ثمرة جهود الفريق بشكل مباشر؟ تستطيع تحقيق كل ذلك على منصّة واحدة: Asana؛ صُممت لتساعد الفرق على تتبع العمل وتحقيق النتائج. باستخدام Asana يتعاون أفراد الفريق بكفاءة ويعملون بطريقة أفضل، أسرع، وأكثر ذكاءً. في Asana يعرف كل فرد من أفراد الفريق المهمة التي أوكلت إليه ومتى عليه إنهائها. في Asana تستطيع تحويل الأفكار إلى واقع والوصول إلى أكثر الأهداف طموحًا. هل تريد أن تبدأ رحلة التعرف على Asana وكيفيّة استخدامها؟ إذا كنت كذلك، كلّ ما عليك فعله هو متابعة هذه السلسلة التي تشرح كيفيّة استخدام هذه الأداة. Asana هي من أسهل الوسائل التي تساعدك وتساعد فريقك في تتبّع العمل، وهنالك ثلاث أمور أساسية يجب أن تعرفها عنها: أولا: تتبع مشاريع فريقك ومهامهم من البداية وحتى النهايةتساعدك Asana على تقسيم العمل إلى مشاريع ومهام، وبذلك تكون جميع المسؤوليات والخطوات القادمة التي يجب اتخاذها واضحة. كما يمكنك إجراء محادثات قابلة للتنفيذ للانتقال بالعمل خطوة إلى الأمام. بهذه الطريقة تعرف ما المشروع التالي الذي يجب إنجازه ومتى يجب إنجازه، والحصول على جميع المعلومات التي تحتاجها في مكان واحد. ثانيا: رؤية تقدم العمل، الإنجاز في الميعاد النهائي، والحصول على نتائج عظيمةتستطيع باستخدام Asana أن تبقى على اطلاع على المرحلة التي وصل إليها العمل دون أن تضطر إلى إرسال بريد إلكتروني واحد حول التحديثات. ستصلك التحديثات حول المشاريع والمهام التي تتبعها، وبإمكانك رؤية تقدم الفريق باستخدام لوحات المعلومات Dashboards والتقاويم Calendars. ثالثا: Asana سهلة الاستخدام وتصبح أكثر فعالية كلما أضفت المزيد من العملمن السهل أن تبدأ العمل على Asana وتهيئة فريقك لاستخدامها. تستطيع أن تبدأ بإضافة العمل إلى Asana وتتبّعه طالما بإمكانك إنشاء قائمة مهام وإرسال بريد إلكتروني. وستتوسّع Asana لاستيعاب عملك كلما أضفت فرقًا أخرى أو أنشأت مشاريع أكثر تعقيدًا. والآن بعد أن تعرّفت على Asana، حان الوقت لتتعرّف على كيفيّة إنشاء حساب Asana لتشرع باستخدامها. كيفية إنشاء حساب على Asanaإنّ إنشاء الحساب على Asana مجاني (وهناك خدمة مدفوعة premium بخصائص إضافيّة متقدّمة). تستطيع إنشاء حساب بنفسك قبول دعوة للانضمام. سيُطلب منك إدخال اسمك وعنوان بريدك الإلكتروني، وبإمكانك استخدام البريد الإلكتروني الخاص بعملك إذا أردت الانتماء إلى "مؤسسة" خاصة بشركتك. كما بإمكانك إضافة عناوين بريد أخرى لاحقًا إذا أردت ربط حسابك بعدّة عناوين. وفي الخيار الأخير بعض المزايا، على سبيل المثال لا الحصر؛ ستكون لديك خيارات إضافيّة لإرسال المهام عبر البريد الإلكتروني، وخيارات إضافيّة لتلقّي التنبيهات على البريد الإلكتروني. تستطيع الانضمام وإنشاء أي عدد تريده من "المؤسسات" أو "مساحات العمل" من خلال حساب واحد، أي لا تحتاج إلى إنشاء حسابات متعدّدة. وسنأتي إلى ذكر الفرق بين "المؤسسة" و"مساحة العمل" لاحقًا في هذا المقال. الاشتراك عن طريق الصفحة الرئيسية للموقعلإنشاء حساب خاص بك أو بشركتك قم بزيارة موقع http://www.asana.com. تستطيع الاشتراك بإدخال عنوان بريدك الإلكتروني وكلمة سريّة خاصّة بحساب Asana، باستخدام حساب جوجل، أو بواسطة SAML. إذا اخترت الاشتراك باستخدام حساب جوجل سيتم استخدام بيانات الاعتماد للحساب الحالي الذي سجلّت الدخول إليه، أو سيُطلب منك تسجيل الدخول إلى حسابك على جوجل. وكذلك لن تكون لديك كلمة سريّة خاصة بـ Asana، ولكن يمكنك إدخال واحدة عن طريق عملية "استعادة الكلمة السرية" التي سنشرحها لاحقًا في هذا المقال. الاشتراك عن طريق دعوةعندما تصلك دعوة للانضمام إلى فريق على Asana، قم بفتح البريد الإلكتروني في إحدى المتصفحات التي تدعمها Asana، ثم انقر على زر الانضمام للفريق "Join [team name] Now"، أو قم بنسخ ولصق الرابط المرفق أسفله. في صفحة إنشاء الحساب أدخل اسمك، الكلمة السريّة، وصورة الملف الشخصي، علمًا أنّ إضافة صورة الملف الشخصي اختيارية في هذه المرحلة، بإمكانك تجاوزها وإضافة الصورة لاحقًا عن طريق إعدادات الملف الشخصي Profile Settings. تسجيل الدخوللتسجيل الدخول إلى Asana، اذهب إلى https://app.asana.com/ أو https://www.asana.com: ومن صفحة تسجيل الدخول تستطيع: إدخال عنوان البريد الإلكتروني والكلمة السرية الخاصة بحسابك.أو النقر على "Use Google Account"تسجيل الدخول عن طريق SAMLلن يطلب منك إدخال الكلمة السرية لتسجيل الدخول إذا كنت تستخدم حساب مدفوع لمؤسسة تمكّن SAML، وستتم المصادقة على حسابك عبر البريد الإلكتروني فقط. ولتسجيل الدخول إلى حسابك: اذهب إلى https://www.asana.com أو https://app.asana.com.أدخل عنوان البريد الإلكتروني الخاص بحسابك واترك حقل الكلمة السرية فارغًا.انقر على زر Log In.أو بدلًا من ذلك، بالإمكان تسجيل الدخول عن طريق عنوان URL مخصص، وهذا الخيار متاح للمستخدمين في المؤسسات التي تمكّن SAML. ويتم ذلك عن طريق إضافة اسم نطاق البريد الإلكتروني للشركة في نهاية العنوان https://app.asana.com/a/ للوصول إلى بوابة تسجيل الدخول المخصصة. مثلًا، يستطيع أعضاء "مؤسسة" acme.com تسجيل الدخول إلى حساباتهم من الرابط https://app.asana.com/a/acme.com. ملاحظة: يجب على أعضاء المؤسسات المدفوعة التي تمكّن SAML تسجيل الدخول إلى حساباتهم عن طريق عنوان البريد الإلكتروني المرتبط بـ SAML، بغض النظر عن عدد عناوين البريد الإلكتروني التي يمتلكونها على الحساب. دمج الحسابات المتعددةإذا أنشأت حسابين بعناوين بريد مختلفة، تستطيع دمجها بإضافة البريد الإلكتروني المرتبط بأحد الحسابات إلى الحساب الآخر عن طريق إعدادات الملف الشخصي. إنّ دمج الحسابات يعني أنّ: عناوين البريد الإلكتروني لكِلا الحسابين الأصليين سترتبط بحساب واحد جديد.الحساب الجديد سيحتوي على جميع "المؤسسات" و"مساحات العمل" لكلا الحسابين الأصليين.مشاريعك الشخصيّة سيتم دمجها إلى حساب واحد. لكي تدمج الحسابات، اذهب إلى حسابك الرئيسي، ثم: انقر على صورة الملف الشخصي واختر My Profile Settings من القائمة المنسدلة.انقر على To Email.انقر على +Add New Email، وادخل عنوان البريد الإلكتروني لحسابك الثانوي، ثم انقر على Reauthenticate.سيتم إرسال رابط تأكيد الدمج إلى عنوان البريد الإلكتروني للحساب الثانوي. يمكنك تأكيد الدمج عن طريق ذلك الرابط. تعيين/إعادة تعيين الكلمة السريةلقد أدخلت الكلمة السرية عند إنشاء الحساب بالفعل. ولكن إذا قمت بالاشتراك بواسطة حساب جوجل فهذا يعني أنّك لا تمتلك كلمة سريّة خاصّة بحساب Asana. بإمكانك تعيين واحدة عن طريق رابط "Forgot your password?" من صفحة تسجيل الدخول الذي يمكنك استخدامه أيضًا في حال نسيت الكلمة السريّة أو أردت تغييرها. لتوليد رابط استعادة الكلمة السريّة انقر على " Forgot your password?" واملأ الحقل في الصفحة التالية. سيصلك رابط استعادة الكلمة السرية إلى عنوان البريد الإلكتروني الذي أدخلته، بإمكانك استخدامه لإعداد كلمة سريّة جديدة. تسجيل الخروج لتسجيل الخروج من Asana: انقر على صورة ملفك الشخصيانقر على Log Out من القائمة المنسدلة.تعطيل الحسابإنّ تعطيل الحساب دائمي ولا يمكن التراجع عنه. قم بتعطيل حسابك الشخصي إذا كنت متأكدًا من أنّك لا تريد استخدام Asana بعد الآن. تستطيع الوصول إلى خيار التعطيل عن طريق إعدادات الملف الشخصي عبر تبويب "Account" عندما تقوم بتعطيل حساب، لن يكون بإمكانك الوصول إلى أي بياناتك في ذلك الحساب. وإذا رغبت في استخدام Asana في المستقبل، سيكون عليك الاشتراك بحساب جديد. ملاحظة: التعطيل سيشمل حسابك الشخصي فقط، وسيستمر وجود "المؤسسات" و"مساحات العمل" التي تنتمي إليها حتّى بعد تعطيله. الفرق بين "المؤسسة" و"مساحة العمل"المؤسسة Organization: تستخدم لربط جميع موظفي شركتك في مكان واحد باستخدام Asana بناءً على نطاق البريد الإلكتروني email domain المشترك للشركة.مساحات العمل Workspaces: تستخدم من قبل أي مجموعة من الناس ولا تتطلب نطاق بريد إلكتروني مشترك؛ أي أنّ الاشتراك يتم بواسطة عناوين البريد الإلكتروني الشخصيّة (xxx@yahoo.com، xxx@gmail.com).انتهينا، ولكنّها نهاية البداية، فمازال هنالك المزيد لتتعرف عليه حول خدمة Asana والخصائص التي توفرها والتي تمكّنك من تتبع عملك بسهولة والارتقاء به إلى مستويات متقدّمة. تابع بقية أجزاء السلسلة. ترجمة وبتصرف لأدلة المساعدة لخدمة asana.
  3. بعد أن انتهينا من إعداد قواعد البيانات والطرق (routes)، سوف نتحدث في هذا الجزء عن المتحكِّمات (Controllers)، النماذج (مع العلاقات)، والعروض views. (بما في ذلك نظام blade ومخططات المحتوى). مساعدات النماذج Form Helpers في Laravelبعد كل هذه الإعدادات، إذا ذهبنا الآن (في المتصفح) إلى projects/ فسوف نحصل على صفحة فارغة فما هو السبب؟ حسنا، لنكتشف ذلك، قم بتنفيذ الأمر php artisan route:list على سطر الأوامر مرة أخرى وأنظر إلى هذا السطر: +--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+ | | GET|HEAD | projects | projects.index | App\Http\Controllers\ProjectsController@index | | +--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+يبدو أن رابط projects/ يقوم بتحميل الوظيفة Index الخاصة بـ ProjectsController، لذلك سنقوم بفتح app/Http/controllers/ProjectsController.php/ وسنقوم بتحديث التابع (method) لنقوم بربطه إلى عرض سوف نقوم بإنشائه. قم بإضافة السطر ;('return view('projects.index إلى الوظيفة ()index كالتالي: public function index() { return view('projects.index'); }بما أننا نستخدم في هذا الدرس نظام Blade للقَوْلَبة سنقوم بإنشاء ملف resources/views/projects/index.blade.php/ وسنكتب نص قصير داخله، ثم سنقوم مرة أخرى بالذهاب إلى projects/ في المتصفح، إذا كان كل شيء يعمل جيدا فسوف تجد النص الذي كتبته بالأعلى. والآن قُم بنفس الشيء لتابع المتحكِّم create عن طريق إضافة السطر ;('return view('projects.create إلى التابع ()create كالتالي: public function create() { return view('projects.create'); }إن إظهار محتويات العرض view هو أمر رائع، لكن ماذا لو كنا نملك أكثر من صفحة واحدة في موقعنا ؟ في هذه الحالة، سوف نحتاج إلى قالب ثابت لجميع الصفحات، أي أننا نحتاج إلى عرض محتويات العرض view داخل قالب HTML بسيط، وسنقوم بهذا عن طريق مخططات المتحكِّمات. من أجل عمل مخططات المتحكِّمات سنقوم بالخطوات التالية: إنشاء مخطط العرض، وبما أن Laravel توفر لنا واحدة جيدة تدعى app.blade.php لذلك سنوفر الوقت وسنقوم بإستخدامها. لاحظ أن قرب أسفل المخطط هنالك سطر ('@yield('content وهذه دالة ستقوم بتحميل محتوانا الحالي.الإشارة إلى مخططك في عرضك view باستخدام ('extends('app@ ولفها عن طريق كتلة ('section('content@، مثل التالي: @extends('app') @section('content') This is my /resources/views/projects/index.blade.php file! @endsection سنقوم الآن بتنفيذ هذه الخطوات بإنشاء عروض show.blade.php و create.blade.php و index.blade.php في مجلد resources/views/projects/ مع الشيفرات (markup) المذكورة أعلاه وقُم بتغيير اسم الملف إذا كان الأمر ضروريا، ثم قُم بعمل تحديث للصفحة projects/ في متصفحك، وسوف ترى هيكل app.blade.php حول محتويات عرضك (view). الربط بين الطريق (route) والنموذجسيوفر Laravel بشكل افتراضي معرف رقمي ID للعديد من توابع متحكِّمات الموارد مثل ()show و ()edit و ()update و ()destroy، وهذا الأمر سيضيف العديد من الشيفرات الجاهزة (boilerplate) التي نحتاج إلى كتابتها، مثل الحصول على مثيل النموذج والتأكد من وجودها وغيرها. ولهذا سوف نستخدم إحدى مميزات Laravel والتي تدعى الربط بين الطريق و النموذج route model binding، فبدل من توفير متغير id$، سوف نقوم بإعطاء الوظيفة (method) كائن project$ أو task$. قُم بفتح app/Http/routes.php/ وأضف هذين السطرين (أول سطرين بعد التعليق): // Provide controller methods with object instead of ID Route::model('tasks', 'Task'); Route::model('projects', 'Project'); // Use slugs rather than IDs in URLs Route::bind('tasks', function($value, $route) { return App\Task::whereSlug($value)->first(); }); Route::bind('projects', function($value, $route) { return App\Project::whereSlug($value)->first(); }); Route::resource('projects', 'ProjectsController'); Route::resource('projects.tasks', 'TasksController'); وفي TasksController و ProjectsController (ملفات app/Http/Controllers/ProjectsController.php/ و app/Http/Controllers/TasksController.php/) قُم باستبدال كل وظيفة (method) مُعرف بمرجع id$ بـ task$ أو project$ مثل التالي: // public function edit($id) public function edit(Project $project)لا تنسَ إضافة use App\Task و use App\Project في أعلى المتحكِّمات حتى نشير إلى هذه النماذج. لا تقلق إذا لم تفهم هذه التغييرات، فسنقوم بعرض الشيفرة البرمجة الكاملة لـ TasksController و ProjectsController لاحقا. وفي هذه المرحلة يمكنك تمرير الكائن (object) إلى عرضه في كل متحكِّم لوظيفة (method) الإظهار والتعديل والتحديث حتى نستطيع استخدامهم لاحقا: public function edit(Project $project) { return view('projects.show', compact('project')); }سوف يحتاج TasksController إلى بضعة تعديلات طفيفة أخرى، وبما أننا نستخدم الموارد المضمّنة nested resources، سيخبرنا php artisan route:list أن جميع طرق task تحتوي على قناع {projects} بالإضافة إلى أن بعضها يستقبل قناع {tasks} أيضا. و كنتيجة لذلك، سيتم تمرير مثيل Project كمُعامل أول لتوابع المتحكِّمات (controller methods)، لذلك قُم بتحديثها وقٌم بتمرير متغير project$ الجديد. إذا لم تفهم خطوات الإضافة لـ TasksController و ProjectsController فهذه هي الشيفرة الكاملة للملفين بعد كل التعديلات: // /app/Http/Controllers/ProjectsController.php <?php namespace App\Http\Controllers; use App\Project; use App\Http\Requests; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class ProjectsController extends Controller { /** * Display a listing of the resource. * * @return Response */ public function index() { $projects = Project::all(); return view('projects.index', compact('projects')); } /** * Show the form for creating a new resource. * * @return Response */ public function create() { return view('projects.create'); } /** * Store a newly created resource in storage. * * @return Response */ public function store() { // } /** * Display the specified resource. * * @param \App\Project $project * @return Response */ public function show(Project $project) { return view('projects.show', compact('project')); } /** * Show the form for editing the specified resource. * * @param \App\Project $project * @return Response */ public function edit(Project $project) { return view('projects.edit', compact('project')); } /** * Update the specified resource in storage. * * @param \App\Project $project * @return Response */ public function update(Project $project) { // } /** * Remove the specified resource from storage. * * @param \App\Project $project * @return Response */ public function destroy(Project $project) { // } } // /app/Http/Controllers/TasksController.php <?php namespace App\Http\Controllers; use App\Project; use App\Task; use App\Http\Requests; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class TasksController extends Controller { /** * Display a listing of the resource. * * @param \App\Project $project * @return Response */ public function index(Project $project) { return view('tasks.index', compact('project')); } /** * Show the form for creating a new resource. * * @param \App\Project $project * @return Response */ public function create(Project $project) { return view('tasks.create', compact('project')); } /** * Store a newly created resource in storage. * * @param \App\Project $project * @return Response */ public function store(Project $project) { // } /** * Display the specified resource. * * @param \App\Project $project * @param \App\Task $task * @return Response */ public function show(Project $project, Task $task) { return view('tasks.show', compact('project', 'task')); } /** * Show the form for editing the specified resource. * * @param \App\Project $project * @param \App\Task $task * @return Response */ public function edit(Project $project, Task $task) { return view('tasks.edit', compact('project', 'task')); } /** * Update the specified resource in storage. * * @param \App\Project $project * @param \App\Task $task * @return Response */ public function update(Project $project, Task $task) { // } /** * Remove the specified resource from storage. * * @param \App\Project $project * @param \App\Task $task * @return Response */ public function destroy(Project $project, Task $task) { // } }لاحظ أنه إذا قمت بتحديث صفحة projects/project-1/ سيبقى كل شيء يعمل. عرض نماذجناصفحة عرض قائمة المشاريع، حان الآن وقت البدء بعرض المشاريع والمهام، قٌم بفتح projects/ في متصفحك. وبالاعتماد على php artisan route:list، ستكون هذه الصفحة هي صفحة عرض المشاريع، لذلك قُم بفتح resources/views/projects/index.blade.php/ وأضف التالي: @extends('app') @section('content') <h2>Projects</h2> @if ( !$projects->count() ) You have no projects @else <ul> @foreach( $projects as $project ) <li><a href="{{ route('projects.show', $project->slug) }}">{{ $project->name }}</a></li> @endforeach </ul> @endif @endsectionسوف أشرح بعض النقاط في هذه الشفرة البرمجية: استخدمنا في هذه الشفرة لغة Blade للقَوْلَبة، لذلك فإن if و foreach تتحكم في تدفق flow الدوال بإضافة إلى أنها دالة طباعة (الأقواس المعقوفة المزدوجة).تأكدنا إن كان هنالك أي مشروع لعرضه، إن كان هنالك أية مشاريع فسيقوم بعرضها وإن لم يكن تظهر رسالة تخبرك بذلك.استدعينا مساعد ()route مع طريق ذا اسم (يمكنك رؤية قائمة الطرق ذات الاسم عن طريق php artisan route:list) لربط كل مشروع مع صفحة تفاصيله.سوف تحتاج أيضا إلى تمرير متغير projects$ لهذا العرض view وإلا ستحصل على خطأ متغير غير معرف undefined variable error. قُم بفتح app/Http/controllers/ProjectsController.php/ وقُم بتحديث الوظيفة ()index إلى: public function index() { $projects = Project::all(); return view('projects.index', compact('projects')); }قُم بتحديث الصفحة (Refresh) وستجد قائمة من مشاريعك. علاقات النموذج - صفحة تفاصيل المشروعفي صفحة تفاصيل المشروع نحتاج إلى عرض قائمة من مهام المشاريع، وللقيام بذلك نحتاج إلى تعريف علاقة "واحد إلى الكثير one-to-many" في نموذج Project للسماح له بالحصول على المهام tasks. قُم بفتح app/Project.php/ وأضف التابع ()tasks كالتالي: public function tasks() { return $this->hasMany('App\Task'); }بشكل عكسي، يمكننا إضافة علاقة "الكثير إلى واحد many-to-one" لنموذج المهام Task: public function project() { return $this->belongsTo('App\Project'); }للتأكد من أنها تعمل اكتب الأمر: $ php artisan tinkerوستكون النّتيجة كالتي حسب المدخلات: >App\Project::whereSlug('project-1')->first()->tasks->count(); 5 >App\Project::whereSlug('project-2')->first()->tasks->count(); 2 >App\Task::first()->project->name; Project 1ممتاز، يمكننا الآن تحديث عرض resources/views/projects/show.blade.php/: @extends('app') @section('content') <h2>{{ $project->name }}</h2> @if ( !$project->tasks->count() ) Your project has no tasks. @else <ul> @foreach( $project->tasks as $task ) <li><a href="{{ route('projects.tasks.show', [$project->slug, $task->slug]) }}">{{ $task->name }}</a></li> @endforeach </ul> @endif @endsectionاضغط على أي مشروع في صفحة عرض قائمة المشاريع في متصفحك وسوف يتم عرض المشروع مع جميع المهام المرتبطة به. وأخير تَبقى لدينا صفحة عرض المهام (resources/views/tasks/show.blade.php/)، وهذه سهلة للغاية: @extends('app') @section('content') <h2> {!! link_to_route('projects.show', $project->name, [$project->slug]) !!} - {{ $task->name }} </h2> {{ $task->description }} @endsectionملاحظة: كُن حذرا عندما تستخدم علاقات النماذج (models)، فإنه من السهل إنشاء عدد كبير من استعلامات SQL، وتسمى هذه المشكلة بـ "مشكلة N+1". الخاتمةاليوم تعلمنا الكثير من الأشياء الجديدة مثل: الربط بين الطريق (route) و النموذجالنماذج (مع علاقة واحد إلى الكثير one-to-many)المتحكِّمات (مع الربط بين الطريق و النموذج)العروض (مع لغة blade للقَوْلَبة والمخططات)أصبحت الصفحة تعرض لنا قائمة من المشاريع والمهام، وفي الدرس القادم سوف نركز على تعديل وإضافة وحذف المشاريع والمهام. ترجمة -وبتصرّف- للمقال Creating a Basic ToDo Application in Laravel 5 – Part 2. حقوق الصورة البارزة: Designed by Freepik.
  4. حتى الآن تعلمنا كيفية تثبيت وإعداد Laravel، بالإضافة إلى إعداد بعض المشاريع والمهام والموارد المضمّنة و عرضهم على المستخدم، كما أنشأنا وظائف الإنشاء والتعديل والحذف، وفي هذا الفصل سوف نختم الدرس عن طريق إضافة استمارة التحقق. استمارة التحقق من جانب الخادمعلى الرغم من أن استمارات الإنشاء والتعديل تعمل إلا أننا لم نقم بالتحقق من ما يتم إدخاله، وهذا ما سنقوم بعمله اليوم. هنالك طرق متعددة للتعامل مع استمارة التحقق، بعضها أفضل من الآخر، ولهذا التطبيق الصغير نقترح أن نستخدم وظيفة المتحكِّمات ()validate مع كائن Illuminate\Http\Request مثل هذا، في ملف app/Http/Controllers/ProjectsController.php/: // /app/Http/Controllers/ProjectsController.php use Illuminate\Http\Request; class ProjectsController extends Controller { protected $rules = [ 'name' => ['required', 'min:3'], 'slug' => ['required'], ]; /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return Response */ public function store(Request $request) { $this->validate($request, $this->rules); $input = Input::all(); Project::create( $input ); return Redirect::route('projects.index')->with('message', 'Project created'); } /** * Update the specified resource in storage. * * @param \App\Project $project * @param \Illuminate\Http\Request $request * @return Response */ public function update(Project $project, Request $request) { $this->validate($request, $this->rules); $input = array_except(Input::all(), '_method'); $project->update($input); return Redirect::route('projects.show', $project->slug)->with('message', 'Project updated.'); }وأما في ملف app/Http/Controllers/TasksController.php/: // /app/Http/Controllers/TasksController.php use Illuminate\Http\Request; class TasksController extends Controller { protected $rules = ['name' => ['required', 'min:3'], 'slug' => ['required'], 'description' => ['required'], ]; /** * Store a newly created resource in storage. * * @param \App\Project $project * @param \Illuminate\Http\Request $request * @return Response */ public function store(Project $project, Request $request) { $this->validate($request, $this->rules); $input = Input::all(); $input['project_id'] = $project->id; Task::create( $input ); return Redirect::route('projects.show', $project->slug)->with('Task created.'); } /** * Update the specified resource in storage. * * @param \App\Project $project * @param \App\Task $task * @param \Illuminate\Http\Request $request * @return Response */ public function update(Project $project, Task $task, Request $request) { $this->validate($request, $this->rules); $input = array_except(Input::all(), '_method'); $task->update($input); return Redirect::route('projects.tasks.show', [$project->slug, $task->slug])->with('message', 'Task updated.'); }سوف نحتاج أيضا إلى مكان لعرض أية أخطاء، لذلك قُم بفتح resources/views/app.blade.php/ وأضف السطور التالية أسفل ('yield('content@: <div class="content"> @if (Session::has('message')) <div class="flash alert-info"> <p>{{ Session::get('message') }}</p> </div> @endif @if ($errors->any()) <div class='flash alert-danger'> @foreach ( $errors->all() as $error ) <p>{{ $error }}</p> @endforeach </div> @endif @yield('content') </div>إذا أردت قائمة كاملة من قواعد التحقق، أنصحك بزيارة التوثيق الرسمي. من المفترض أن يعمل كل شيء الآن، وإذا كان عكس ذلك، فسوف تقوم ()this->validate$ بتوجيهك إلى الصفحة الحالية مع الأخطاء التي سوف تظهر على الصفحة. خاتمةلقد قمنا في هذه الدورة بتعلم الكثير من الأشياء حول Laravel، مثل كيفية تثبيت وإعداد Laravel 5 بالإضافة إلى بعض المفاهيم المتقدمة مثل الربط بين الطريق والنموذج route model binding والحماية من CSRF، وعلى الرغم من بساطة التطبيق الذي قمنا به إلا أنه بداية جيدة لكل من يريد احتراف Laravel. ترجمة -وبتصرّف- للمقال Creating a Basic ToDo Application in Laravel 5 – Part 4. حقوق الصورة البارزة: Designed by Freepik.
  5. حتى الآن تعلمنا كيفية تثبيت وإعداد Laravel، بالإضافة إلى أننا قمنا بـإعداد بعض موارد المشاريع والمهام وعرضهم للمستخدم. في هذا الدرس، سنتعلم كيفية إنشاء وتعديل وحذف الصفحات والإجراءات. إضافة روابط التصفحقبل أن نفعل أي شيء، سنقوم بإضافة روابط create/edit/delete/back إلى صفحات المشاريع والمهام: <!-- /resources/views/projects/index.blade.php --> @extends('app') @section('content') <h2>Projects</h2> @if ( !$projects->count() ) You have no projects @else <ul> @foreach( $projects as $project ) <li> {!! Form::open(array('class' => 'form-inline', 'method' => 'DELETE', 'route' => array('projects.destroy', $project->slug))) !!} <a href="{{ route('projects.show', $project->slug) }}">{{ $project->name }}</a> ( {!! link_to_route('projects.edit', 'Edit', array($project->slug), array('class' => 'btn btn-info')) !!}, {!! Form::submit('Delete', array('class' => 'btn btn-danger')) !!} ) {!! Form::close() !!} </li> @endforeach </ul> @endif <p> {!! link_to_route('projects.create', 'Create Project') !!} </p> @endsection <!-- /resources/views/projects/show.blade.php --> @extends('app') @section('content') <h2>{{ $project->name }}</h2> @if ( !$project->tasks->count() ) Your project has no tasks. @else <ul> @foreach( $project->tasks as $task ) <li> {!! Form::open(array('class' => 'form-inline', 'method' => 'DELETE', 'route' => array('projects.tasks.destroy', $project->slug, $task->slug))) !!} <a href="{{ route('projects.tasks.show', [$project->slug, $task->slug]) }}">{{ $task->name }}</a> ( {!! link_to_route('projects.tasks.edit', 'Edit', array($project->slug, $task->slug), array('class' => 'btn btn-info')) !!}, {!! Form::submit('Delete', array('class' => 'btn btn-danger')) !!} ) {!! Form::close() !!} </li> @endforeach </ul> @endif <p> {!! link_to_route('projects.index', 'Back to Projects') !!} | {!! link_to_route('projects.tasks.create', 'Create Task', $project->slug) !!} </p> @endsectionهذه الشفرة البرمجية مفهومة، الصعوبة تكمن في رابط الحذف، متحكِّمات الموارد تتطلب إرسال وظيفة HTTP DELETE، وهذا لا يمكن أن يتم مع رابط عادي، لذلك يتطلب نموذج يتم تقديمه إلى طريق route محدد. للمزيد من المعلومات قُم بزيارة إجراءات يتم التحكم بها عن طريق متحكِّمات الموارد. إنشاء صفحات الإضافة والتعديلبعد الانتهاء من صفحات عرض قائمة المشاريع، نحتاج إلى إمكانية إضافة وحذف المشاريع والمهام. استمارات الإضافة والحذف ستكون متشابهة كثيرا، لذلك بدلا من تكرارهم، سنقوم بوراثتهم من نموذج واحد. سوف نبدأ مع عروض create/edit للمشروع: <!-- /resources/views/projects/create.blade.php --> @extends('app') @section('content') <h2>Create Project</h2> {!! Form::model(new App\Project, ['route' => ['projects.store']]) !!} @include('projects/partials/_form', ['submit_text' => 'Create Project']) {!! Form::close() !!} @endsection <!-- /resources/views/projects/edit.blade.php --> @extends('app') @section('content') <h2>Edit Project</h2> {!! Form::model($project, ['method' => 'PATCH', 'route' => ['projects.update', $project->slug]]) !!} @include('projects/partials/_form', ['submit_text' => 'Edit Project']) {!! Form::close() !!} @endsectionقُم بعمل نفس الشيء مع المهام لكن لا تنسَ تحديث الطرق (routes): <!-- /resources/views/tasks/create.blade.php --> @extends('app') @section('content') <h2>Create Task for Project "{{ $project->name }}"</h2> {!! Form::model(new App\Task, ['route' => ['projects.tasks.store', $project->slug], 'class'=>'']) !!} @include('tasks/partials/_form', ['submit_text' => 'Create Task']) {!! Form::close() !!} @endsection <!-- /resources/views/tasks/edit.blade.php --> @extends('app') @section('content') <h2>Edit Task "{{ $task->name }}"</h2> {!! Form::model($task, ['method' => 'PATCH', 'route' => ['projects.tasks.update', $project->slug, $task->slug]]) !!} @include('tasks/partials/_form', ['submit_text' => 'Edit Task']) {!! Form::close() !!} @endsectionالآن توجد عدة مفاهيم جديدة: إضافة جزئيةالاستمارة تتطلب عدة وسوم، وبدلا من ذلك سنقوم بتقسيمها من جزئية _form ونضعها مباشرة في العرض، استمارة Add هي من نوع POST ترسل البيانات إلى طريق projects.store واستمارة Edit هي من نوع PATCH وترسل البيانات إلى projects.update. قد يبدوا هذا معقدا ومبهم لكن هذه هي الطريقة التي تعمل بها المتحكِّمات. لاحظ أننا استخدمنا ()Form::model، وتسمى هذه نموذج الاستمارة الملزمة و ليس لدى هذه أهمية كبيرة الآن، فهي تُستخدم للتعبئة التلقائية وسوف نحتاجها في وقت لاحقا عندما نضيف الحقول باستخدام ()Form::input.الحماية من CSRF:مساعدي الاستمارة (Form helpers) توفر العديد من الوظائف مجانا، فإذا ذهبت إلى projects/create/ ورأيت مصدر الصفحة ستجد شيئا مشابها لهذا: <form method="POST" action="http://l4todo.localhost.com/projects" accept-charset="UTF-8"> <input name="_token" type="hidden" value="Y8uOo7SeD5tQZExezDf5a7UwiYR4P6qIHEUKJNxI"> </form>هل ترى حقل token_ ؟ هذا هو الرمز المميز لـ CSRF مُنشئ تِلقائيا بواسطة استدعاء {{ ()Form::model }} الذي يمنع ثغرة CSRF. يكفي أن نقول أن هذا شيئ مفيد وأننا لم نقم بأي شيئ للحصول عليه. إنشاء استمارة التعديلنحن بحاجة إلى ترميز (markup) الاستمارة للمشاريع والمهام، وبفضل نموذج الاستمارة الملزمة يمكننا فقط استخدام مساعدي الاستمارة في Laravel لإخراج كافة الحقول التي نحتاجها. <!-- /resources/views/projects/partials/_form.blade.php --> <div class="form-group"> {!! Form::label('name', 'Name:') !!} {!! Form::text('name') !!} </div> <div class="form-group"> {!! Form::label('slug', 'Slug:') !!} {!! Form::text('slug') !!} </div> <div class="form-group"> {!! Form::submit($submit_text, ['class'=>'btn primary']) !!} </div> <!-- /resources/views/tasks/partials/_form.blade.php --> <div class="form-group"> {!! Form::label('name', 'Name:') !!} {!! Form::text('name') !!} </div> <div class="form-group"> {!! Form::label('slug', 'Slug:') !!} {!! Form::text('slug') !!} </div> <div class="form-group"> {!! Form::label('completed', 'Completed:') !!} {!! Form::checkbox('completed') !!} </div> <div class="form-group"> {!! Form::label('description', 'Description:') !!} {!! Form::textarea('description') !!} </div> <div class="form-group"> {!! Form::submit($submit_text) !!} </div>هذا كل شيئ، سوف تستطيع الأن التصفح في صفحات الإضافة والتعديل، الأمر كان سهلا للغاية. جعل الاستمارات تعمللدينا استمارات الإضافة والتعديل للمشروع و المهام، بالإضافة إلى استمارة مُضللة لحذفهم، الآن يجب علينا أن نجعلهم يعملون لأداء مهامهم. أولا، أضف هذا في أعلى المتحكِّمات: use Input; use Redirect;والآن لوظائف store و update و destroy: // ProjectsController public function store() { $input = Input::all(); Project::create( $input ); return Redirect::route('projects.index') ->with('message', 'Project created'); } public function update(Project $project) { $input = array_except(Input::all(), '_method'); $project->update($input); return Redirect::route('projects.show', $project->slug) ->with('message', 'Project updated.'); } public function destroy(Project $project) { $project->delete(); return Redirect::route('projects.index')->with('message', 'Project deleted.'); } // TasksController public function store(Project $project) { $input = Input::all(); $input['project_id'] = $project->id; Task::create( $input ); return Redirect::route('projects.show', $project->slug) ->with('message', 'Task created.'); } public function update(Project $project, Task $task) { $input = array_except(Input::all(), '_method'); $task->update($input); return Redirect::route('projects.tasks.show', [$project->slug, $task->slug]) ->with('message', 'Task updated.'); } public function destroy(Project $project, Task $task) { $task->delete(); return Redirect::route('projects.show', $project->slug)->with('message', 'Task deleted.'); }الشفرة البرمجية في الأعلى مفهومة ولا داعي لشرحها. إذا قمت الآن بتقديم إحدى الاستمارات فسوف تحصل على خطأ MassAssignmentException: _token، فالإحالة الكتلية تحدث عندما تقوم بتمرير مصفوفة بيانات إلى ()Model::create أو ()Model::update من المتحكِّمات بدل من وضع حقل واحد في نفس الوقت، ولإصلاح هذا، قم ببساطة بإضافة خاصية guarded إلى كل نموذج. class Project extends Model { protected $guarded = []; class Task extends Model { protected $guarded = [];رسائل الفلاشسوف تلاحظ من الشفرة السابقة أننا استخدمنا دالة ()with، وهذه الدالة تقوم بتمرير متغير فلاش (يستخدم لمرة واحدة) للجلسة session والتي يمكن قراءتها عند تحميل الصفحة التالية. والآن نحتاج إلى التأكد من تلك الرسالة وعرضها على المستخدم. قُم بفتح resources/views/app.blade.php/ وأضف التالي: ... <div class="content"> @if (Session::has('message')) <div class="flash alert-info"> <p>{{ Session::get('message') }}</p> </div> @endif @yield('content') </div> ...حاول إنشاء مشروع، هذه الرسالة ستظهر مهما حدّثت الصفحة وستذهب بعد فترة. خاتمةاليوم قمنا بأشياء مثيرة للغاية، فلقد أضفنا استمارات الإضافة والتعديل والحذف وتعلمنا حول CSRF و نموذج الاستمارة الملزمة بالإضافة إلى تعلمنا المزيد حول blade و الدوال. كل شيئ الآن يعمل، يمكن تجربة التطبيق وإنشاء وتعديل وحذف المهام والمشاريع، وفي أي وقت يمكنك كتابة الأمر: php artisan migrate:refresh –seed وسوف يتم إعادة تعيين قواعد البيانات. في المرحلة القادمة والتي ستكون النهائية سوف نقوم بالتحقق من الاستمارات. ترجمة -وبتصرّف- للمقال Creating a Basic ToDo Application in Laravel 5 – Part 3. حقوق الصورة البارزة: Designed by Freepik.
  6. يعتبر Laravel أشهر إطار ويب بلغة PHP، ولقد شهد إصداره الخامس العديد من التغييرات وتمت إضافة الكثير من المميزات الجديدة، ولذلك لتعلم أساسيات هذا الإطار سوف نقوم بإنشاء تطبيق Todo List، وسوف نتعلم من خلال هذا التطبيق الكثير من المفاهيم والطرق البرمجية حتى نتمكن من التعامل والتوسع مع إطار Laravel 5. ملاحظة: هذا الدرس طويل للغاية لذلك سوف يتم تقسيمه إلى أجزاء أصغر، ويمكنك الحصول على الكود المصدري لكل جزء من GitHub. في هذا الدرس سوف نتحدث عن تثبيت Laravel 5 وإعداده وعن بعض التقنيات الجديد كالتهجير migration والبذر seeding. قبل أن نبدأ أهم المصطلحات التي ستصادفنا في هذه الدروس: التهجير migration: نظام لإدارة قواعد البيانات، فهو يسمح للفريق بتعديل مخطط قواعد البيانات لجميع الأعضاء. البذر seeding: يقصد بها إدخال البيانات الأولية لتجربة التطبيق، أي أنه سيقوم بإدخال بيانات لمساعدتك على التطوير واكتشاف الأخطاء. هدف المشروع سوف يتكون تطبيقنا من مشروع أو أكثر، كل واحد لديه قائمة مهام خاصة به، وسوف تتمكن من إنشاء وعرض وتعديل وحذف المهام والمشاريع. في هذا الدرس سوف نقوم بـ: إعداد وتنصيب Laravel. تركيب حزم إضافية لتسهيل عملية التطوير. استخدام التهجير migration والبذر seeds. تعلم كيفية استخدام متحكِّمات الموارد resourceful controllers. تعلم كيفية استخدام العروض views. (بما في ذلك نظام blade ومخططات المحتوى) التعامل مع علاقات النماذج. التثبيت إن عملية تثبيت Laravel سهلة للغاية بفضل Composer، لذلك سوف نستخدمه في تثبيته. استخدام Composer والآن نقوم بتشغيل مثبت Laravel (سوف تحتاج إلى عمل هذا لمرة واحدة فقط): composer global require "laravel/installer=~1.1" والآن نقوم بعمل مشروعنا: laravel new l5todo الإعداد يستخدم Laravel 5 حزمة تدعى DotEnv تقوم بتخزين المعلومات الحساسة في ملفات ذات صيغة .env والتي يتم تحميلها كمتغيرات PHP عند التشغيل. قد يبدوا لك هذا معقدا لكن بكلمات أخرى، هذا يعني أن فقط الإعدادات الحسّاسة credentials يتم تخزينها في هذه الملفات وأما بقية إعداداتك فيتم تخزينها في ملفات الإعداد العادية. قاعدة البيانات سوف نحتاج إلى قاعدة بيانات، لذلك سنقوم بعمل واحدة ثم سنقوم بنسخ .env.example إلى .env وتحديث البيانات على الشكل التالي: DB_HOST=localhost DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret في النهاية إذا لم تكن تستخدم MySQL فقُم بفتح config/database.php/ ثم قٌم بتغيير السطر الافتراضي: 'default' => 'mysql', تذكر أن تضيف ملفات بيئة عملك إلى .gitignore عن طريق إضافة سطر .env. خطواتنا الأولى كما ذكرنا في الأعلى، سوف يتكون تطبيق قائمة المهام على مشروع أو أكثر كل واحد مع قائمة المهام الخاصة به، ولذلك سوف نحتاج إلى مشروع، نماذج مهام، متحكِّمات، عروض views، التهجير migration، البذور seeds والطرق routes، ولقد قمنا بشرح بعض هذه المصطلحات في بداية الدرس. لنبدأ بالتعامل معهم كل واحد على حدة. التهجير migration أولا نريد أن نرى مخطط جدولنا، سوف يبدو مثل هذا: Projects +------------+------------------+------+-----+ | Field | Type | Null | Key | +------------+------------------+------+-----+ | id | int(10) unsigned | NO | PRI | | name | varchar(255) | NO | | | slug | varchar(255) | NO | | | created_at | timestamp | NO | | | updated_at | timestamp | NO | | +------------+------------------+------+-----+ Tasks +-------------+------------------+------+-----+ | Field | Type | Null | Key | +-------------+------------------+------+-----+ | id | int(10) unsigned | NO | PRI | | project_id | int(10) unsigned | NO | MUL | | name | varchar(255) | NO | | | slug | varchar(255) | NO | | | completed | tinyint(1) | NO | | | description | text | NO | | | created_at | timestamp | NO | | | updated_at | timestamp | NO | | +-------------+------------------+------+-----+ ثم سوف نقوم بعمل التهجير migration: php artisan make:migration create_projects_and_tasks_tables --create="projects" سوف نقوم بعمل كِلا الجدولين بتهجير migration واحد حتى نتمكن من حذفها بترتيب عكسي لتجنب سلامة خرق القيد integrity constraint violation، قُم بفتح: /database/migrations/createprojectsandtasks_tables.php وقُم بتحديث المعلومات حسب الآتي: <?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateProjectsAndTasksTables extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('projects', function(Blueprint $table) { $table->increments('id'); $table->string('name')->default(''); $table->string('slug')->default(''); $table->timestamps(); }); Schema::create('tasks', function(Blueprint $table) { $table->increments('id'); $table->integer('project_id')->unsigned()->default(0); $table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade'); $table->string('name')->default(''); $table->string('slug')->default(''); $table->boolean('completed')->default(false); $table->text('description')->default(''); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('tasks'); Schema::drop('projects'); } } قم بتنفيذ الهجرة migration: php artisan migrate إذا قمت الآن بمراجعة قاعدة البيانات، يجب أن تكون الجداول مكتملة. البذور Seeds سوف نحتاج إلى بذر المشاريع/المهام ليكون لديك شيء للعمل معه عندما نصل إلى المتصفح، لذلك قم بإنشاء: /database/seeds/ProjectsTableSeeder.php و TasksTableSeeder.php كالتالي: // /database/migrations/seeds/ProjectsTableSeeder.php <?php use Illuminate\Database\Seeder; class ProjectsTableSeeder extends Seeder { public function run() { // Uncomment the below to wipe the table clean before populating DB::table('projects')->delete(); $projects = array( ['id' => 1, 'name' => 'Project 1', 'slug' => 'project-1', 'created_at' => new DateTime, 'updated_at' => new DateTime], ['id' => 2, 'name' => 'Project 2', 'slug' => 'project-2', 'created_at' => new DateTime, 'updated_at' => new DateTime], ['id' => 3, 'name' => 'Project 3', 'slug' => 'project-3', 'created_at' => new DateTime, 'updated_at' => new DateTime], ); // Uncomment the below to run the seeder DB::table('projects')->insert($projects); } } // /database/migrations/seeds/TasksTableSeeder.php <?php use Illuminate\Database\Seeder; class TasksTableSeeder extends Seeder { public function run() { // Uncomment the below to wipe the table clean before populating DB::table('tasks')->delete(); $tasks = array( ['id' => 1, 'name' => 'Task 1', 'slug' => 'task-1', 'project_id' => 1, 'completed' => false, 'description' => 'My first task', 'created_at' => new DateTime, 'updated_at' => new DateTime], ['id' => 2, 'name' => 'Task 2', 'slug' => 'task-2', 'project_id' => 1, 'completed' => false, 'description' => 'My first task', 'created_at' => new DateTime, 'updated_at' => new DateTime], ['id' => 3, 'name' => 'Task 3', 'slug' => 'task-3', 'project_id' => 1, 'completed' => false, 'description' => 'My first task', 'created_at' => new DateTime, 'updated_at' => new DateTime], ['id' => 4, 'name' => 'Task 4', 'slug' => 'task-4', 'project_id' => 1, 'completed' => true, 'description' => 'My second task', 'created_at' => new DateTime, 'updated_at' => new DateTime], ['id' => 5, 'name' => 'Task 5', 'slug' => 'task-5', 'project_id' => 1, 'completed' => true, 'description' => 'My third task', 'created_at' => new DateTime, 'updated_at' => new DateTime], ['id' => 6, 'name' => 'Task 6', 'slug' => 'task-6', 'project_id' => 2, 'completed' => true, 'description' => 'My fourth task', 'created_at' => new DateTime, 'updated_at' => new DateTime], ['id' => 7, 'name' => 'Task 7', 'slug' => 'task-7', 'project_id' => 2, 'completed' => false, 'description' => 'My fifth task', 'created_at' => new DateTime, 'updated_at' => new DateTime], ); //// Uncomment the below to run the seeder DB::table('tasks')->insert($tasks); } } ولا تنسَ إضافة أصناف البذور(seed classes) إلى database/seeds/DatabaseSeeder.php/ : use Illuminate\Database\Seeder; use Illuminate\Database\Eloquent\Model; class DatabaseSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { Model::unguard(); $this->call('ProjectsTableSeeder'); $this->call('TasksTableSeeder'); } } الآن نقوم بالبذر: composer dump-autoload ثم: php artisan db:seed # أو php artisan migrate:refresh --seed يجب الآن أن تكون قاعدة البيانات قد تم بذرها. mysql> select * from projects; +----+-----------+-----------+---------------------+---------------------+ | id | name | slug | created_at | updated_at | +----+-----------+-----------+---------------------+---------------------+ | 1 | Project 1 | project-1 | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 | | 2 | Project 2 | project-2 | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 | | 3 | Project 3 | project-3 | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 | +----+-----------+-----------+---------------------+---------------------+ mysql> select * from tasks; +----+------------+--------+--------+-----------+----------------+---------------------+---------------+ | id | project_id | name | slug | completed | description | created_at | updated_at | +----+------------+--------+--------+-----------+----------------+---------------------+---------------+ | 1 | 1 | Task 1 | task-1 | 0 | My first task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 | 2 | 1 | Task 2 | task-2 | 0 | My first task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 | 3 | 1 | Task 3 | task-3 | 0 | My first task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 | 4 | 1 | Task 4 | task-4 | 1 | My second task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 | 5 | 1 | Task 5 | task-5 | 1 | My third task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 | 6 | 2 | Task 6 | task-6 | 1 | My fourth task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 | 7 | 2 | Task 7 | task-7 | 0 | My fifth task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 +----+------------+--------+--------+-----------+----------------+---------------------+---------------+ النماذج Models للعمل مع جداول المشاريع والمهام نحتاج إلى نماذج مماثلة، سوف نقوم بإنشائها الآن: php artisan make:model Project php artisan make:model Task كان هذا سهلا استخدام Artisan – Tinker الآن لدينا المعلومات في قاعدة البيانات وسيكون من الرائع أن نتعلم حول واحدة من أهم ميزات artisan وهي Tinker الذي يوفر لك سطر أوامر للتعامل مع Laravel، وكمثال، لنستخدمه في معرفة عدد المشاريع في قاعدة البيانات الحالية: $ php artisan tinker > App\Project::count(); 3 > App\Task::count(); 7 وكما ترى يمكن أن يكون Tinker مفيدا للغاية، لذلك سوف نستخدمه عدة مرات في هذه السّلسلة. المُتحكِّمات Controllers الآن وصلنا إلى النقطة التي سوف نبدأ بعرض ما صنعناه على المتصفح، وسوف نحتاج إلى إنشاء بعض المتحكِّمات Controllers والطرق Routes. سنبدأ أولا بالمتحكِّمات: php artisan make:controller ProjectsController php artisan make:controller TasksController الموارد المُضمّنة نبدأ بإضافة موارد Project و Task إلى app/Http/routes.php/ : Route::get('/', 'WelcomeController@index'); //Route::get('home', 'HomeController@index'); // //Route::controllers([ // 'auth' => 'Auth\AuthController', // 'password' => 'Auth\PasswordController', //]); Route::resource('projects', 'ProjectsController');Route::resource('tasks', 'TasksController'); والآن دعونا نرى إحدى مميزات artisan والمُتمثّلة في route:list، في سطر الأوامر أكتب التالي: php artisan route:list لتكون النّتيجة +--------+----------+--------------------------+------------------+-------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+--------------------------+------------------+-------------------------------------------------+------------+ | | GET|HEAD | / | | App\Http\Controllers\WelcomeController@index | | | | GET|HEAD | projects | projects.index | App\Http\Controllers\ProjectsController@index | | | | GET|HEAD | projects/create | projects.create | App\Http\Controllers\ProjectsController@create | | | | POST | projects | projects.store | App\Http\Controllers\ProjectsController@store | | | | GET|HEAD | projects/{projects} | projects.show | App\Http\Controllers\ProjectsController@show | | | | GET|HEAD | projects/{projects}/edit | projects.edit | App\Http\Controllers\ProjectsController@edit | | | | PUT | projects/{projects} | projects.update | App\Http\Controllers\ProjectsController@update | | | | PATCH | projects/{projects} | | App\Http\Controllers\ProjectsController@update | | | | DELETE | projects/{projects} | projects.destroy | App\Http\Controllers\ProjectsController@destroy | | | | GET|HEAD | tasks | tasks.index | App\Http\Controllers\TasksController@index | | | | GET|HEAD | tasks/create | tasks.create | App\Http\Controllers\TasksController@create | | | | POST | tasks | tasks.store | App\Http\Controllers\TasksController@store | | | | GET|HEAD | tasks/{tasks} | tasks.show | App\Http\Controllers\TasksController@show | | | | GET|HEAD | tasks/{tasks}/edit | tasks.edit | App\Http\Controllers\TasksController@edit | | | | PUT | tasks/{tasks} | tasks.update | App\Http\Controllers\TasksController@update | | | | PATCH | tasks/{tasks} | | App\Http\Controllers\TasksController@update | | | | DELETE | tasks/{tasks} | tasks.destroy | App\Http\Controllers\TasksController@destroy | | +--------+----------+--------------------------+------------------+-------------------------------------------------+------------+ ستلاحظ أن كل من projects و tasks هي روابط ذات مستوى عالي، وفي تطبيقنا، المهام تتبع المشاريع، لذلك سيكون من الأفضل للروابط أن تكون مُضمّنة مثل /projects/1/tasks/3 بدلا من /tasks/، وهذا يمكن فعله باستخدام شيء اسمه الموارد المُضمّنة nested resources، وكما هو الحال مع أغلب الأشياء في Laravel، التعديل المطلوب سريع وبسيط، فقط قٌم بفتح /app/Http/routes.php وقٌم بالتعديلات التالية: // Route::resource('tasks', 'TasksController'); Route::resource('projects.tasks', 'TasksController'); هذا كل شيء، قُم بكتابة php artisan route:list لنعلم ماذا لدينا لحد الآن: php artisan route:list +--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+ | | GET|HEAD | / | | App\Http\Controllers\WelcomeController@index | | | | GET|HEAD | projects | projects.index | App\Http\Controllers\ProjectsController@index | | | | GET|HEAD | projects/create | projects.create | App\Http\Controllers\ProjectsController@create | | | | POST | projects | projects.store | App\Http\Controllers\ProjectsController@store | | | | GET|HEAD | projects/{projects} | projects.show | App\Http\Controllers\ProjectsController@show | | | | GET|HEAD | projects/{projects}/edit | projects.edit | App\Http\Controllers\ProjectsController@edit | | | | PUT | projects/{projects} | projects.update | App\Http\Controllers\ProjectsController@update | | | | PATCH | projects/{projects} | | App\Http\Controllers\ProjectsController@update | | | | DELETE | projects/{projects} | projects.destroy | App\Http\Controllers\ProjectsController@destroy | | | | GET|HEAD | projects/{projects}/tasks | projects.tasks.index | App\Http\Controllers\TasksController@index | | | | GET|HEAD | projects/{projects}/tasks/create | projects.tasks.create | App\Http\Controllers\TasksController@create | | | | POST | projects/{projects}/tasks | projects.tasks.store | App\Http\Controllers\TasksController@store | | | | GET|HEAD | projects/{projects}/tasks/{tasks} | projects.tasks.show | App\Http\Controllers\TasksController@show | | | | GET|HEAD | projects/{projects}/tasks/{tasks}/edit | projects.tasks.edit | App\Http\Controllers\TasksController@edit | | | | PUT | projects/{projects}/tasks/{tasks} | projects.tasks.update | App\Http\Controllers\TasksController@update | | | | PATCH | projects/{projects}/tasks/{tasks} | | App\Http\Controllers\TasksController@update | | | | DELETE | projects/{projects}/tasks/{tasks} | projects.tasks.destroy | App\Http\Controllers\TasksController@destroy | | +--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+ جعل روابط ذات اسم لطيف الطرق routes الحالية ممتازة لكنها ذات عناوين يمكن تحسينها، مثل هذا العنوان /projects/1/tasks/2، فسيكون من الرائع للزوار أن يتم تغيير المعرف الرقمي ID بالاسم اللطيف للحقول، فمثلا سوف نحصل على /projects/my-first-project/tasks/buy-milk بدلا من /projects/1/tasks/2. قم بفتح ملف /app/Http/routes.php وضع به التالي: Route::bind('tasks', function($value, $route) { return App\Task::whereSlug($value)->first(); }); Route::bind('projects', function($value, $route) { return App\Project::whereSlug($value)->first(); }); هذه الشيفرة سوف تغير السلوك الافتراضي لـ tasks و projects في artisan routes وجعل الروابط ذات إسم لطيف slug. خاتمة اليوم لقد قمنا بعمل عدة أشياء وهي: تثبيت وإعداد Laravel. إضافة موردان اثنان resources. إنشاء التهجيرات migrations. إضافة بعض بيانات البذور seeds. تكوين هيكل الروابط. بكلمات أخرى، قمنا اليوم بوضع الأساس التي سوف نعتمد عليه في الدروس القادمة من خلال إنشاء جميع العناصر اللازمة حتى تعمل الواجهة الأمامية، ولدينا الآن بعض البيانات في قاعدة البيانات بالإضافة إلى الطرق، في الدرس القادم سوف نبدأ في الواجهة الأمامية للموقع. هنالك بضعة مواقع أخرى لتحصل على المزيد من المعلومات وآخر الأخبار: The Laravel Twitter feed: أخر الأخبار حول تطورات Laravel. Taylor Otwell’s Twitter feed: حساب تويتر لمُؤسّس Laravel. Laravel.io: لمتابعة آخر الأخبار و الدورات من مختلف مواقع الويب، بالإضافة إلى بودكاست أسبوعي يتحدث عن الأفكار والاهتمامات ذات علاقة إلى المنصة. Laravel Packages Registry: مكان جيد لإيجاد أفضل حزم Laravel. Code Bright: كتاب إلكتروني مجاني من المؤلف دايلي ريس Dayle Rees. ترجمة وبتصرف للمقال: Creating a Basic ToDo Application in Laravel 5 – Part 1. حقوق الصورة البارزة: Designed by Freepik.