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



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

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

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

نوع المُحتوى


التصنيفات

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

التصنيفات

  • PHP
    • Laravel
    • ووردبريس
  • جافاسكريبت
    • Node.js
    • jQuery
    • AngularJS
    • Cordova
  • HTML5
  • CSS
    • Sass
    • إطار عمل Bootstrap
  • SQL
  • سي شارب #C
    • منصة Xamarin
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • إطار العمل 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

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

  1. تعرفنا في درس سابق على كيفية تفعيل وحدة mod_rewrite وضبطها لإعادة كتابة عناوين URL في خادوم Apache.ا سنعتمد في هذا الشرح على ما تعلمناه سابقًا ونتوسّع - مع مثاليْن عمليّيْن - في شرحٍ بعض من أكثر التّعليمات استخداما في ضبط mod_rewrite. المثال الأول – تبسيط نصوص الاستعلام Query strings باستخدام RewriteRule تستعمل تطبيقات الوِب في العادة نصوص الاستعلام التي يُمكن إضافتها إلى عنوان URL باستخدام علامة استفهام (?) بعد العنوان. تُمرَّر المُعاملات المُختلفة باستخدام علامة &. يُمكن استخدام نصوص الاستعلام لتمرير معلومات إضافيّة بين صفحات تطبيق الوِب. على سبيل المثال، يُمكن لصفحة نتائج بحث مكتوبة بلغة PHP أن تستعمل عنوانا مثل http://example.com/results.php?item=shirt&season=summer. في هذا المثال، هناك مُعاملان إضافيّان، المُعامل item مع القيمة shirt، والمُعامل season ذو القيمة summer. سيستعمل التّطبيق هذه المعلومات لتقديم أكثر نتيجة مناسبة للمُستخدم. تُكتب قواعد إعادة الكتابة في Apache عادة لتبسيط روابط طويلة مثل التي أعلاه إلى عناوين URL بسيطة سهلة القراءة والفهم. في هذا المثال، نريد تبسيط ما سبق ليكون على شكل http://example.com/shirt/summer. كما تُلاحظ، فالقيمتان shirt و summer لا تزالان مُتواجدتيْن داخل العنوان، لكن دون نصّ استعلام واسم ملفّ PHP. إليك قاعدة لتحقيق مُرادنا: RewriteRule ^shirt/summer$ results.php?item=shirt&season=summer [QSA] المقطع shirt/summer واضح وقد أخبرنا Apache بتوجيه أي طلبات مطابقة إلى العنوان results.php?item=shirt&season=summer. تُستخدم الخيارات [QSA] عادة في قواعد إعادة الكتابة. وتُخبر Apache بإضافة أي نصّ استعلام إضافي إلى عنوان URL المُقدَّم، لذا لو كتب زائر http://example.com/shirt/summer?page=2 فسيجيب الخادوم بـ results.php?item=shirt&season=summer&page=2. إن لم تُضف هذه الخيارات فسيُتجاهل نصّ الاستعلام الإضافي. رغم أنّ هذه الطّريقة تُحقّق هدفنا، إلّا أنّنا كتبنا القيمتين بصراحة داخل الملفّ. لذا فالقاعدة لن تعمل لأي قيم أخرى مثل pants وwinter. لجعل القاعدة عامّة أكثر، يُمكننا استخدام التّعابير النّمطيّة لمُطابقة أجزاء من العنوان الأصلي واستعمالها في مقطع بدل نمطي. بحيث تكون القاعدة المُعدّلة كما يلي: RewriteRule ^([A-Za-z0-9]+)/(summer|winter|fall|spring) results.php?item=$1&season=$2 [QSA] التّعبير النمطي الأول داخل القوسين يُطابق أي مقطع نصّ مكوّن من أحرف وأرقام مثل shirt و pants ويحفظ المقطع المُطابق في المُتغيّر $1. التّعبير النمطي الذي يتبعه يُطابق حرفيًّا كلّا من summer، winter، fall و spring، ويحفظ أي مُطابق في المُتغيّر $2. تُستعمل المقاطع المُطابقة بعدها في عنوان URL النّاتج لتمريرها إلى كل من المُعاملين item وseason عوضا عن كتابة القيمتين على نحو صريح كما فعلنا سابقا. القاعدة أعلاه ستستبدل على سبيل المثال العنوان http://example.com/pants/summer إلى http://example.com/results.php?item=pants&season=summer. هذا المثال قابل للتماشي مع التّطويرات المُستقبليّة كذلك، بحيث يُمكن إعادة كتابة العناوين لعدّة قيم باستخدام قاعدة واحدة فقط. المثال الثّاني – إضافة شروط منطقيّة باستخدام RewriteConds قواعد إعادة الكتابة ليست محصورة في قواعد تُترجم واحدة تلو الأخرى دون أية قيود. تُمكّننا تعليمة RewriteCond من إضافة شروط لقواعد إعادة الكتابة للتحكم في وقت ترجمة القواعد. تتّبع RewriteCond التّنسيق التّالي: RewriteCond TestString Condition [Flags] RewriteCond: تعليمة الشرط. TestString النّص الذي سيُجرى عليه الاختبار. Condition نمط أو شرط للاختبار به. Flags عبارة عن مُعاملات إضافيّة يُمكن لها تعديل الشّرط وقواعد التّحويل. إذا أرجع شرط في RewriteCond القيمة المنطقيّة true (أي أنّ الشرط قد تحقّق)، فستُنفَّذ قاعدة RewriteRule التي تلي الشرط مُباشرة. إن لم يتحقّق الشّرط فتُتجاهل القاعدة. يُمكن استخدام أكثر من شرط. يجب مبدئيًّا على جميع الشّروط أن تتحقّق لتطبيق القاعدة التي تليها. على سبيل المثال، لنفترض بأنّك تريد إعادة توجيه جميع الطّلبات المُوجّهة إلى ملفّات أو مُجلّدات غير موجودة إلى الصّفحة الرّئيسيّة عوضا عن عرض صفحة الخطأ 404. يُمكن تحقيق هذا الهدف بالشّروط التّاليّة: RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . / في المثال أعلاه: %{REQUEST_FILENAME} يُمثّل النصّ المُختبَر. في هذه الحالة، القيمة ستكون عبارة عن اسم الملفّ الذي طلبه المُستخدم وهو مُتغيّر نظام خاص يتوفّر في كل طلب. f- شرط متوفّر مُسبقا في وحدة mod_rewrite للتّحقّق من أنّ الاسم الذي طلبه المُستخدم مُتواجد على القرص وبأنّه ملفّ فعلا. أمّا ! فهي علامة نفي. بجمعهما، فـf-! تتحقّق من أنّ الاسم الذي طلبه الاستعلام غير مُتواجد أو أنّه ليس ملفّا. d-! يعمل بطريقة مُشابهة ولكن بالنسبة للمجلّدات، إذ يُساوي القيمة true فقط إن كان الاسم المطلوب غير موجود أو أنّه ليس مجلّدا. ستُنفَّذ قاعدة RewriteRule الموجودة في السطر الأخير فقط إن تلقى الخادوم طلبا لملفّ أو مُجلّد غير موجود. القاعدة بسيطة وكلّ ما تفعله هو إعادة توجيه الطّلب إلى موجّه الجذر / في الموقع (والذي يكون عادة صفحة رئيسيّة). خاتمة mod_rewrite وحدة مُفيدة جدّا في Apache يُمكن استخدامها لتوفير عناوين URL سهلة القراءة. في هذا الدّرس، تعلّمتَ كيفيّة استخدام تعليمة RewriteRule لإعادة توجيه المُستخدمين حتى ولو كانت تتضمّن نصوص استعلام. تعلّمت كذلك كيفيّة إعادة التّوجيه حسب شروط باستعمال التّعليمة RewriteCond. للتّعرف أكثر على mod_rewrite، ألق نظرة على هذه الصّفحة والتّوثيق الرّسمي لـmod_rewrite من Apache. ترجمة – بتصرّف - للمقال How To Rewrite URLs with mod_rewrite for Apache on Ubuntu 16.04 لكاتبه Mateusz Papiernik.
  2. مُقدّمة سنتعرّف في هذا الدّرس على كيفيّة إعادة كتابة عناوين URL باستخدام وحدة mod_rewrite الخاصّة بـApache 2. تمنحنا هذه الوحدة حريّة إعادة كتابة روابط URL لتكون أكثر نظافة وتنسيقا عبر ترجمة مسارات قابلة للقراءة إلى استعلامات مُوجّهة لتطبيق الوِب أو إعادة توجيه المُستخدم حسب شروط إضافيّة. هذا الدّرس مُقسّم إلى جزأين. بحيث نجهّز في الجزء الأول موقعا إلكترونيا بسيطا مع مثال بسيط لإعادة كتابة عنوان URL. يُغطّي الجزء الثّاني مثالين مُعمّقين لأكثر قواعد إعادة الكتابة شيوعا. المُتطلّبات لاتّباع هذا الدّرس، ستحتاج إلى: خادوم أوبونتو 16.04 مضبوط باتّباع الخطوات الواردة في درس الإعداد الابتدائي لخادوم أوبونتو، وذلك يشمل مُستخدما ذا صلاحيّات sudo مع ضبط مُسبق لتمكينه من تنفيذ مهام إداريّة، غير المستخدم الجذر root، بالإضافة إلى جدار ناري. Apache 2 مُنصّب على خادومك باتّباع الخطوة الأولى من درس تثبيت حزم LAMP على أوبونتو. الخطوة 1 – تفعيل mod_rewrite أولا، نحتاج إلى تفعيل mod_rewrite. مبدئيًّا، الوحدة متوفّرة لكنّها غير مُفعّلة عند تنصيب Apache 2. sudo a2enmod rewrite سيقوم هذا الأمر بتفعيل الوحدة أو إخبارك بأنّ الوحدة قد سبق تفعيلها. لتطبيق التّغييرات، أعد تشغيل Apache: sudo systemctl restart apache2 وحدة mod_rewrite مُفعّلة الآن. سنضبُط في الخطوة التّاليّة ملفّ .htaccess لاستخدامه لتحديد قواعد إعادة الكتابة لإعادات التّوجيه Redirects. الخطوة 2 – ضبط htaccess. يسمح لنا ملفّ .htaccessبتعديل قواعد إعادة الكتابة دون الحاجة إلى الوصول إلى ملفّات إعدادات الخادوم. لهذا السّبب، فملفّ .htaccess مُهمّ جدّا لحماية تطبيق الوِب الخاصّ بك. النّقطة في أول الاسم تُشير إلى أنّ الملفّ مخفي. مُلاحظة: يُمكن لأي قواعد تضعها داخل ملفّ .htaccess أن توضع كذلك داخل ملفّات إعدادات الخادوم، في الحقيقة، ينصح التوثيق الرّسمي لـApache ينصح باستعمال ملفات إعدادات الخادوم عوضا عن ملفّ .htaccess لقدرة Apache على مُعالجتها بسرعة أعلى. مع ذلك، في مثالنا البسيط، الفرق في الأداء لن يكون ملحوظا. بالإضافة إلى أنّ وضع القواعد داخل ملفّ .htaccess مُريح أكثر، خاصّة إن كان لديك الكثير من المواقع الإلكترونيّة في خادوم واحد. إذ لا تتطلّب التّغييرات إعادة تشغيل الخادوم ولا تحتاج إلى صلاحيّات المُستخدم الجذر Root لتعديل الملفّ، ما يُسهّل إجراء التّغييرات بحساب مُستخدم عاديّ. بعض البرمجيّات مفتوحة المصدر مثل جوملا ، ووردبريس ولارافل تعتمد على ملفّ .htaccess لإجراء التّعديلات وإضافة قواعد إضافيّة حسب الطّلب. سنحتاج إلى ضبط وتأمين بعض الإعدادات قبل أن نبدأ. يمنع Apache مبدئيًّا استخدام ملفّ .htaccess لقواعد إعادة كتابة روابط URL، لذا سيتوجّب عليك أولا تفعيل إمكانيّة استخدام الملفّ. افتح ملفّ إعدادات Apache المبدئية باستخدام nano أو مُحرّرك المفضّل. sudo nano /etc/apache2/sites-available/000-default.conf ستجد داخل هذا الملفّ الجزء <VirtualHost *:80> في أول سطر. داخل هذا الجزء، أضف الجزء التّالي مباشرة بعد السطر الذي يبدأ بـDocumentRoot: <Directory /var/www/html> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted </Directory> ليُصبح ملفّ الإعدادات كما يلي (حذفنا - للاختصار - التعليقات، وهي الأسطر التي تبدأ بـ# من المُقتَطع أدناه). تأكّد من أنّ الإزاحة صحيحة: <VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/html <Directory /var/www/html> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> احفظ وأغلق الملفّ. ملحوظة: يفترض هذا الدليل وجودَ موقع واحد على خادومك، في هذه الحالة يكفي التعديل على ملف المضيف الافتراضي Virtual host المبدئي (000-default.conf) بالطريقة أعلاه لتفعيل إمكانيّة إعادة التوجيه. إن كان لديك أكثر من موقع فستحتاج لإجراء التعديل أعلاه على ملفّ المضيف الافتراضي الخاصّ بالموقع الذي تريد. توجد ملفات المضيفات الافتراضية على المسار /etc/apache2/sites-available/. لتطبيق التّغييرات، أعد تشغيل خادوم Apache: sudo systemctl restart apache2 الآن، أنشئ ملفّ .htaccess داخل مجلّد الوب الجذر: sudo nano /var/www/html/.htaccess أضف السّطر التّالي إلى أعلى الملفّ لتفعيل مُحرّك إعادة الكتابة Rewrite engine: RewriteEngine on احفظ وأغلق الملفّ. يُمكنك الآن استعمال الملفّ .htaccess للتّحكم بقواعد المُوجّهات في تطبيق الوِب الخاصّ بك. الخطوة 3 – ضبط إعادات كتابة روابط URL سنعدّ في هذه الفقرة إعادة كتابة بسيطة لرابط URL، بحيث نستطيع تحويل عناوين URL جميلة إلى مسارات يُمكن للشفرة فهمها. سنسمح بالخصوص للمُستخدمين بالوصول إلى العنوان http://your_server_ip/about. لنبدأ بإنشاء ملفّ باسم about.php داخل مُجلّد الوب: sudo nano /var/www/html/about.php انسخ شفرة HTML التّاليّة إلى الملفّ واحفظه ثمّ أغلقه: <html> <head> <title>About Us</title> </head> <body> <h1>About Us</h1> </body> </html> ملحوظة: تأكّد من أن خادوم الوِب لديه صلاحيات الوصول إلى الملف الذي أنشأته للتو. مثلا، بإعطاء الأذون 755على مجلد الوِب: sudo chmod -R 755 /var/www يُمكنك الوصول إلى هذه الصّفحة على العنوان http://your_server_ip/about.html، لكن لو حاولت الوصول إلى العنوان http://your_server_ip/about، فستُلاحظ خطأ 404 Not Found، إن أردت تمكين مُستخدميك من استعمال هذا العنوان عوضا عن العنوان السّابق (أي دون الجزء .html) فقواعد إعادة الكتابة كفيلة بتوفير هذه الوظيفة. تتّبع جميع قواعد الكتابة التّنسيق التّالي: RewriteRule pattern substitution [flags] بحيثُ: RewriteRule يُحدّد التّعليمة. pattern تعبير نمطي Regular Expression يُحدّد عنوان URL المرغوب به، هذا هو ما سيكتبه المُستخدم في شريط عنوان URL. substitution: البدل، وهو مسار عنوان URL الأصلي، (مسار الملفّ الذي يقوم Apache بتقديمه). flags عبارة عن مُعاملات اختياريّة لتعديل آليّة عمل القاعدة. افتح ملفّ .htaccess: sudo nano /var/www/html/.htaccess بعد السّطر الأول، أضف السّطر الثّاني ممّا يلي: RewriteEngine on RewriteRule ^about$ about.html [NC] في هذه الحالة، المقطع ^about$ هو التّعبير النّمطي، about.html يُعبّر عن البدل، و [NC] هي المُعاملات. استخدمنا في هذا المثال عدّة محارف تحمل معان خاصّة: ^ يُشير إلى بداية العنوان بعد المقطع your_server_ip/. $ يُشير إلى نهاية عنوان URL. about المقطع الذي يجب على التّعبير النّمطي مُطابقته. about.html اسم الملفّ الأصلي الذي يصل إليه المُستخدم [NC] خيار لجعل القاعدة تتجاهل حالة الأحرف Case insensitive. ينبغي الآن أن تستطيع الوصول إلى العنوان http://your_server_ip/about في مُتصّفح الويب الخاصّ بك. في الحقيقة، بالقاعدة التي كتبناها أعلاه، فالعناوين التّاليّة ستؤدّي جميعها إلى الملفّ about.html: http://your_server_ip/about، بسبب تعريفنا للقاعدة. http://your_server_ip/About، لأنّ القاعدة تتجاهل حالة الأحرف. http://your_server_ip/about.html، لأنّ اسم الملفّ الأصلي سيعمل دائما. العناوين التّاليّة لن تعمل: http://your_server_ip/about/، لأنّ القاعدة تنصّ بوضوح بأنّه لا يجوز على أي شيء أن يكون بعد about باستخدام المحرف $. http://your_server_ip/contact، لأنّ العنوان لن يُطابق المقطع about. تمتلك الآن ملفّ .htaccess مع قاعدة بسيطة، يُمكنك الآن تعديله وتوسيعه حسب حاجاتك. سنتعرّف في الجزء الثاني من هذا الدرس على أمثلة إضافية لإعادة كتابة الروابط والتعليمات الأكثر استخداما مع mod_rewrite. ترجمة – بتصرّف - للمقال How To Rewrite URLs with mod_rewrite for Apache on Ubuntu 16.04 لكاتبه Mateusz Papiernik.
  3. يسمح تحويل الطلبات بإرسالها من عنوان URL إلى آخر تلقائيًا، وهي طريقة عملية لإرسال الزوار وعناكب محركات البحث إلى عنوان URL مختلف عن العنوان الأصليّ المطلوب، ويمكّن من الحفاظ على تقييم محركات البحث لعنوان معيّن، كما يساعد في الحفاظ على أيّة زيارات محتملة لمحتوى قديم من خلال تحويلها إلى المحتوى الجديد بعد أن تمّ تحديثه. سنستعرض كيفية إنشاء تحويلات 301 (أو ما يُعرف أيضًا بـ 301 Redirect)مع بعض الطرق التي يُمكن استخدامها للحفاظ على محتوى حديث للموقع من أجل تقييم SEO أعلى، ومثالًا عن استخدامنا تحويل 301 على مدوّنتنا لرفع معدّل الزيارات. ما هي أنماط التحويل المتوفرة؟ يوجد أنماط مختلفة للتحويل تحمل الرموز (301، 302، 307) بالإضافة إلى تحديث الصفحة باستخدام وسم meta. 1. التحويل 301 (301 Redirect) تحويل دائم للطلبات من عنوان لآخر، يسمح بتمرير 90-99% من عصير الروابط (قوّة التقييم) القادمة من محركات البحث لعنوان ما إلى العنوان الجديد، حيث يشير الرقم 301 إلى رمز حالة HTTP، التي تخبر محركات البحث بأنّ الصفحة قد نُقلت. إنّ هذا التحويل هو الأفضل لتحويل الطلبات من رابط لآخر في معظم الحالات. 2. التحويل 302 تحويل مؤقّت لطلبات عنوان ما لعنوان آخر، يقوم بتمرير 0% من عصير الروابط (قوّة التقييم) محرك البحث إلى العنوان الجديد، ويفضّل تجنّب استخدامه في معظم الحالات. 3. التحويل 307 الإصدار البديل عن تحويل 302 المتوفّر في الإصدار 1.1 لبروتوكول HTTP. 4. وسم meta نوع من أنواع التحويل الذي يمكن تنفيذه في المتصفّح لدى العميل مباشرة عوضًا عن تنفيذه على مستوى الخادوم. إنّ من الأفضل بشكل عام استخدام التحويل من النمط 301 عند القيام بتحويل طلبات عنوان لآخر بهدف المحافظة على تقييم محرّكات البحث. لماذا قد نحتاج للتحويل 301 (301 Redirect)؟ يستحسن استخدام التحويل 301 بهدف المحافظة على الزوّار وعلى تقييم محركات البحث لعنوان ما، فإعادة جواب من الخادوم يحمل رمز التحويل 301 هو إشارة واضحة للمتصفّح ومحرّكات البحث بأنّ الصفحة قد انتقلت من هذا العنوان بشكل نهائي. ستقوم محركات البحث بتفسير ذلك بأنّ الصفحة لم تنتقل إلى عنوان جديد فحسب، ولكنّ المحتوى -أو نسخة أحدث منه- يمكن إيجاده على العنوان الجديد، عندها يتم نقل قوّة التقييم من العنوان الأصليّ إلى العنوان الجديد. إنّ استخدام التحويل 301 بالشكل الصحيح له القدرة على إعادة تنظيم أيّ هيكلة سيّئة للموقع، بالإضافة إلى حلّ مشكلة المحتوى القديم ورفع جودة تجربة الزائر، كلّ ذلك مع المحافظة على قوّة التقييم. اكتشفنا في أحد الأشهر الماضية بأنّ إحدى المنشورات القديمة التي تعود لعام 2011 وأخرى لعام 2012، كانت تحصل على معدّل زيارات مرتفع، لذا قرّرنا استخدام هذه التقنيّة على سبيل التجربة، لذا أنشأنا مقالًا جديدًا بتاريخ 2 ديسمبر 2013، وقمنا بتحويل الطلبات من المقالات القديمة إلى المنشور الجديد وخلال ذلك الشهر حتى 31 ديسمبر، حصل المنشور الجديد على أكثر من 13,000 زيارة من محرّكات البحث فقط، تتضمن الزيارات تلك التي تمّ تحويلها من المقالات القديمة إليه. لم يكن الوقت ليكون أفضل من ذلك، فلم يكن محتوى المقال مناسبًا لفترة نهاية العام فحسب بل كان المقال من أفضل المقالات في ذلك الشهر بحسب عدد الزيارات، فقد تمكّنا من تحويل معظم الزيارات من المقالات القديمة إلى المحتوى الجديد مُعْلمين بذلك كلًّا من الزوّار ومحرّكات البحث بأنّ لدينا مقالات ذات محتوى جديد ومناسب. إنشاء التحويل باستخدام الإضافات إضافة Redirection تسمح إضافة Redirection بإدارة التحويل من النمط 301 ومتابعة أي أخطاء 404 تظهر عند طلب محتوى غير موجود، وتعمل الإضافة عبر ووردبريس فقط دون الحاجة للوصول إلى ملف htaccess. أو أيّ من إعدادات خادوم أباتشي. تتمتع الإضافة بميّزة عظيمة هي إحصائيات التحويل التي تسمح لك بمشاهدة عدد المرّات التي تمّ فيها تنفيذ تحويل لعنوان مطلوب، وآخر مرّة تمّ فيها ذلك، ومن كان صاحب الطلب (زائر أم محرّك بحث) وأين كان يوجد العنوان الذي تمّ طلبه قبل التحويل. إضافة SEO Redirection تسمح إضافة SEO Redirection بإعداد تحويل سريع للطلبات باستخدام الأنماط 301, 302 و307، كما يمكنك مراقبة أخطاء 404 التي تشير إلى محتوى غير متوفّر وتسمح بتحويل الطلبات تلك إلى عناوين أخرى، وتتميّز الإضافة بأنّه من السهل جدًّا إنشاء التحويل حيث يكفي إدخال العنوان القديم والجديد الذي ترغب بتحويل الزيارات إليه وأخيرًا نوع التحويل (301, 302, 307) الذي ترغب باستخدامه. إضافة Quick Page/Post Redirection تسمح إضافة Quick Page/Post Redirect بإرسال الزيارات من عنوان لآخر على ذات النطاق أو على موقع آخر، وتتمتع بالكثير من الخيارات المتاحة التي تسمح بإنشاء التحويل ونمطه، استيراد وتصدير لوائح التحويل، خيارات التجاوز override أو حذف كلّ عمليات التحويل التي تمّ إضافتها. إنشاء التحويل باستخدام htaccess. وتبقى هذه الطريقة من أبسط الطرق لإنشاء تحويل 301 من خلال إنشاء ملف htaccess. في الجذر الرئيسي للموقع -إن لم يكن الملف موجودًا مسبقًا- حيث أنّ هذه الطريقة سهلة وسريعة ومناسبة لمحرّكات البحث، لكن تذكّر بأنّ هذه الطريقة تعمل فقط مع خوادم أباتشي Apache. لتحويل زيارات صفحة واحدة: Redirect 301 /oldpage.html http://www.yoursite.com/newpage.html Redirect 301 /oldpage2.html http://www.yoursite.com/folder/ أمّا لتحويل جميع زيارات الموقع: Redirect 301 / http://newsite.com/ وتعدّ هذه الطريقة مناسبة جدًا في حال قمت بحجز نطاق جديد وترغب بتحويل زيارات الموقع القديم إلى الجديد شريطة أن تحافظ على مسارات الروابط النسبيّة كما هي، حيث يؤدي طلب الرابط من الشكل www.oldsite.com/helloworld إلى تحويل الزائر إلى www.newsite.com/helloworld . الخلاصة يفيد تحويل الزيارات من النمط 301 إن كنت تملك مجموعة من المنشورات القديمة والتي ترغب بأن تقوم بتحويل زياراتها إلى محتوى جديد للمحافظة على قوّة التقييم الخاص بها; كما يمكن استخدامه مع محرّكات البحث لإبلاغها بأنك تحافظ على محتوى جديد لموقعك. توفّر الإضافات المتاحة طرقًا سهلة لإنشاء التحويلات لموقعك، ولكن إن رغبت باستخدام الطريقة التقليدية فيمكنك اعتماد التحويل باستخدام ملف htaccess. ترجمة -وبتصرّف- للمقال Creating 301 Redirects With WordPress and How it Boosted Our Traffic لصاحبته Raelene Morey.
  4. أصبح من المعروف أهمية العناوين (URLs) في تهيئة المواقع لمُحركات البحث SEO، ولكن ماذا عن تأثيرها على تحليل المواقع analytics؟ وهل يجب الاهتمام بها؟ ولماذا؟ هذا ما سيجيب عنه المقال. كنت أراجع أحد الملخصات التحليلية والتي قد كنت قمت بها منذ فترة، ما لفت نظري أن حصولي على نتائج وتقارير مُجدية كان من قبيل الصُدفة ولم أعد له بشكل جيّد، بعبارة أخرى، إن كانت بنية روابط الصّفحات URL قد نُفّذت بطريقة منطقيّة لكان الحصول على هذه النتائج أسهل بكثير. مثال حول أهمية بنية الروابط مع تحليل المواقع Analytics سأقوم بتوضيح الفكرة بمثال، لنفرض أنه لدينا موقع لشركة استشارية (أو شركة خدمات) والتي تعتمد بشكل أساسي على خبرة كل فرد من الأفراد في مجاله، ومن أهداف الموقع الرّئيسية هي تسهيل مهمة الزّائر في معرفة الأشخاص المُناسبين ضمن الفريق ممن يستطيع تقديم المُساعدة أو الخدمة التي يبحث عنها. بعض الأشخاص في الشركة شهيرون جدًا في مجالات تخصّصاتهم، لذلك سيصل بعض المستخدمين إلى الموقع عن طريق البحث عن أسمائهم على مُحرّكات البحث، أما باقي أفراد الشّركة فيصل الزّوار إلى صفحاتهم عبر تصفّح مُختلف صفحات الموقع. يأتي الزّوّار إلى الموقع لأسباب عديدة، وليس فقط بغرض البحث عن بيانات حول أعضاء الفريق، ومن أجل ذلك كان المطلوب إنشاء شريحة تحليلية باستخدام Google Analytics، والتي ستُحدّد المستخدمين الذين يبحثون عن أفراد الفريق (الأشخاص)، حيث كان المطلوب استقصاء صفات وميزات هؤلاء الزوّار لتحسين تجربتهم في استخدام الموقع. إن الشريحة segment ما هي إلّا مجموعة جزئية subset من البيانات، والتي توافق معايير معيّنة، وعليه كيف لنا أن نُحدّد هذه المجموعة الجزئية في Google Analytics؟ كيفية إعداد شريحة في Google Analytics الخطوة الأولى: تحديد الصفحات تحديد جميع الصفحات التي تمثل أية زيارة لها إشارة على أن الزائر يَقع ضمن الشريحة التي أتت إلى الموقع بحثًا عن أحد أعضاء الفريق (والتي ستعرّف لاحقًا) وهذه الصفحات هي التالية: صفحة الفريق الرئيسية People، والتي تتضمّن صندوق بحث، وروابط لصفحات تعرض الأشخاص بحسب الترتيب الأبجدي، وجميع هذه الروابط تشترك في الجزء المُتمثل في example.com/people/ (أي أن جميع هذه الرّوابط تحتوي هذا الجزء ضمنها). تملك صفحات التدريب المتخصّصة بالشركة صفحة فرعية تعرض الأشخاص المتخصصين في هذا المجال، جميع هذه الصفحات تحت المسار /services/، وتحتوي سجلّات الأشخاص هذه على detail=people& في آخر العنوان URL، وبالتالي هذا يُسهّل من عملية إضافتها إلى الشريحة، ولو كان العنوان على الشكل /services/servicename/ كان سيكون الأمر أفضل مع محركات البحث SEO وأوضح في القراءة للمستخدم. صفحات الملف الشخصي profile لكل شخص، وهنا نواجه مُشكلًا، حيث أن هذه المسارات/العناوين URLs تكون على الشكل example.com/name_of_the_user/ وهي صفحات هامّة تُحيل إليها محركات البحث، لذلك لا يمكن تجاهلها في تعريف الشريحة، ولكن يوجد عدد كبير من الأشخاص ليتم إضافتهم بشكل يدوي وصريح، إذًا نحتاج شيئًا يميّز هذه الصفحات عن غيرها، وهذا ما كان، حيث أن عناوين titles هذه الصفحات هي من الشكل "User Name | People |"، وعليه يمكن استخدام هذه العناوين في تعريف الشريحة. الخطوة الثانية: استخدام Google Analytics لإنشاء الشريحة سيتمّ اختيار "إضافة شريحة" من صفحة "إعداد التقارير"، ومنها اختيار "شريحة جديدة"، واختيار اسم مُناسب لها في "اسم الشريحة"، وليكن "الباحثون عن أشخاص" (People seeker). سيتمّ بعد ذلك إضافة المعايير التي من شأنها تحديد الزيارة في الشريحة، فعندما يزور المستخدم واحدة من صفحات التي تحتوي في مسارها URL على /people/ أو detail=people& أو الصفحات التي تحتوي في عنوانها على "| People |" ستكون هذه الصفحة مطابقة لتعريف الشريحة، ولذلك تمّ استخدام أو لجمع المعايير الثلاث، أي أحد هذه الشروط الثلاث سيُجّل من ضمن الشريحة. يُلاحظ كيف تمّ استخدام "عنوان الصفحة" (المعيار الثالث) لاختيار صفحات الملفّ الشخصي لكل شخص. تصميم أفضل يؤدي إلى تحليل أفضل تمّ استكمال المثال السابق عبر استخدام "عنوان الصفحة" كمعيار في تعريف الشريحة، وهذا الأسلوب قد لا ينجح دائمًا، فمن المحتمل جدًا ورود "people" في عناوين باقي الصفحات فمن الضروري وجود اختلاف ولو بسيط مثل "|" لتمييز هذه الصفحات عن بعضها، وإلا فلا يوجد طريقة لتمييز هذه الصفحات. يُهمل المطّورون الوسم title غالبًا، لذا قد يكون من غير الحكمة الاعتماد عليها كاستراتيجيّة في التحليل في المواقع المتوسطة والكبيرة، الأمر الذي يؤدي إلى نتائج غير دقيقة في التحليل. يُنصح من أجل ذلك بالتخطيط المسبق وفي مرحلة التطوير فعلى سبيل المثال، حال مثالنا السابق سيكون أفضل بكثير لو كان المسار URL على الشكل التّالي/people/name_of_the_user/، لكان من الممكن عندها ببساطة المطابقة باستخدام تعبير نمطي regular expression مثل /people/[a-zA-Z0-9]+/. خاتمة كما أسلفت سابقًا، إن بُنية المسار URL ليست من أجل محركات البحث فقط، فالاهتمام به والتخطيط له مسبقًا في مرحلة التطوير أمر حتمي ولا يُمكن تجاهله، وذلك من أجل الحصول على تحليل أفضل ونتائج دقيقة تُمثّل الواقع بالفعل. ترجمة -وبتصرّف- للمقال URL structures and analytics لصاحبه Chris Scott.
  5. أنشأنا في الدرس السابق موقع الويب الأوّل لنا، سنتعلّم الآن كيف سننشر موقع الويب هذا بشكل فعليّ على الانترنت. ملاحظة: لن يكون هناك الكثير من الزوار لموقعك في البداية، مالم تعط الناس عنوان الموقع على الانترنت. الاستضافة لكي يستطيع الجميع الوصول إلى موقعنا على الانترنت، نحتاج إلى مُخدّم Server يُخزّن موقعنا عليه، بالإضافة إلى عنوان URL يُشير إلى الموقع. هناك عدد هائل من الشركات التي يمكن أن تقدّم لك خدمة تأجير مساحة على المُخدّم لهذا الغرض. تُسمّى هذه الخدمة عادةً باستضافة ويب Webhosting. نستعرض بعض الاستضافات المجّانية المُتاحة. أنصح أن تبدأ بخدمة BitBalloon إذا كانت هذه هي التجربة الأولى لك. 1- الاستضافة على BitBallon خدمة BitBallon بسيطة ورائعة وأنصح بها. إليك الخطوات اللازمة للتسجيل: 1. اشترك ضمن موقع BitBalloon. وذلك بالنقر على زر التسجيل Sign Up ثم اختر Sign in Using Persona. بعد ذلك أدخل بريدك الإلكتروني وكلمة المرور. 2. عندما تسجّل الدخول، يمكنك ببساطة سحب كامل مجلّد موقع الويب (المجلّد Portfolio) إلى المكان المخصّص في صفحة الخدمة. 3. ربما تستغرب هذه البساطة، ولكن بمجرّد تحميل الموقع سيُولّد عنوان URL يُشير إلى موقعك الذي حمّلته قبل قليل. انقر هذا العنوان واختبر ظهور الموقع بشكل صحيح. 4. لتبسيط عنوان URL المولّد بشكل آلي، يمكننا النقر على Edit name وإدخال اسم مناسب. 5. من أجل التحديثات التي من الممكن أن تجريها على الموقع، اسحب مجلّد الموقع من جديد إلى الصندوق المسمّى Drag & Drop to Update your Site. 2- الاستضافة على Google Drive يمكن استخدام خدمة Google Drive كخدمة استضافة. الأمر السلبي الوحيد هنا، هو أنّك ستحصل على عنوان URL طويل جدًّا. لنجري الخطوات التالية للاستضافة: حمّل مجلّد الموقع إلى Google Drive. حدّد المجلّد المُحمّل ثم اختر مشاركة Share. انقر فوق خيارات متقدّمة Advanced وغيّر مستوى الوصول إلى Public on the web أي متاح للعموم على الانترنت. افتح المجلّد في Google Drive وتأكّد من أنّ جميع ملفّات الموقع قد حمّلت (index.html والصور …الخ). انسخ الرموز التي تأتي بعد الكلمة ( /folders#) ضمن شريط العنوان للمتصفّح. ستكون هذه الرموز هي المُعرّف الخاص بالمجلّد المُحمّل. أدخل في شريط العنوان للمتصفّح العنوان التالي http://googledrive.com/host متبوعًا بالرموز التي نسختها من الخطوة السابقة. يمكن الآن لأي شخص لديه هذا العنوان الوصول إلى موقعنا. 3- الاستضافة على Dropbox يمكن استخدام Dropbox كخدمة استضافة. ولكي نتمكّن من ذلك نحتاج إلى خدمة إضافية لتوجيه الطلبات إلى الموقع المُستضاف. توجد خدمتان يمكن استخدامهما وهما Pancake و DropPages. 4- الاستضافة على GitHub إذا كان لديك بعض الخبرة البرمجية فعندها يُعتبر GitHub طريقةً رائعة لاستضافة مواقع الويب. تُعتبر GitHub منصّة لتسهيل التشاركية بين المبرمجين، كما تُتيح هذه المنصة استضافة مجّانيّة لصفحات الويب وذلك على صفحات GitHub. تؤمّن صفحات GitHub المزيد من الخيارات (فمثلاً تستطيع استخدام النطاق domain الخاص بك)، لكنها تتطلّب بعض المهارات في التعامل مع نظام التحكم بالإصدارات البرمجية Git. تصغير عناوين URL يمكن أن يكون عنوان موقعك طويلًا جدًّا وذلك بحسب الاستضافة التي اخترتها. توجد بعض الخدمات البسيطة لتصغير عنوان URL الخاص بموقعك. لتصغير العناوين فائدة كبيرة، حيث يمكن إدخالها يدويًا بسهولة ضمن متصفح الويب في هاتفك الذكي مثلًا، كما توجد بعض الخدمات التي تزوّدك بكود QR للوصول السريع من هاتفك الذكي إلى الموقع مباشرة باستخدام كاميرا الهاتف فحسب. إليك قائمة من بعض خدمات تصغير العناوين: خدمة Goo.gl (تتضمن توليد كود QR). خدمة bit.ly. خدمة Tiny.cc. النطاق الخاص بنا ربما يأتي يوم نرغب فيه بأن نحصل على اسم نطاق خاص بنا مثل http://www.my-super-website.com. يمكنك في بعض الحالات تسجيل اسم نطاق ضمن مزوّد خدمة الاستضافة نفسه (كما هو الحال مع خدمة الاستضافة BitBallon). أو يمكنك الوصول إلى عدد كبير جدًّا من خدمات تسجيل النطاقات الخاصة، تقدّم بعضها عروضًا مختلفةً عن بعضها الآخر، يمكنك البحث في Google لتصل إلى عدد كبير منها. سنُضفي على الموقع في الدرس الثالث بعض تأثيرات التنسيق المختلفة عن طريق CSS. ترجمة -وبتصرف- للمقال HTML & CSS Tutorial - Part 2: Publishing Your Website لصاحبه Marco Jakob.
  6. تلعب روابط URL دورا هامًّا في العثور على مواقع الويب؛ لذا من المهم تحسينها لمحركات البحث Search Engine Optimization. سنرى في هذا الدرس طريقةً لجعل روابط مشروع larashop محسّنة للمحركات. رأينا في الدرس السابق كيف تعمل المسارات والمتحكمات، سنبني على هذه المعرفة التي اكتسبناها من أجل الوصول إلى الهدف المحدّد. هذا الدرس جزء من سلسلة تعلم Laravel والتي تنتهج مبدأ "أفضل وسيلة للتعلم هي الممارسة"، حيث ستكون ممارستنا عبارة عن إنشاء تطبيق ويب للتسوق مع ميزة سلة المشتريات. يتكون فهرس السلسلة من التالي: مدخل إلى Laravel 5.تثبيت Laravel وإعداده على كلّ من Windows وUbuntu.أساسيات بناء تطبيق باستخدام Laravel.إنشاء روابط محسنة لمحركات البحث (SEO) في إطار عمل Laravel. (هذا الدرس)نظام Blade للقوالب.تهجير قواعد البيانات في Laravel.استخدام Eloquent ORM لإدخال البيانات في قاعدة البيانات، تحديثها أو حذفها.إنشاء سلة مشتريات في Laravel.الاستيثاق في Laravel.إنشاء واجهة لبرمجة التطبيقات API في Laravel.إنشاء مدوّنة باستخدام Laravel.استخدام AngularJS واجهةً أمامية Front end لتطبيق Laravel.الدوّال المساعدة المخصّصة في Laravel.استخدام مكتبة Faker في تطبيق Laravel لتوليد بيانات وهمية قصدَ الاختبار. سنغطّي في هذا الدرس موضوعين أساسيّين: العوامل المؤثّرة في التحسين لمحركات البحث.كيفية إنشاء روابط محسّنة لمحركات البحث في Laravel.العوامل المؤثرة في التحسين لمحركات البحثلا نهدف إلى تقديم دليل شامل عن التحسين لمحركات البحث؛ ما نريده هنا هو ذكر بضعة عوامل يجب على المطور أن يكون على اطّلاع عليها. في ما يلي عوامل تؤثر على تقويم محركات البحث مثل Google لصفحات الويب: سرعة الموقع: يحب الجميع أن تظهر صفحة الويب التي يزورها بسرعة، فلا أحد يحب الانتظار إلى ما لا نهاية حتى تظهر الصفحة التي يطلبها. من الأحسن ألا يتعدى زمن تنزيل الصفحة ثانيتين وكل ما قلّ كلّ ما كان الأمر أفضل. يجب عليك بوصفك مطوّرا اختبارُ سرعة تطبيقك وإجراء التحسينات اللازمة إن اقتضت الضرورة.إحصاءات الشبكات الاجتماعية: من الطبيعي، عند قراءتك شيئا مهمّا، مشاركتُه مع متابعيك وأصدقائك على الشبكات الاجتماعية؛ وهذا دليل على الأهمية بالنسبة لمحركات البحث. دورك كمطور هو توفير الأدوات التي تسهل على الزوار مشاركة محتوى الموقع.تصميم تجاوبي Responsive: يمثل مستخدمو الأجهزة المتنقلة جزءًا كبيرًا من مستخدمي خدمات الويب. من هذا المنطلق يجب التأكد من أن موقع الويب يظهر بشكل صحيح على أجهزة الجوّال، الأجهزة اللوحية وأجهزة سطح المكتب؛ إذ أن تجربة المستخدم من العوامل المؤثرة في تقويم محركات البحث.الكلمات المفتاحية Keywords: تصنف محركات البحث مليارات صفحات الويب حسب الكلمات الأساسية الواردة فيها. يتمثل دور المطور في التأكد من توفير آليات مثل الوسوم Tags، أوصاف meta، وعناوين HTML يمكن لكاتب المحتوى استخدامها لتمييز المحتوى المفتاحي.روابط URL الخاصة بالموقع: يجب أن تظهر الكلمات المفتاحية في روابط الموقع.كيفية إنشاء روابط محسنة لمحركات البحث في Laravelعرضنا لأساسيات تحسين محركات البحث مع ذكر دور المطور في تنفيذها. سنبدأ الآن في وضع هذه المبادئ موضع التنفيذ. سننشئ مسارات ونربطها بمت حكم. يُظهر الجدول التالي الروابط التي سيتكون منها متجرنا الإلكتروني. التسلسل الرابط الدالة الوصف1/indexالصفحة الرئيسية2/productsproductsصفحة المنتجات3/products/details/{id}product_details(id)صفحة المنتج ذي المعرّف id4/products/categoryproduct_categoriesعرض تصنيفات المنتجات5/products/brandsproduct_brandsعرض العلامات التجارية للمنتجات6/blogblogعرض فهرس بمنشورات المدونة7/blog/post/{id}blog_post($id)عرض محتوى التدوينة ذات المعرّف id8/contact-uscontact_usعرض صفحة الاتصال9/loginloginصفحة تسجيل الدخول10/logoutlogoutتسجيل خروج المستخدم11/cartcartعرض محتوى سلة المشتريات12/checkoutcheckoutصفحة الدفع13/search/{query}search($query)عرض نتائج البحث في الموقعتعريف مسارات الروابطسنعرّف مسارا لكل من الروابط الموجودة في الجدول أعلاه، لذا نفتح الملف app/Http/routes.php ونعدّل المحتوى بحيث يصبح التالي: <?php /* |-------------------------------------------------------------------------- | Application Routes |-------------------------------------------------------------------------- | | Here is where you can register all of the routes for an application. | It's a breeze. Simply tell Laravel the URIs it should respond to | and give it the controller to call when that URI is requested. | */ Route::get('/','Front@index'); Route::get('/products','Front@products'); Route::get('/products/details/{id}','Front@product_details'); Route::get('/products/category','Front@product_categories'); Route::get('/products/brands','Front@product_brands'); Route::get('/blog','Front@blog'); Route::get('/blog/post/{id}','Front@blog_post'); Route::get('/contact-us','Front@contact_us'); Route::get('/login','Front@login'); Route::get('/logout','Front@logout'); Route::get('/cart','Front@cart'); Route::get('/checkout','Front@checkout'); Route::get('/search/{query}','Front@search');احفظ الملف. يستدعي كلٌّ مسار دالة المتحكم Front الموافقة له، حسب الجدول أعلاه. بقي الآن إنشاء المتحكم وكتابة الدوال. نستخدم أداة Artisan لإنشاء شفرة نمطية لمتحكم Laravel. تأكد من وجودك في مجلد المشروع larashop ثم نفذ الأمر التالي: php artisan make:controller Front يعني ظهور الرسالة التالية أن الأمر نُفذ كما يجب: Controller created successfully.افتح ملف المتحكم Font الذي أنشأناه للتو (app/Http/Controllers/Front.php) وعدّل عليه بحيث يصبح محتواه التالي: <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class Front extends Controller { public function index() { return 'index page'; } public function products() { return 'products page'; } public function product_details($id) { return 'product details page'; } public function product_categories() { return 'product categories page'; } public function product_brands() { return 'product brands page'; } public function blog() { return 'blog page'; } public function blog_post($id) { return 'blog post page'; } public function contact_us() { return 'contact us page'; } public function login() { return 'login page'; } public function logout() { return 'logout page'; } public function cart() { return 'cart page'; } public function checkout() { return 'checkout page'; } public function search($query) { return "$query search page"; } }تعرّف الشفرة أعلاه الدوال التي تجيب على كل طلب يأتي من المسارات التي عرّفناها في ملف routes.php. اكتفينا -لحد الساعة- بجعل كل دالة ترجع اسم المسار الذي تجيب على طلباته. انتقل الآن للمتصفح وأدخل الرابط التالي في شريط العناوين: http://larashop.dev/search/bootsستحصل على صفحة بالمحتوى التالي: boots search pageجرب الروابط الأخرى أيضا: http://larashop.dev/ http://larashop.dev/products http://larashop.dev/products/details/7 http://larashop.dev/products/category http://larashop.dev/products/brands http://larashop.dev/blog http://larashop.dev/blog/post/3 http://larashop.dev/contact-us http://larashop.dev/login http://larashop.dev/logout http://larashop.dev/cart http://larashop.dev/checkout http://larashop.dev/search/Keywordترجمة -وبتصرّف- لمقال Laravel 5 SEO Friendly URLs لصاحبه Rodrick Kazembe.
  7. أساسيات angularjs

    تقتصر بعض تطبيقات Angular على كونها أدوات مساعدة في صفحة ويب تقليدية، إلا أنّ الأغلبية العُظمى لتطبيقاتها هي التطبيقات وحيدة الصفحة (single-page applications)، التي تستبدل تصفح الويب المعتمد على المتصفّح بواجهاتٍ وانتقالاتٍ مشابهة في صفحةٍ واحدة، مقدمة للمستخدم تجربة تفاعليّة رائعة. إلّا أنّ كتابة تطبيقات وحيدة الصفحة بطريقةٍ بسيطة يجعلنا نخسر شيئًا قيّمًا في التطبيقات المعتمدة على المتصفّح وهو الرّابط URL. ففي تطبيقٍ بسيطٍ وحيد الصفحة، سيكون هناك رابط URL واحد فقط، ولن تكون هناك طريقة لمشاركة روابطَ مخصصة لكلّ مورد (resource) على حدة، كتعليق محدّد على تدوينة ما على سبيل المثال. وعلى العكس، فسيقوم تطبيق تقليدي في طرف المخدّم يتبع نمط REST (تبادل الحالة ضمن رابط HTML) بإدارة الواجهات كبنية هرميّة من الروابط المنظّمة سهلة القراءة والتي تظهر حالة التّطبيق الحاليّة بوضوح. تُقدّم هذه الروابط طريقةً للمستخدم ليعود إلى حالةٍ من حالات التطبيق في وقتٍ لاحق، أو ليشارك هذه الحالة مع الآخرين. يُعرَّف التوجيه في تطبيق ويب تقليديّ بأنّه صلة الوصل بين عمليّات HTTP مثل (GET وPOST وما إلى ذلك) وأنماط الروابط وبين المتحكّمات. إن لم تكن معتادًا على التوجيه من طرف المخدّم فسيقدّم لك دليل التوجيه السريع مقدّمةً سهلةً للتوجيه في JavaScript. على أي حال، فالتوجيه من طرف المستخدم يقلب الحالة رأسًا على عقب. فبدلًا من أن يتمّ التفاعل مع الأفعال التي ينقلها لنا المتصفّح، فسنحتاج إلى إبقاء المتصفّح متابعًا للتحديثات بينما يتفاعل التطبيق مباشرةً مع مدخلات المستخدم. كمثالٍ على ذلك، كيف يمكننا الإبقاء على شريط التّنقل محدّثًا بروابط تمثّل الحالة بدقّة، وفي نفس الوقت نستجيب لروابط تُدخل فيه أو تُحمّل من العلامات المرجعية؟ لحُسن الحظ، فقد تمّ إيجاد الوحدة ngRoute لتساعدنا في هذا العمل. لنتمكّن من استخدام هذه الوحدة، سنحتاج إلى تحميل ملف angular-route.js إضافةً إلى ملف مكتبة Angular الرئيسي. كما سنقوم بتحميل بيئة Bootstrap لاستخدام أنماط CSS الخاصة بها. <base href="/"> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js"></script> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-route.js"></script>لاحظ تعريف العنصر base في السطر الأول في المثال السابق. يُعرِّف هذا العنصر رابط URL القاعديّ لتطبيق Angular الحالي، وهذا العنصر يطلبه دعم Angular لـتوابع HTML5 الخاصة بالتاريخ (سنتحدث عنها أدناه). إن كنت تتساءل لمَ تم إسناد الخاصية href إلى مسار الجذر، بدلًا من أن تكون مسندةً إلى مسار الصفحة، فهذا لأنّ أمثلة هذه السلسلة تعمل داخل أُطُر iframe خاصة لكل واحد منها. <body ng-app="app"> <!-- كل الأمثلة توضع هنا --> </body>بعد ذلك، سيكون علينا جلب ngRoute عند تهيئة الوحدة الجذر، وقد قمنا بتغطية هذه الفكرة بعمق في فصل الوحدات. angular.module('app', ['ngRoute']);وهكذا نكون قد أتممنا تحميل الوحدة ngRoute في تطبيقنا. routeProvider$لنتمكن من استخدام ngRoute، سنحتاج إلى ربط مسار URL نسبي واحدٍ أو أكثر مع معالجاتٍ (handlers). يتيح لنا التابع module.config إعداد وحداتٍ مثل ngRoute بعد أن تقوم Angular بتحميلها. كل ما علينا هنا هو معرفة اسم الخدمة (service) أو المزوّد (provider) الذي سيقوم بإعداد الوحدة. في حالة ngRoute يُسمّى المزوِّد بـrouteProvider$. سنتمكن عند وضع هذا الاسم في تابع الاستدعاء الخلفي config من عمل سلسلةٍ من عمليّات ربط المسارات باستخدام التابع when. الوسيط الأول للتابع when هو المسار النسبي الخاص بوجهة التوجيه، أما الوسيط الثاني فهو كائن الإعدادات الذي يحدد الكيفية التي سيتم بها معالجة محتوى وجهة التوجيه. angular.module('app') .config(function($routeProvider) { $routeProvider .when('/', { template: "<a href='#/about'>About</a>" }) .when('/about', { template: "<a href='#/'>Home</a>" }); });يشبه الخيار template الذي يظهر في المثال السابق ذلك الذي استخدمناه في إعداد التوجيهات سابقًا. لا يحوي المثال السابق أي محتوىً متغيّر، فقط نص HTML ثابت. يُقدّم كلّ قالبٍ رابطًا إلى المسار النسبي للآخرين، لذا سنتمكن في المثال السابق من التبديل بين الاثنين. قد تتساءل أين سيتم وضع المحتوى المعالَج، حسنًا، تُقدّم الوحدة ngRoute توجيهًا مُميّزًا، هو ng-view، ويجب أن يكون هذا التوجيه موجودًا في وحدتنا لتعمل. تتكوّن القوالب الرئيسي في هذا الفصل كلّها من عنصرdiv خالٍ يوجد فيه التوجيه ng-view، وكلّ ما سوى ذلك سيقوم المعالج (handler) بمعالجته للمسار الحالي. <div ng-view></div>جرب النقر على الرابط الناتج لتتم معالجة الرابط للمورد الآخر. لم يعمل؟ حسنًا، لقد تجاهلنا أمرًا هامًا، إن نظرت إلى شريط التنقل الخاص بمتصفحك أثناء نقر الرابط فلن تراه قد تغير ليلائم المسار النسبي الصحيح، في الواقع، ليس هناك أي أمرٍ خاطئ في النص البرمجي الخاص بالمثال، وفي التطبيقات الحقيقية ستلاحظ التغيير، فكلّ ما في الأمر أن البيئة التفاعلية التي تمّ استضافة الأمثلة في داخلها ضمن هذه السلسلة لا تسمح لنا برؤية التغيير في الصفحة الرئيسية للفصل. الخدمة location$جميع أمثلة هذه السلسلة موضوعة داخل صناديق sandbox داخل أُطر iframe الخاصة بكل واحد منها. (يُمكنك إلقاء نظرة على الرابط التالي Codecademy/stuff.js إن كان لديك فضول لمعرفة طريقة القيام بذلك.) وهذا ممتازٌ لعزل البيئة البرمجية، إلا أنّه يمنعك من رؤية رابط الـURL الخاص بالأمثلة في شريط الانتقال. ومن حسن الحظ أنّه توجد طريقةٌ للتحايل على هذا الأمر، مع فائدةٍ إضافيّة في استكشاف خدمةٍ مفيدةٍ في Angular تسمح بمعاينة رابط URL الحالي، وهي الخدمة location$. angular.module('app') .controller('LocationController', function($scope, $location) { $scope.location = $location.absUrl(); });يتم في المثال السابق التصريح عن متحكم بسيطٍ يستقبل الخدمة location$ عن طريق حقن التبعية، ويستخدمها للدخول إلى رابط URL المُطلق الحالي للتطبيق، حيث تكون القيمة هي دمجًا للرابط الثابت للجذر الخاص بالصفحة المغلّفة للمثال مع رابط الامتداد الذي تُديره الوحدة ngRoute. المتحكميُمكننا أن نقوم بتحميل المتحكّم LocationController في المثال السابق بالطريقة المعيارية باستخدام التّوجيه ng-controller، إلّا أنّه بإمكاننا أيضًا أن نقوم بإعداد متحكّمٍ كخيار (option)، كما سنضيف خاصّيّة المجال location إلى قالبنا. angular.module('app') .config(function($routeProvider) { $routeProvider .when('/', { controller: 'LocationController', template: '<div class="well well-sm" ng-bind="location"></div>\ <a href="#/about">About</a>' }) .when('/about', { controller: 'LocationController', template: '<div class="well well-sm" ng-bind="location"></div>\ <a href="#/">Home</a>' }); });ها نحن ذا، صار لدينا الآن محاكٍ لشريط الانتقال لأمثلتنا، ولكن للأسف لن تتمكّن من تعديلها لرؤية الكيفية التي ستدير بها الوحدة ngRoute التغييرات بمعالجتها وإظهار محتوىً جديد، وسيكون عليك اختبار ذلك في تطبيقاتك الخاصة. رمز Hashbangتتوقّع وحدة ngRoute في الحالة الافتراضية أن تبدأ مسارات URL النسبيّة برمز hash (#)، ويُمكنك بسهولةٍ تغييره إلى البادئة hashbang متمثّلة بالرمز (!#) بإضافة إعداداتٍ إلى الخدمة locationProvider$ كما يبيّن المثال التالي. لاحظ أنّه يجب علينا أيضًا إضافة رمز ! إلى الروابط في قوالبنا. angular.module('app') .config(function($locationProvider) { $locationProvider.hashPrefix('!'); }) .config(function($routeProvider) { $routeProvider .when('/', { controller: 'LocationController', template: '<div class="well well-sm" ng-bind="location"></div>\ <a href="#!/about">About</a>' }) .when('/about', { controller: 'LocationController', template: '<div class="well well-sm" ng-bind="location"></div>\ <a href="#!/">Home</a>' }); });لا يزال رمز البادئة hashbang مصادقًا عليه من Google في دليل Webmasters الخاص بها، وتحديدًا في المقطع Making AJAX Applications Crawlable، الذي ينص على أنّ "أقسام الـhash يجب أن تبدأ بعلامة تعجّب"، على أيّ حالٍ، طالما أنّك تقوم بالخطوات اللازمة للتّأكّد من ملاءمة موقعك لقواعد SEO فقد تجد أنّه من الأفضل أن يكون تطبيقك مخدومًا بأسلوبٍ خالٍ من البادئة، وهذا الأسلوب مفعّلٌ في HTML5 الآن. الكائن History من HTML5يُقدّم الكائن window.history تحكّمًا بالتّنقّل في المتصفّحات الحديثة، مما يقدّم تجربة مستخدمٍ سلسة. angular.module('app') .config(function($locationProvider) { $locationProvider.html5Mode(true); });يُمكننا كتابة قيم href الخاصة بنا كمسارٍ بسيط، بدون البادئة # ولا البادئة !#. angular.module('app') .config(function($routeProvider) { $routeProvider .when('/', { controller: 'LocationController', template: '<div class="well well-sm" ng-bind="location"></div>\ <a href="/about">About</a>' }) .when('/about', { controller: 'LocationController', template: '<div class="well well-sm" ng-bind="location"></div>\ <a href="/">Home</a>' }); });استخدام الكائن history من HTML5 وسيلةٌ ممتازةٌ إن كنت غير مضطرٍّ لدعم متصفحاتٍ قديمة في تطبيقك. العنصر templateUrlلنقم الآن بتحليل تطبيقنا البسيط إلى مكوناته الأولية. كما قمنا سابقًا مع التوجيهات بجعل شيفراتنا البرمجية أكثر قابلية للإدارة عن طريق استخراج قوالبنا (حتى الصغيرة منها) إلى ملفاتٍ مستقلة، فسيكون علينا للقيام بذلك فقط استبدال العناصر template في إعداداتنا بالعناصر templateUrl. angular.module('app') .config(function($routeProvider) { $routeProvider .when('/', { controller: 'LocationController', templateUrl: '/views/index.html' }) .when('/about', { controller: 'LocationController', templateUrl: '/views/about.html' }); });دون تغييرٍ على صفحة About التي سنضعها في مجلد views. <div class="well well-sm" ng-bind="location"></div> <a href="/">Home</a> <h4>About</h4>سنتكلّم في الفقرات التالية عن فكرة التعامل مع روابط URL غير الصالحة، لذا لنقم بإضافة واحدٍ منها الآن. <div class="well well-sm" ng-bind="location"></div> <a href="/about">About</a> | <a href="/bad-path">Bad path</a> <h4>Home</h4>جرّب النقر على Bad path في المثال السابق، ستنتهي التّسلية للأسف، وستضطر لإعادة إنعاش الصفحة لاستعادتها. التابع otherwiseما الذي يمكننا فعله لتجنب النهايات الحزينة كما حدث قبل قليل؟ قد يكون أحد الإجابات هو تجنب تقديم روابط غير صالحة، ولكن في التطبيقات الحقيقيّة لا يمكننا إيقاف المستخدم عن الكتابة في شريط التنقل. يُمكننا أن نُعِدّ المُخدّم ليقوم بإعادة توجيهٍ للروابط غير الصالحة إلى رابط الجذر لتطبيق Angular، ولكن هذا يعني إعادة تحميل الصفحة من جديد، مما يعني إعادة تشغيل التطبيق من البداية. كيف يُمكننا بناء تطبيقٍ من طرف المستخدم ليقوم بإعادة توجيهٍ للروابط غير الصالحة؟ لو افترضنا بأننا نريد أن نُعلم المستخدم بأن الرابط غير صالح قبل أن نقوم بإعادة التوجيه، فالأمر الأول الذي نحتاجه هو الواجهة التي ستظهر لأي رابط غير صالح. سنسُمّي هذا القالب 404 ليتناسب مع معناه، وطبعًا يمكنك تسميته بأي اسمٍ آخر. <div class="well well-sm" ng-bind="location"></div> <a href="/">Home</a> <h4 class="text-danger">404 - Not Found</h4>كلّ ما نحتاجه الآن هو عبارة when أخرى لإضافة المسار 404/. ثم لربط أي رابط غير متوافق مع الروابط الموجودة بالمسار 404/، وسنقوم بذلك بإضافة استدعاءٍ للتابع otherwise الذي يقوم بإضافة المسار إلى العنصر redirectTo فيه. في المثال التالي، سيتم تشغيل الاستدعاء للتابع config إضافةً إلى كل الإعدادات السابقة. (يُمكنك تسجيل عددٍ غير محدودٍ من الاستدعاءات الخلفية (callbacks) للتابع config في المزوِّد (provider)) angular.module('app') .config(function($routeProvider) { $routeProvider .when('/404', { controller: 'LocationController', templateUrl: '/views/404.html' }) .otherwise({ redirectTo: '/404' }); });جّرب النقر الآن على Bad path. صحيحٌ أنّ بيئة الأمثلة لا تسمح لك بإدخال مسارٍ عشوائيّ في شريط التصفح، إلّا أنّه يمكنك تعديل "href="/bad-path في القالب السابق إلى أيّ قيمة تريدها لترى كيف سيتم التعامل معها. ربما يجب عليك دومًا إضافة معالجٍ (handler) ليتعامل مع كل الاحتمالات الباقية في إعدادات التوجيه الخاصة بك. الأحداث (Events)تُقدّم Angular تطبيقًا للرسائل من نمط (publish-subscribe) لأحداث التطبيق، وهي تعتمد على ثلاث توابع: emit$ وbroadcast$ وon$، حيث يقوم التابع emit$ و broadcast$ بتفعيل نشر أحداثٍ مخصصة، أما التابع on$ فيقوم بتسجيل معالجات (handlers) للأحداث التي تقوم بنشرها الوحدة ngRoute. فمثلًا، عندما يتمّ تغيير المسار بنجاح سينتج عن ذلك نشر الأحداث التالية: routeChangeStart$locationChangeStart$locationChangeSuccess$routeChangeSuccess$هذه الأحداث مرتبةٌ في القائمة بنفس ترتيب ظهورها أثناء دورة حياة عملية تغيير المسار، لنقُم بإثبات ذلك. تسجيل معالج للحدث (event handler)لنستخدم التابع on$ لتسجيل معالجٍ بسيط لأحداث المسار، حيث سيقوم هذا المعالج بجمع أسماء الأحداث في مصفوفة، ثم سنقوم لاحقًا بطباعة أسماء الأحداث في الصفحة بنفس الترتيب الذي حُفظت به. angular.module('app') .value('eventsLog', []) .factory('logEvent', function(eventsLog) { return function(event) { eventsLog.push(event.name); }; });في هذا المثال، سنقوم بتسجيل الأحداث أثناء انتقالنا من مسار الجذر (والمسؤول عنه هو المتحكم HomeController) إلى المسار events/ (والمسؤول عنه المتحكم EventsController). سنقوم أيضًا بجعل المتحكّم يضيف اسمه إلى القائمة أيضًا لنعرف وقت استدعاء هذا المتحكم. angular.module('app') .controller('HomeController', function($scope, $location, $rootScope, eventsLog, logEvent) { $scope.location = $location.absUrl(); $scope.link = {path: '/events', title: 'Events'}; eventsLog.push("HomeController: " + $location.path()); $rootScope.$on('$routeChangeStart', logEvent); $rootScope.$on('$locationChangeStart', logEvent); $rootScope.$on('$locationChangeSuccess', logEvent); $rootScope.$on('$routeChangeSuccess', logEvent); $scope.eventsLog = eventsLog; });يقوم المتحكم EventsController بإضافة اسمه إلى المصفوفة eventsLog ثم يقوم بكشف (expose) السجل للمجال بحيث يمكننا رؤيته في الصفحة. angular.module('app') .controller('EventsController', function($scope, eventsLog, $location) { $scope.location = $location.absUrl(); $scope.link = {path: '/', title: 'Home'}; eventsLog.push("EventsController: " + $location.path()); $scope.eventsLog = eventsLog; });نفس الواجهة ستعمل في كلا المتحكّمين. وسيتم عرض شريط انتقالٍ متغيّر إضافةً إلى محتويات السجل باستخدام التوجيه ng-repeat. <div class="well well-sm" ng-bind="location"></div> <a ng-href="{{link.path}}">{{link.title}}</a> <ol> <li ng-repeat="event in eventsLog track by $index"> {{event}} </li> </ol>كملاحظةٍ جانبية، يُعدّ المرشح json المبني في Angular مفيدًا في التنقيح وإنشاء السجلات، فإن أردنا رؤية ما هو أكثر من اسم الحدث، فيُمكننا استخدامه لعرض كامل المحتويات لكائن الحدث. سيكون علينا لإتمام المثال أن نكتب إعداداتٍ مباشرةً للمسارين. angular.module('app') .config(function($routeProvider) { $routeProvider .when('/', { controller: 'HomeController', templateUrl: '/views/events/index.html' }) .when('/events', { controller: 'EventsController', templateUrl: '/views/events/index.html' }); });انقر على الرابط في المثال السابق لرؤية الأحداث المسجلة في الصفحة. الموارد التي تتبع أسلوب RESTيُقدّم أسلوب REST في تطوير تطبيقات الويب مجموعةً من المعايير لتنظيم عمليات CRUD (إنشاء، قراءة، تحديث و حذف) على مجموعات الموارد والموارد المفردة أيضًا. لن تحتاج عند استخدامك لـ Angular أن تتّبع أسلوب REST في التوجيه إلا إذا قمت بتحميل الوحدة ngResource التي لم نقم بتغطيتها في السلسلة. على أيّ حال، سنختم هذا الفصل بالقليل من التوجيه المتّبع لأسلوب REST لتحصل على خبرةٍ في بعض الأمور العمليّة في التوجيه. سنحتاج إلى مجموعة موارد لنتمكّن من البدء، وسنعرض في الفصل التالي HTTP كيف نقوم بتحميل البيانات من مخدّمٍ في النهاية الخلفية (backend). أما الآن فسنقوم فقط بحقن مصفوفةٍ من كائناتٍ من نوع item في داخل المتحكّم. angular.module('app') .factory('Item', function(filterFilter) { var items = [ {id: 1, name: 'Item 1', color: 'red'}, {id: 2, name: 'Item 2', color: 'blue'}, {id: 3, name: 'Item 3', color: 'red'}, {id: 4, name: 'Item 4', color: 'white'} ]; return { query: function(params) { return filterFilter(items, params); }, get: function(params) { return this.query(params)[0]; } }; });لكلّ عنصرٍ في المصفوفة قيمة فريدة للخاصية id فيه، مما يسمح لنا بالتعامل معه كموردٍ منفرد. تقوم الخدمة التي يُنشئها التابع factory بتغليف الوصول إلى المصفوفة items بتابعين مفيدين هما: query لمجموعة الموارد، وget للموارد المنفردة. يستخدم التابع query المرشّح ذا الاسم سيء الحظ، filter (محقونٍ مع filterFilter) لتنفيذ جلبٍ حسب المثال باستخدام الوسيط params، أمّا التابع get فيقوم باستدعاء التابع query ليقوم بإعادة موردٍ واحد. (راجع فصل المرشحات إن كنت قد تجاوزته، لمعلوماتٍ إضافيّة عن المرشّحات في Angular.) أوّل شيءٍ نحتاجه في تطبيقٍ يتبع أسلوب REST هو دليل (index) أو مسارٌ للقائمة ليتم كشف المجموعة items كاملةً. وكلّ ما على المتحكم القيام به هو كشف كامل المحتويات للمصفوفة items باستدعاء التابع query دون وُسطاء. angular.module('app') .controller('ItemsController', function($scope, $location, Item) { $scope.location = $location.absUrl(); $scope.items = Item.query(); });واجهة هذا المتحكم سهلةٌ أيضًا، وسنستخدم التوجيه ng-repeat لإظهار العناصر. <div class="well well-sm" ng-bind="location"></div> <a ng-href="/">Home</a> <ol> <li ng-repeat="item in items"> {{item.name}} - {{item.color}} </li> </ol>في هذا المثال الأساسيّ، ستربط إعدادات التوجيه بين مسار الجذر (/) وبين واجهة المجموعة view. angular.module('app') .config(function($routeProvider) { $routeProvider .when('/', { controller: 'ItemsController', templateUrl: '/views/items/index.html' }); });لا يُحقّق المثال السّابق أسلوب REST فعلًا، وذلك لأنّ المسار ليس اسم مجموعة الموارد (items/). المشكلة هي أننا نحتاج إلى ننشئ شيئًا ما في مسار الجذر ليكون المكان الافتراضي الذي يتم تحميل تطبيق Angular منه. سنرى الحل في المثال التالي، وهو إعادة التوجيه الفوري من المسار الجذر إلى المسار items/. العنصر redirectToلنتمكّن من القيام بإعادة توجيهٍ تلقائيّة من مسارٍ لآخر، سيكون علينا استخدام العنصر redirectTo بدلًا من متحكّم وقالب. angular.module('app') .config(function($routeProvider) { $routeProvider .when('/', { redirectTo: '/items' }) .when('/items', { controller: 'ItemsController', templateUrl: '/views/items/index.html' }); });كما يُمكنك أن ترى في شريط الموضع في المثال السابق، فالمجموعة items يتم عرضها في المسار items/. ومهما كان عدد المرات التي تنقر بها على الرابط Home، فلن تتمكن من الانتقال إلى المسار الجذر / وسيتم دومًا إعادة توجيهك إلى المسار items/. هذا استخدامٌ بسيط للخيار redirectTo. إن كنت تريد تطبيق بعض العمليات على إعادة التوجيه، فيُمكنك توفير تابعٍ بدلًا من مسارٍ نصّيّ. التابع searchكما ناقشنا في بداية هذا الفصل، تقدّم روابط URL النصّية تمثيلًا لحالة التطبيق (مثل عملية ترشيحٍ للموارد) يُمكن أن يتم حفظها ومشاركتها بسهولة. كيف يُمكننا معالجة نصّ طلب (query) يطلب فقط الحصول على العناصر التي تكون قيمة العنصر color فيها هو لونًا معيّنًا؟ angular.module('app') .config(function($routeProvider) { $routeProvider .when('/', { controller: 'LocationController', template: '<div class="well well-sm" ng-bind="location"></div>\ <a ng-href="/items?color=red">Red items</a>' }) .when('/items', { controller: 'ItemsController', templateUrl: '/views/items/index.html' }); });في هذا المثال، تحتوي واجهة مسار الجذر الخاص بالتطبيق على رابط التّنقّل الحاوي على نصّ الطلب color=red. يُمكننا جلب قيمة هذا الوسيط بسهولةٍ باستخدام التابع search للخدمة location$. angular.module('app') .controller('ItemsController', function($scope, $location, Item) { $scope.location = $location.absUrl(); $scope.items = Item.query({color: $location.search().color}); });عند النّقر على الرابط Red items في المثال السابق، سترى كيف استخدم التابع query (الذي قُمنا بتعريفه سابقًا في الخدمة items) المُرشّح filter للقيام بعملية جلبٍ حسب المثال. الخدمة routeParams$يعتمد أسلوب REST نموذجيًّا على إلحاق معرّف المورد الفريد في نهاية المسار بدلًا من وضعه في نصّ الطلب. كيف يُمكننا القيام بمعالجةٍ صحيحة للمسار بحيث يحوي المعرّف الفريد؟ أو بعبارةٍ أدقّ، كيف يُمكننا استخراج المعرّف الفريد 3 من المسار items/3/ على سبيل المثال؟ لنقم بتحديث واجهة المجموعة لتتضمّن هذا الأسلوب من رابط التّنقّل لكلّ مورد مفرد على حدة. <div class="well well-sm" ng-bind="location"></div> <p class="lead">Items</p> <ol> <li ng-repeat="item in items"> <a ng-href="/items/{{item.id}}"> {{item.name}} </a> </li> </ol>تُقدّم الخدمة routeParams$ وصولًا ملائمًا للعناصر في المسار، حيث يقوم بكشفها (expose) كعناصر مُسمّاة. يُمثّل القسم الأخير من المسار المعرّف الفريد لموردٍ وحيد يتبع أسلوب REST. فمثلًا، يجب أن يعيد المسار items/3/ تمثيلًا للمورد Item بالمعرّف الفريد 3. في إعدادات التوجيه الخاصة بنا، يُمكننا استخدام البادئة الخاصّة : لتعريف متغيّراتٍ ذات أسماءٍ متغيرّة قابلةٍ للاستخراج من المسار. تمّ الاتّفاق على تسمية الوسيط المعرّف للمورد بالاسم id:، لذا سيكون نصّ المسار هو items/:id/. angular.module('app') .config(function($routeProvider) { $routeProvider .when('/', { redirectTo: '/items' }) .when('/items', { controller: 'ItemsController', templateUrl: '/views/items/linked-index.html' }) .when('/items/:id', { controller: 'ItemController', templateUrl: '/views/items/show.html' }); });تقوم الوحدة بوضع الوسطاء المستخرجة من المسار في الخدمة routeParams$ التي يجب أن نقوم بحقنها في المتحكّم ItemController جنبًا إلى جنبٍ مع الخدمة Item التي أنشأناها. angular.module('app') .controller('ItemController', function($scope, $location, Item, $routeParams) { $scope.location = $location.absUrl(); $scope.item = Item.get({id: $routeParams.id}); });سنقوم باستدعاء التّابع Item.get مستخدمين القيمة التي تمّ إسنادها في routeParams.id$، وهذا التّابع يستخدم المرشّح filter لإيجاد موقع النموذج الصحيح. (يُمكن للتابع ()Array.prototype.find الموجود في المكتبة المركزيّة أن يُقدّم طريقةً أفضل للقيام بذلك عندما ينتشر هذا التابع على نطاقٍ واسع.) طريقة عرض المورد item المفرد سهلةٌ ومباشرة، سنقوم بتضمين رابطٍ للعودة إلى المسار items/ بحيث نتمكّن من العودة إلى واجهة عرض القائمة. <div class="well well-sm" ng-bind="location"></div> <a ng-href="/items">Items</a> <p class="lead">{{item.name}}</p> <p>Color: {{item.color}}</p>صحيحٌ أنّ الخدمة routeParams$ والتابع ()location.search$ كلاهما سهل الاستخدام نوعًا ما، إلّا أنّهما معًا يقدّمان حجر بناءٍ هامًّا في أيّ عمليّة توجيه متضمّنةٍ لأسلوب REST. خاتمةتعلّمنا في هذا الفصل أساسيات طريقة Angular الخاصة بها في التوجيه. ورغم أنّ ngRoute لا تُقدّم بعض الميزات المعقّدة للتوجيه، كدعم الموارد المتداخلة، أو آلة الحالة من الدرجة الأولى، أو توليد مسارات URL، إلا أنّها تعطيك مقدّمةً ممتازةً للتوجيه في Angular. ستجد أنّ العديد من التطبيقات الحقيقية تستخدم UI-Router من مشروع AngularUI بدلًا من ذلك، ولن نتطرّق إليها في هذه السلسلة، بل سيكون الفصل الأخير مقدّمةً لتحميل البيانات من المخدّم في النهاية الخلفية (backend) باستخدام الخدمة http$ في Angular. ترجمة -وبتصرّف- للفصل الثاني عشر (Routing) من كتاب: Angular Basics لصاحبه: Chris Smith.
  8. تطرقنا في المقال السابق إلى نبذة عن تاريخ نماذج HTML5 إضافة إلى جُملة من خصائصها الجديدة. سنتطرق في هذا المقال إلى أنواع الحقول الجديدة التي أضافتها HTML5 إلى النماذج. مثلما سنلاحظه طيلة هذا المقال أيضا فإن هذه المميزات الجديدة ستُسهل المهمة على المُطورين وستقدم تجربة أفضل للمستخدم. وكما سبق وأن أشرنا إليه في المقال السابق فإنه يُمكن الشروع في استخدام كل هذه الميزات منذ الآن. أنواع الحقول الجديدةأضافت HTML5 13 نوعا جديدًا من الحقول، سنقوم باستعراضها أولا ومن ثم سنشرح لماذا يجب عليك الشروع في استخدامها في مشاريعك. لاستخدام هذه الحقول الجديدة فائدتان، أولاهما هو تقليص زمن التطوير الذي تحتاجه لإنهاء تطبيقك، وثانيهما هو تقديم تجربة استخدام أفضل. الحقول الجديدة التي سنستعرضها في هذا المقال هي كالتالي: searchemailurltelnumberrangedatemonthweektimedatetimedatetime-localcolorsearchلا يوجد أفضل من هذا الحقل للشروع في استعراض خواص هذه الحقول الجديدة. ليس المقصود بالبحث هنا المحركات الشهيرة كـ Google، Yahoo أو Bing، بل نقصد حقل البحث الذي استعملته على أحد مواقع التجارة الإلكترونية، على ويكيبيديا أو على مُدونتك الشخصية. وقد تكون هذه الحقول (حقول البحث بشكل عام) هي الحقول الأكثر استعمالا على الويب، إلا أننا نستعملها بشكل لا يدل فعليا على وظيفتها، حيث أننا ألفنا إنشاء حقول البحث على النحو التالي: <input type="text" name="search"> لكن ماذا لو كان بإمكاننا القيام كتابتها على النحو التالي: <input type="search" name="search"> وهو ما يُمكن فعلا القيام به باستخدام HTML5، وهو ما يبدو أفضل بكثير، أليس كذلك؟ تظهر المُتصفحات حقول البحث بنفس مظهر الحقول النصية إلى غاية أن تشرع في الكتابة فيها، وحينها ستظهر علامة x صغيرة على الجانب الأيمن للحقل، والذي يسمح لك بمسح الحقل بمجرد النقر عليه، وهو أمر مماثل لما يحدث مع حقل البحث في مُتصفح Safari. حقل البحث كما يظهر على مُتصفح Safari على نظام Windows.الوضع على الهواتف الذكية أفضل بكثير، ألق نظرة على الصورة التالية والتي تُظهر حقل بحث على هاتف iPhone. لدى انتقال التركيز Focus إلى خانة البحث فإن لوحة مفاتيح خاصة تظهر، لاحظ زر search في الزاوية اليُمنى أسفل الشاشة، والتي تُعوض زر Go لما يكون الحقل نصيا فقط. حقل البحث على هاتف iPhoneكما سبق وأن لاحظناه مع الخصائص الجديدة في المقال السابق فإن المُتصفحات التي لا تفهم/تدعم هذا الحقل تُوفر تراجعا رشيقا له graceful degradation، وهو ما يحدث مع جميع الحقول التي سنتطرق إليها في هذا المقال. إذا لم يستطع المُتصفح فهم type="search" فإنه سيقوم بتعويضه بـ type="text"، وهو ما يعني بأنك لن تخسر أي شيء باستخدامك لهذا الحقل، بل العكس كل العكس، حيث أنك تُوفر تحسينا تدريجيا progressive enhancement وتُوفر لزوار موقعك تجربة مُستخدم أفضل. كما نعلم جميعا فإن ملء حقول نموذج ليس بالأمر المُمتع وبالتالي فإن أي تحسين يُمكن أن ندخله عليها مُرحب به. emailمن حيث المظهر لا يملك التفريق ما بين حقل email وما بين الحقول النصية العادية، ويستعمل هذا الحقل لإدخال عنوان بريد إلكتروني (أو أكثر). لكن من حيث الاستخدام ولدى إضافة خاصية required إلى هذا الحقل فإن المُتصفح سيقوم حينها من التحقق من أن النص الذي تم إدخاله هو فعلا عُنوان بريد إلكتروني صحيح من حيث بُنيته. بطبيعة الحال التحقق الذي يقوم به المُتصفح هو مُجرد تحقق بدائي حيث يتحقق من وجود كل من @ و النقطة في العنوان كما أنه لا يسمح بوجود المسافات. يدعم هذه الخاصية كل من Opera 9.5+، Firefox 4+، IE10 وChrome 5+، وتُظهر المُتصفحات رسالة خطأ إن كان العنوان الذي تم إدخاله غير صحيح البُنية. بإمكانك التحكم في مظهر الحقل بعد ملئه وذلك باستخدام أشباه الفئة :valid و :invalid أو :required مثلما يشرحه هذا المقال. <input type="email" name="email" required>رسالة خطأ في حقل email كما يظهر على مُتصفح Opera.تُشير مواصفات HTML5 إلى أنه يُمكن إدخال أكثر من عنوان بريد إلكتروني في هذا الحقل، مما يعني بأن يُمكنك استخدام خاصية multiple مع حقول البريد الإلكتروني (type="email") أيضا، وهو ما يذكرك بمقدار شفرات JavaScript التي كان يتوجب عليك كتابتها بنفسك لو كنت تقوم بعمليات التحقق هذه بنفسك. لمزيد من التفاصيل حول التحكم في مظهر حقول النماذج بالاستعانة بأشباه الأصناف pseudo-classes يُرجى الاطلاع على هذا المقال على موقع A List Apart. ملاحظة: لدى كتابة هذه السطور لا تزال بعض المُتصفحات تُعاني من نقائص لدى التحقق من عناوين البريد الإلكتروني التابعة لأسماء نطاقات تستعمل حروفا غير لاتينية (كبعض أسماء النطاقات اليابانية)، حيث أن بعض المُتصفحات تعتبرها غير صحيحة البُنية. خذ على سبيل المثال التالي: <input type="email" name="email" value="gordo@日本.jp">والتي تعتبرها كل من متصفحات Firefox (تم تصحيح الوضع في Firefox)، Safari، IE أو Chrome غير صحيحة البُنية (يقبل مُتصفح Opera هذا العنوان)، إلا أن Kyle Barrow وجد طريقة لحل هذا المُشكل وذلك باستخدام حقل نصي عادي والاستعانة بخاصية pattern على النحو التالي: <input type="text" name="email" value="gordo@日本.jp" pattern="[^ @]*@[^ @]*">هناك حل آخر إن أردت الإبقاء على type="email" وذلك باستخدام formnovalidate مع زر إرسال النموذج على النحو التالي (هذه الطريقة ستضمن بأن المُتصفح لن يقوم بالتحقق مما يتم إدخاله في حقل البريد الإلكتروني وهو ما أمر قد لا ترغب فيه): <form action="process.php"> <label for="email">Email:</label> <input type="email" name="email" value="gordo@日本.jp"> <input type="submit" formnovalidate value="Submit">كما يُمكن استخدام خاصية novalidate مع النموذج على النحو التالي: <form action="process.php" novalidate> <label for="email">Email:</label> <input type="email" name="email" value="gordo@日本.jp"> <input type="submit" value="Submit">دعونا من هذه المشكل ولنعد إلى ما سبق وأن تحدثنا عنه بخصوص منافع حقول HTML5 الجديدة، والتي هي –كما سبق ذكره أيضا- تقليص وقت التطوير وتحسين تجربة المُستخدم. ألقوا نظرة على المثال السابق لكن باستخدام iPhone مثلا، سيظهر لك أمر مماثل للصورة التالية: يُظهر iPhone لوحة مفاتيح خاصة مع حقول البريد الإلكترونيهل لاحظت الاختلاف هذه المرة؟ ركز على السطر السُفلي في لوحة المفاتيح ستجد بأن هناك زرا خاصا بـ @ وآخر خاصا بالنقطة . وهما زران ستحتاجهما لدى كتابة عناوين بريد إلكتروني. وكما سبق ذكره مع حقول search فإنه لا يوجد أي جانب سلبي لاستخدام هذا الحقل (type="email") من الآن، حيث أن المُتصفحات التي لا تدعمه ستقوم بتعويضه بحقل نصي عادي (type="text")، وفي باقي المُتصفحات سيحصل الزائر على تجربة مستخدم أفضل. urlتُخصص حقول url مثلما قد تتوقعه لعناوين الويب. تقبل هذه الحقول استخدام خاصية multiple معها للسماح بإدخال أكثر من عنوان واحد. ومثلما هو الحال مع حقول البريد الإلكتروني فإن المُتصفحات تقوم بعملية تحقق بسيطة من مُحتوى هذا الحقل، ومن ثم تعرض رسالة خطأ إن كان بُنية العنوان غير صحيحة، ويتم ذلك عبر التحقق من وجود بعض المحارف الخاصة كـ / ، النقاط، المسافات مع إمكانية التحقق من لاحقة العنوان top-level domain كـ .com مثلا. يتم استخدام حقول url على النحو التالي: <input type="url" name="url" required>ومن جديد سنلقي نظرة على نتيجة صفحة تحتوي هذا الحقل باستخدام iPhone. مثلما تلاحظونه في الصورة التالية فإن المُتصفح يُظهر لوحة مفاتيح خاصة ليسهل مهمة الكتابة على المُستخدم، حيث تم استبدال زر المسافة بأزرار لكل من الـ /، النقطة و زر خاص بـ .com (يكفي الضغط مطولا عليه لتظهر لواحق أُخرى كـ .org أو .net). يُظهر iPhone لوحة مفاتيح خاصة مع حقول عناوين الويبtelتختلف حقول tel عن حقول email أو url بكونها لا تعتمد أي نمط مُعين بحكم أن أرقام الهواتف تختلف باختلاف بلدانها وهو ما يجعل من مهمة التحقق من الأرقام في غاية الصعوبة، عدى السماح باستخدام الأرقام فقط مع إمكانية استخدام مُحرف +. بطبيعة الحال يبقى بإمكانك التحقق من رقم الهاتف إن أردت إن كنت تعرف بأن الأرقام التي سيتم إدخالها تتبع نمطا مُعينا، لكن يجب عليك القيام بذلك على جانب الخادوم من تطبيقك. يتم استخدام حقول tel على النحو التالي: <input type="tel" name="tel" id="tel" required>من جديد فإن هواتف iPhone تتعرف على حقول أرقام الهواتف لكن هذه المرة يستعرض المُتصفح لوحة مفاتيح مُختلفة كُلية، حيث يتم استخدام لوحة أرقام الهواتف، وهو ما يحدث أيضا على بعض هواتف Android (مثل هاتف HTC Desire والذي يظهر في الصورة أدناه). ظهور لوحة أرقام الهاتف ستمكن المُستخدم من إدخال رقم هاتفه بشكل أسرع. يقوم iPhone وبعض هواتف Android بتغيير لوحة المفاتيح بشكل كبير لدى استخدام حقول أرقام الهواتف.numberمثلما هو ظاهر من اسمه، يتم استخدام حقل number مع الأرقام. ومثلما هو عليه الحال مع أغلب هذه الحقول الجديدة فلقد كان مُتصفح Opera السباق في دعمها. يظهر هذا الحقل على كل من Opera، Safari وChrome على هيئة spinbox حيث أنه يمكن النقر على سهمي فوق وتحت لتغيير قيمة الحقل. أما على Firefox وIE10 فيظهر الحقل كمجرد حقل نصي عادي. حقل number كما يظهر على مُتصفح Operaيُمكن استخدام خصائص min، max وstep مع الحقول الرقمية ما يسمح بالتحكم في القيم القصوى والدنيا للحقل إضافة إلى "الخطوة" التي يتم الانتقال بها لدى النقر على زري فوق وتحت، إضافة إلى إمكانية التحكم في القيمة القياسية عبر استخدام خاصية value. المثال التالي يُوضح كيفية القيام بذلك: <input type="number" min="5" max="18" step="0.5" value="9" name="shoe-size">في هذا المثال يُمثل min القيمة الدنيا المُمكنة التي يُمكن للحقل قبولها، max تُمثل القيمة القصوى المُمكنة. لدى الوصول إلى هاتين القيميتن فإنه سيتم تعطيل السهم المسؤول عن ذلك وبالتالي فإنه لا مجال للذهاب أعلى القيمة القُصوى أو أدنى من القيمة الدنيا*. أما step فهي الخُطوة التي يتم الانتقال بها لدى النقر على السهمين والتي تأخذ 1 كقيمة قياسية، وهو ما يعني بأنه يمكن استخدام قيم سالبة أو استخدام خطوات مثل 0.5 أو5**. أما value فهي خاصية ألفنا استخدامها مع HTML4. كل هذه الخواص ليست إجبارية. *: لم يتم تعطيل الأسهم لدى تجربتي للحقل على كل من Safari وOpera. **: لدى تجربتي لقيم سالبة قام كل من Opera وSafari باستخدام القيمة القياسية 1 للخطوة بدل القيمة السالبة. في مقابل طريقة عرض Opera للحقول الرقمية، لا يقوم كل من iPhone و بعض هواتف Android بعرضها سوى كحقول نصية عادية، لكن يقوم كلاهما باستخدام لوحة مفاتيح خاصة. حقل number كما يظهر على كل من iPhone وHTC Desireلجعل iPhone يستخدم لوحة أرقام الهواتف مثلما رأينا مع حقول الهواتف، اكتشف Chris Coyier صاحب موقع CSS Tricks خدعة تساعد في القيام بذلك، حيث أنه بدل استخدام type="number" فإنه يكفي استخدام حقل نصي type="text" وإضافة خاصية pattern بحيث نجعله لا يقبل سوى الأرقام مثلما هو موضح في المثال التالي. هذا الحل ليس مثاليا، لكنه يحل الُمشكل. يُمكنكم الإطلاع على نتيجة ذلك في هذه الفيديو القصيرة. <input type="text" pattern="[0-9]*" name="shoe-size">هذه التقنية من شأنها أن تصبح "مهجورة" obsolete بعد اعتماد خاصية inputmode والتي تمت إضافتها مؤخرا إلى مواصفات HTML5. هذه الخاصية من شأنها أن تُحدد طريقة ملء الحقل الأنسب للمستخدم. لدى استخدام هذه الخاصية فإنه سيصبح بالإمكان الاختيار ما بين الأرقام، الحروف اللاتينية، عناوين البريد الإلكتروني أو Kana (والتي يبدو بأنها خاصة باللغة اليابانية). rangeحقل range مُشابه لحقل number مع نكهة إضافية، حيث أنه يُمثل قيمة عددية محصورة ضمن نطاق مُعين (range). قد تتساءل عن الفرق ما بين هذين الحقلين، الفرق بسيط وهو أن قيمة الحقل ليست بتلك الأهمية التي هي عليها قيمة الحقل مع number، كما أن المُتصفح يوفر آلية أكثر سهولة في التحكم فيه. يتم إظهار حقل range على كل من مُتصفحات Opera، Safari، IE10 وChrome على هيئة slider (انظر الصورة أدناه). يُظهر مُتصفح IE10 لدى تحريك زر الحقل القيمة التي تم اختيارها. يقوم مُتصفح Opera بإظهار الـ slider بشكل عمودي إن تم إعطاء قيمة للطول أكبر من قيمة العُرض له في ملف CSS. المثال التالي يُوضح كيفية استخدام حقل rang للقيام مثلا بتحديد مدى مهارة المُستخدم في مجال مُعين على سُلم من 1 إلى 100، حيث نقوم بتحديد القيم الدنيا والقُصوى من خلال الخاصيتين min وmax. بإمكاننا أيضا تحديد قيمة قياسية لهذا الحقل بالاستعانة بخاصية value. <input id="skill" type="range" min="1" max="100" value="0">حقل range على مُتصفح Chromeملاحظة: إن كنت تبحث عن طريقة لتوفير تراجع رشيق لحقول rang على المُتصفحات التي لا تدعمها، فيُمكنك القيام بذلك باستخدام هذه الطريقة التي أتى بها Remy Sharp. dates و timesإن سبق لك أن حجزت أو اشتريت تذاكر على الإنترنت فإنك من دون شك قد تعاملت مع data picker لاختيار التاريخ الذي توده، وربما قد سبق لك وأن استخدمت ذلك في أحد مشاريعك. عادة ما يتم توفير ذلك باستخدام JavaScript وبالتحديد مكتبة jQuery، Dojo أو YUI. قد يكون تحميل مكتبة بأكملها وإحدى إضافاتها من أجل القيام بذلك قرارًا غير صائب، لكن مع HTML5 فإنه يُمكن القيام بذلك من دون أية إضافات. ليس هذا فحسب فما تُقدمه HTML5 لا تسمح باختيار التاريخ فقط، بل يُمكن أيضا اختيار الأسبوع، الشهر، الوقت، التاريخ، وحتى التاريخ التابع لمنطقة زمنية مُعيّنة. يُمكن القيام بذلك على النحو التالي: <input id="dob" name="dob" type="date">يُمكنك الذهاب إلى أبعد من ذلك باستخدام خاصيتي min وmax لتضمن بأن التاريخ الذي يختاره المُستخدم يقع ضمن نطاق تقوم بتحديده. <input id="startdate" name="startdate" min="2012-01-01" max="2013-01-01" type="date">وكما حول الحال مع العديد من أنواع الحقول فإن مُتصفح Opera يتميز عن غيره بدعمها لهذا الحقل بشكل جيد. دعونا نلقي نظرة على الكيفية التي تظهر فيها هذه الحقول على مُتصفح Opera: dateالصورة التالية تُبين الحالة التي يظهر عليها حقل date على الإصدار 10.5 من مُتصفح Opera لا يقتصر استخدام هذا الحقل على الأجهزة المكتبية فقط، تقوم أجهزة BlackBerry ومتصفح Chrome على نظام Android باستخدام date pickerالخاص بها لدى استخدام حقل date. monthالصورة التالية توضح كيف تظهر حقول month على مُتصفح Opera والتي يُمكن استخدامها مثلا لإدخال شهر انتهاء صلاحية بطاقة دفع إلكتروني. يُمكن استخدام حقل month على النحو التالي: <input id="expiry" name="expiry" type="month" required> weekيُمكن أيضا تمكين المُستخدم من اختيار أسبوع مُعين في الشهر على النحو التالي: <input id="vacation" name="vacation" type="week">لاحظوا في الصورة التالية كيف يقوم مُتصفح Opera بإبراز/تظليل الأسبوع الذي يتم اختياره. timeالصورة التالية تُبين الحالة التي يظهر عليها حقل time على متصفح Opera والذي يُمكن استخدامه على النحو التالي: <input id="exit-time" name="exit-time" type="time"> datetimeيُمكن دمج كلا من حقلي date وtime لينتج لنا حقل datetime والذي يُستعمل لتحديد التاريخ والوقت معا على النحو التالي: <input id="entry-day-time" name="entry-day-time" type="datetime"> datetime-local وأخيرا وليس آخرا، تظهر الصورة التالية كيف يسمح HTML5 لنا بالتحكم بشكل أدق في آلية اختيار التاريخ والوقت ضمن المنطقة الزمنية المحلية باستخدام datetime-local على النحو التالي: <input id="arrival-time" name="arrival-time " type="datetime-local"> مشاكل مع date و timeهناك على الأقل مشكلان رئيسيان مع حقول الوقت والتاريخ. الأول يخص عدم التمكن من كتابة التاريخ يدويا بشكل مباشر (على المتصفحات التي تدعمها) رغم أنه يمكن التحكم في هذه الحقول باستخدام لوحة المفاتيح، حيث أنه وفي الحالات التي يقوم المستخدم بملء نفس النموذج عدة مرات فإنه هذه العملية ستكون أسرع لو تم تمكينه من كتابة التواريخ يدويا. المشكل الثاني يكمن في عدم مقدرتنا في التحكم في مظهر الـ data Picker. الاعتقاد السائد هو أن هذا الأمر محمود، حيث سيحصل المستخدم على نفس تجربة المستخدم ونفس المظهر على جميع المواقع التي يزورها، إلا أن الشركات -ومن دون شك- سترغب في توفير Data Picker خاص بها. قامت كل من Safari5 و Chrome5 بدعم هذه الحقول إلا أن مظهرها ليس جيدا. يجب أن تكون حقول date على الشكل التالي: YYYY-MM-DD وحقول datetime على الشكل الغريب التالي: YYYYMM-DDT00:00Z. ومثلما هو عليه الحال مع باقي أنواع الحقول الأخرى تقوم المتصفحات التي لا تدعم هذه الحقول بتجاهلها وتعويضها بحقول نصية عادية type="text". colorتسمح حقول color باختيار لون مُعين وإرجاع قيمته الست عُشرية Hex value. من المفترض أن يكون المُستخدم قادرا على إدخال قيمة اللون الذي اختاره أو أن يقوم باختيار اللون من لوحة Color Picker والتي يمكن أن تكون إما لوحة اختيار الألوان الخاصة بنظام التشغيل أو لوحة اختيار الألوان الخاصة بالمُتصفح. قام مُتصفح Opera 11 بدعم حقل الألوان بتوفيره جملة من الألوان القياسية إضافية إلى زر يوفر إمكانية اختيار ألوان أخرى، والذي -بمجرد النقر عليه- يُظهر لوحة اختيار الألوان الخاصة بنظام التشغيل. <input id="color" name="color" type="color">حقل الألوان على مُتصفح Opera على اليسار ونتيجة النقر على زر other على اليمين.في المقابل توفر بعض أجهزة BlackBerry دعما لحقول color حيث تقوم بإظهار لوحة اختيار الألوان المُبنية في الصورة التالية: خلاصةباستخدامك للحقول الجديدة الخاصة بـ HTML5 فأنت تقدم تجربة مستخدم أفضل لزوار موقعك، تحضر موقعك للعمل حسب معايير المستقبل، وتسهل من مهمة التطوير عليك. بطبيعة الحال ليس من المُمكن أن نتجاهل المُتصفحات التي لا تدعم هذه الخواص، إلا أنه من الممكن توفير دعم لها باستخدام JavaScript (ستجد تفاصيل حول الأمر بقراءتك للفصل السادس من كتاب Beginning HTML5 and CSS3). يُمكن لك أن تجد نموذجا تجريبيا يستخدم بعضا من الأمثلة التي استعرضناها في هذا المقال هنا. أشرنا خلال هذا المقال إلى المتصفحات التي تدعم كل من الحقول التي استعرضناها، لكن مع الإصدارات الجديدة لكل متصفح والتي يتم إطلاقها بوتيرات متسارعة فإنه من الصعب معرفة ما الذي يدعمه هذا المتصفح وما الذي لا يدعمه ذاك المتصفح، لكن إن أردت البقاء على اطلاع على ذلك فإنه يُمكنك ذلك عبر المواقع التالية: can I use …، FindMeByIP ومحرك بحث Wufoo الخاص بالـ HTML5. إذا فاتتك قراءة المقال السابق الذي يتحدث عن مختلف الخصائص الجديدة في نماذج HTML5 فيُمكن إيجاده هنا. ترجمة –وبتصرف- للمقال HTML5 forms input types لصاحبه Richard Clark.