عبد اللطيف ايمش

المساهمون
  • المساهمات

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

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

  • Days Won

    20

السُّمعة بالموقع

103 Excellent

آخر الزُوّار

5,399 زيارة للملف الشّخصي
  1. إحدى المهارات الأساسية والمهمة التي عليك أن تتقنها هي القدرة على استيراد وتصدير قواعد البيانات، إذ تستطيع أخذ نسخ احتياطية لقواعد بياناتك وتستعيدها عند الحاجة، أو يمكنك الاستفادة منها لنقل البيانات إلى خادوم جديد أو بيئة تطوير مختلفة. إجراء عملية تصدير من قواعد بيانات MySQL و MariaDB هو أمرٌ بسيطٌ، وسنشرحه في هذا الدرس إضافةً إلى شرح طريقة استيراد النسخة الاحتياطية. المتطلبات المسبقة لتصدير أو استيراد قواعد بيانات MySQL ستحتاج إلى: وصول إلى خادوم لينكس يستعمل قواعد بيانات MySQL أو MariaDB. قاعدة بيانات مع معلومات المستخدم القادر على إجراء عمليات عليها. تصدير قاعدة البيانات تُستعمَل الأداة mysqldump لتصدير قواعد البيانات إلى ملفات SQL نصية، ويمكن بسهولة نقل تلك الملفات كيفما تشاء. ستحتاج إلى معرفة اسم قاعدة البيانات نفسها وإلى اسم المستخدم وكلمة المرور لحسابٍ يملك امتيازاتٍ تسمح –على الأقل– بأذونات القراءة الكاملة على قاعدة البيانات. استعمل الأمر الآتي لتصدير قاعدة البيانات: mysqldump -u username -p database_name > data-dump.sql username هو اسم المستخدم الذي يستطيع الوصول إلى قاعدة البيانات database_name هو اسم قاعدة البيانات التي نريد تصديرها data-dump.sql هو مسار الملف الذي نريد حفظ مخرجات عملية التصدير إليه لن يعرض الأمر السابق أيّة مخرجات مرئية، لكن يمكنك النظر في محتويات الملف data-dump.sql لتتأكد من وجود ملف SQL سليم فيه باستعمال الأمر: head -n 5 data-dump.sql يجب أن تبدو المخرجات (التي تظهر أوّل خمسة أسطر من الملف) كما يلي، يجدر بالذكر أنَّ الملف الآتي هو ناتج عملية تصدير قاعدة بيانات باسم database_name: -- MySQL dump 10.13 Distrib 5.7.16, for Linux (x86_64) -- -- Host: localhost Database: database_name -- ------------------------------------------------------ -- Server version 5.7.16-0ubuntu0.16.04.1 إذا حدثت أيّة أخطاء أثناء عملية التصدير، فسيعرضها mysqldump على الشاشة مباشرةً. استيراد قاعدة البيانات لاستيراد ملف SQL مُصدَّر إلى قاعدة بيانات MySQL أو MariaDB، فعليك أولًا إنشاء قاعدة بيانات جديدة التي ستستضيف البيانات المستوردة. سجِّل دخولك إلى عميل قواعد البيانات بحساب المستخدم root أو أي حساب آخر له امتيازات كافية لإنشاء قواعد بيانات جديدة: mysql -u root -p ستنتقل الآن إلى سطر الأوامر الخاص بقواعد MySQL، أنشِئ الآن قاعدة بيانات جديدة وليكن اسمها new_database: CREATE DATABASE new_database; يجب أن تشاهد الناتج الآتي الذي يدل على نجاح إنشائها: Query OK, 1 row affected (0.00 sec) اخرج الآن من عميل MySQL بكتابة الأمر exit أو بالضغط على الزرين Ctrl+D، وبعد عودتك إلى سطر الأوامر ستستطيع استيراد الملف باستخدام الأمر الآتي: mysql -u username -p new_database < data-dump.sql username هو اسم المستخدم الذي يستطيع الوصول إلى قاعدة البيانات new_database هو اسم قاعدة البيانات التي نريد استيراد البيانات إليها data-dump.sql هو مسار الملف الذي نريد استيراد محتوياته لن تظهر أية مخرجات إذا نجح تنفيذ الأمر السابق، لكن إن حدثت أخطاء خلال العملية فسيظهرها الأمر mysql على الشاشة. يمكنك التأكد من استيراد قاعدة البيانات بتسجيل الدخول إلى عميل MySQL مجددًا وتفحص البيانات، يمكن فعل ذلك بتحديد قاعدة البيانات الجديدة عبر USE new_database ثم كتابة الأمر SHOW TABLES;‎ أو ما شابهه. الخلاصة أصبحت تعلم كيف تصدِّر قواعد بيانات MySQL إلى ملفات وكيف تستوردها مجددًا. هنالك خياراتٌ أخرى متاحةٌ للأمر mysqldump التي تُعدِّل سلوك هذا الأمر عند تصدير قواعد البيانات، والتي يمكنك التعرف عليها في صفحة التوثيق الرسمي. ترجمة –وبتصرّف– للمقال How To Import and Export Databases in MySQL or MariaDB لصاحبه Mateusz Papiernik
  2. برمجية Jenkins هي خدمة أتمتة مفتوحة المصدر الغرض منها هو أتمتة المهام التقنية المتكررة التي تتعلق بدمج وتوفير البرمجيات. برمجية Jenkins مكتوبة بلغة Java ويمكن تثبيتها من حزم أوبنتو أو بتنزيل وتشغيل ملف WAR (الذي هو مجموعة من الملفات التي تُنشِئ تطبيق ويب كامل ليعمل على خادومك). سنُثبِّت Jenkins في هذا الدرس بإضافة مستودع حزم دبيان الخاص بها، ثم بتثبيت الحزم اللازمة عبر الأداة apt-get من ذاك المستودع. المتطلبات المسبقة سنحتاج إلى خادوم أوبنتو 16.04 فيه حساب مستخدم ليس جذرًا وفيه جدار ناري وذلك باتباع التعليمات الواردة في درس «الإعداد الابتدائي لخادوم أوبنتو 14.04](https://academy.hsoub.com/devops/servers/الإعداد-الابتدائي-لخادوم-أوبنتو-1404-r4/)»، ننصح باستعمال 1 غيغابايت من ذاكرة RAM على الأقل؛ راجع صفحة Choosing the Right Hardware for Masters لمزيدٍ من المعلومات حول العتاد اللازم لتثبيت Jenkins. يمكنك المتابعة مع هذا الدرس بعد إعداد الخادوم. الخطوة الأولى: تثبيت Jenkins الإصدار المتوافر في مستودعات أوبنتو الرسمية يكون قديمًا ومتأخرًا عن الإصدار الحالي لمشروع Jenkins؛ وللاستفادة من آخر التحديثات والميزات فسنستخدم الحزم المُصانة من قِبل مشروع Jenkins نفسه. علينا أولًا إضافة مفتاح المستودع إلى النظام: wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add - بعد إتمام إضافة المفتاح بنجاح فستظهر كلمة OK في الطرفية؛ ثم سنضيف بعد ذلك عنوان مستودع دبيان إلى ملف sources.list الموجود في الخادوم: echo deb http://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list بعد تنفيذ الخطوتين السابقتين، علينا تحديث فهرس الحزم عبر الأمر: sudo apt-get update ثم نثبّت Jenkins مع اعتمادياته كلها، بما فيها بيئة تشغيل Java: sudo apt-get install jenkins يمكننا الآن تشغيل خادوم Jenkins بعد تثبيته مع اعتمادياته. الخطوة الثانية: بدء تشغيل خادوم Jenkins سنستخدم الأداة systemctl لتشغيل Jenkins: sudo systemctl start jenkins ولعدم إظهار الأمر systemctl لأية مخرجات، فسنستخدم الخيار status لعرض حالة الخدمة للتأكد أنها قد بدأت دون مشاكل: sudo systemctl status jenkins إذا جرى كل شيءٍ على ما يرام، فيجب أن تشير المخرجات أنَّ الخدمة تعمل حاليًا وستُشغَّل تلقائيًا عند الإقلاع: ● jenkins.service - LSB: Start Jenkins at boot time Loaded: loaded (/etc/init.d/jenkins; bad; vendor preset: enabled) Active:active (exited) since Thu 2017-04-20 16:51:13 UTC; 2min 7s ago Docs: man:systemd-sysv-generator(8) بعد تشغيل خادوم Jenkins، علينا الآن تعديل قواعد الجدار الناري للسماح بالوصول إلى خدمة Jenkins من متصفح الويب لإكمال ضبطه المبدئي. الخطوة الثالثة: فتح المنفذ في الجدار الناري يعمل خادوم Jenkins افتراضيًا على المنفذ 8080، لذا سنفتحه باستخدام ufw: sudo ufw allow 8080 يمكننا رؤية القاعدة الجديدة بالتحقق من حالة جدار UFW الناري: sudo ufw status يجب أن نلاحظ أنَّ التراسل الشبكي إلى المنفذ 8080 متاحٌ من كل الشبكات: Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 8080 ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 8080 (v6) ALLOW Anywhere (v6) بعد أن ثبتنا Jenkins وضبطنا الجدار الناري للسماح بالوصول إليه من جميع الشبكات، فسنكمل في الخطوة التالية الضبط المبدئي له. الخطوة الرابعة: ضبط خدمة Jenkins علينا لضبط خدمة Jenkins أن نزور صفحته على المنفذ الافتراضي 8080 مستعملين اسم نطاق الخادوم أو عنوان IP الخاص به كما يلي: http://ip_address_or_domain_name:8080. سنستعمل الأمر cat في نافذة الطرفية لعرض كلمة المرور: sudo cat /var/lib/jenkins/secrets/initialAdminPassword انسخ كلمة المرور المكومة من 32 محرفًا ورقمًا من الطرفية وألصقها في حقل «Administrator password» ثم اضغط على زر «Continue»، ثم ستظهر لك صفحة تعرض خيارين لتثبيت الإضافات المقترحة أو تحديد إضافات معيّنة. اضغط على خيار «Install suggested plugins» الذي سيبدأ عملية التنزيل مباشرةً: بعد إكمال التثبيت سيُطلَب منك ضبط أوّل حساب مستخدم، وصحيح أنَّ من الممكن تخطي هذه الخطوة والإكمال باستعمال المستخدم admin مع كملة المرور المبدئية التي استعملناها أعلاه، لكن من الأفضل إنشاء مستخدم جديد. ملاحظة: الاتصالات المنشأة إلى خادوم Jenkins غير مشفرة، لذا ستُرسَل البيانات النصية كما هي دون أي تشفير، لذا أنصحك باتباع ما ورد في هذا الدرس لإعداد تشفير SSL مع خادوم Jenkins، مما يحمي بيانات المستخدم والمعلومات التي ترسَل عبر واجهة الويب. بعد ضبط أوّل حساب للمدير فستُعرَض لك صفحة فيها «Jenkins is ready!‎»: اضغط على زر «Start using Jenkins» للانتقال إلى لوحة التحكم الرئيسية لخادوم Jenkins: تهانينا، لقد ثبتنا خادوم Jenkins بنجاح. الخلاصة ثبتنا في هذا الدرس برمجية Jenkins من الحزم التي يوفرها المشروع، ثم بدأنا الخدمة وفتحنا منفذًا في الجدار الناري، وأنشأنا حسابًا جديدًا للمدير؛ وتستطيع الآن أن تستكشف Jenkins. ترجمة –وبتصرّف– للمقال How To Install Jenkins on Ubuntu 16.04لصاحبته Melissa Anderson
  3. عندما تصون مستودعًا لمشروع مفتوح المصدر، فأنت تأخذ راية القائد، فلو كنتَ مؤسس أحد المشاريع التي أطلقتها للعموم ليستخدموها ويشاركوا فيها، أو كنت تعمل في فريقٍ وكنت تصون جانبًا من جوانب المشروع، فأنت تقدم خدمةً مهمةً إلى مجتمع التطوير. وعلى الرغم من أنَّ المساهمات في المشاريع مفتوحة المصدر تكون عادةً عبر طلبيات pull وهي أمرٌ بالغ الأهمية للحفاظ على جودة البرمجيات وفائدتها للمستخدمين النهائيين، لكن المساهمين في المشروع ليس لهم نفس تأثير من يقوم بصيانته ويبلور الشكل العام للمشروع؛ فالصائنون يشاركون في صلب تطوير المشاريع مفتوحة المصدر، إذ يديرون المشروع وينظموه يوميًا ويطوروه، ويتفاعلون مع المستخدمين ويوفرون المعلومات اللازمة للمساهمين. سنستعرض في هذا المقال بعض التلميحات عن صيانة المستودعات العامة للمشاريع مفتوحة المصدر. فالمسؤولون عن المشاريع مفتوحة المصدر عليهم مسؤوليات كبيرة تقنية وغير تقنية، والعمل كصائن للمشروع يعطي الفرصة للتعلم من الآخرين، وأخذ خبرة في إدارة المشاريع، ويسمح بمراقبة مراحل نمو المشروع وكيف أصبح المستخدمون العاديون مساهمين فعالين فيه. اكتب توثيقًا مفيدًا سيزيد التوثيق سهل الفهم (والذي سيؤدي إلى جعل البرنامج سهل الاستخدام) من قاعدة مستخدميك، ويساعد في تحويل المستخدمين إلى مساهمين في مشروعك. عندما تفكر بالشيفرات التي تكتبها أثناء تطويرك للمشروع، وتكتب بعض الملاحظات الجانبية لتساعدك في دمج مختلف أجزاء مشروعك مع بعضها بعضًا، فسيسهل عليك البدء بكتابة التوثيق أثناء عملية التطوير؛ أو ربما تقرر أن تكتب التوثيق قبل برمجة التطبيق، متبعًا بذلك منهجية «التطوير الموجه بالتوثيق» (documentation-driven development) التي تقول أنَّ عليك كتابة توثيق ميزات المشروع أولًا ثم برمجة تلك الميزات اعتمادًا على توثيقها. هنالك بضعة ملفات عليك وضعها في المجلد الرئيسي لمشروعك بجانب الشيفرات وهي: - ملف README.md الذي يوفر ملخصًا عن المشروع وأهدافه. - ملف CONTRIBUTING.md الذي يحتوي على تعليمات المساهمة في المشروع. - رخصة مشروعك، والتي ستشجِّع الناس على المساهمة في موقعك، أرجو أن تراجع مقالة كيف تختار رخصة مفتوحة المصدر لبرامجك. قد يأخذ التوثيق أشكالًا عدِّة، لذا عليك أن تضع نوعية المستخدمين المحتملين ومجال المشروع في الحسبان، فمن الممكن أن يأتي التوثيق بمختلف الأشكال ويكون موجهًا نحو فئات مختلفة من مستخدمي المشروع. قد تقرر استخدام شكل أو أكثر من الأشكال الآتية اعتمادًا على مجال عملك: دليل عام لتعريف المستخدمين بالمشروع الدروس التعليمية لعرض مختلف حالات الاستخدام الأسئلة الشائعة (FAQ) للإجابة عن أكثر التساؤلات شيوعًا بين المستخدمين مقالات عن استكشاف الأخطاء التي قد يواجهها المستخدمون وكيفية إصلاحها مرجع للواجهة البرمجية (API) للتطبيق تسمح للمستخدمين معرفة معلومات عن الواجهة البرمجية بسرعة ملاحظات الإصدار (release notes) التي تُذكَر فيها العلل المعروفة والتغييرات التي حدثت في كل إصدار الميزات المستقبلية لتتبع وشرح ما هي الميزات التي ستأتي في إصدارات مستقبلية. تسجيل مقطع فيديو لتعريف المستخدمين بمشروعك عبر الوسائط المتعددة. قد تلائم بعض أشكال التوثيق السابقة مشروعك أكثر من غيرها، لكن توفير أكثر من شكل للتوثيق سيساعد مستخدمي مشروعك أن يفهموا كيف يتفاعلون معك فهمًا أعمق. عليك عند كتابة التوثيق أو تسجيل مقطع فيديو أن تكون واضحًا قدر الإمكان، ومن الأفضل ألّا تكون عندك افتراضات مسبقة عن القدرات التقنية لمستخدمي مشروعك، ومن الأفضل أن تتبع منهجية Top-Down عند تأليف التوثيق، أي أن تشرح بداية الأمر ما الذي تفعله البرمجية بشكل عام (مثلًا: أتمتة أمور إدارة النظام، أو بناء موقع إلكتروني …إلخ.) قبل التعمق في التفاصيل. وصحيحٌ أنَّ اللغة الإنكليزية هي اللغة الرائدة في عالم التقنية، لكن أبقِ في ذهنك مَن هم المستخدمون المتوقعون وما هي لغتهم الأم؛ فاللغة الإنكليزية هي خيارٌ جيدٌ إذا كانت لديك قاعدة مستخدمين واسعة ومن مختلف البلدان، لكن ضع في بالك أنَّ عدد كبيرًا ممن سيقرؤون توثيقك لا تكون اللغة الإنكليزية هي لغتهم الأم، لذا حاول استخدام لغة سهلة لا تُسبِّب لبسًا عند القراء، وإذا كان مشروعك موجّه لمنطقة أو لغة معيّنة مثل برنامج للتعرف على الكلام العربي فأنصحك حينئذٍ أن توفر التوثيق باللغة العربية. حاول أن تكتب التوثيق كما لو كنتَ تكتب لأحد المساهمين الجدد الذين يريدون أن يطلعوا على حالة المشروع، فلا تنسَ أنَّك تريد أن يتحول المستخدمون العاديون إلى مساهمين. تنظيم «القضايا» القضايا (issues) هي طريقةٌ تستعمل لتتبع أو التبليغ عن العلل، أو لطلب ميزات جديدة لتضاف إلى البرنامج. توفِّر خدمات استضافة مستودعات المشاريع مفتوحة المصدر مثل GitHub و GitLab و Bitbucket طرائق لتتبع القضايا التي تُنشِئها وتسمح للمستخدمين بإنشائها. فمن المتوقع عند إطلاق مشروعك مفتوح المصدر أن تُفتَح عدِّة قضايا من قِبل مجتمع المستخدمين، لذا سيمثِّل تنظيم ووضع أولويات لهذه القضايا أمرًا مهمًا لتبيان خارطة الطريق لما عليك فعله للمشروع مستقبلًا. ولأنَّ أي مستخدم يستطيع أن يفتح قضية، فلن تكون جميع القضايا لتبليغ العلل أو لطلب الميزات، فقد تأتيك أسئلة عبرها، أو قد تأتي طلبات لتحسينات صغيرة على واجهة المستخدم مثلًا. فمن الأفضل تنظيم هذه القضايا في أفضل شكل ممكن ومحاولة التواصل مع المستخدمين الذين أنشؤوها. يجب أن تمثِّل القضايا مهامًا محددة عليك تنفيذها برمجيًا، لذا عليك تنظيمها حسب أهميتها. يجب أن يكون هنالك حدود للوقت والعمل الذي تنفقه أنت أو المساهمون في المشروع للقضايا المفتوحة فيه، ويمكنكم التعاون على اتخاذ القرارات والخروج بخطة قابلة للتنفيذ، وعندما تعلم أنَّك غير قادر على حل مشكلة معيّنة في الإطار الزمني المتاح لك، فيمكنك التعليق عليها وإخبار المستخدم أنَّك قرأت المشكلة وستفعل ما بوسعك تجاهها، وقد تستطيع أن تخبره بالوقت المتوقع للنظر في أمر هذه المشكلة مرةً أخرى. أما لطلبات الميزات أو التحسينات، فيمكنك أن تسأل الشخص الذي أنشأ القضية إن كان يستطيع المساهمة في الشيفرة لتطبيق هذه الميزة، يمكنك توجيه المستخدمين إلى ملف CONTRIBUTORS.md أو إلى أيّة صفحات أخرى من التوثيق. ولأن الأسئلة لا تمثِّل عادةً مهامًا محدَّدة، فالتعليق على السؤال لتوجيه المستخدم بلباقة إلى صفحة التوثيق هو خيارٌ ممتاز لإبقاء تفاعلك مع المستخدم احترافيًا ولطيفًا؛ وإذا لم يحتوي التوثيق على جوابٍ لهذا السؤال فحان الوقت لإضافة التوثيق الملائم، وتعبِّر عن شكرك للمستخدم لأنه دلّك على موضع النقص في التوثيق. إذا كنتَ تستقبل عددًا كبيرًا من الأسئلة عبر القضايا، فربما تفكر بإنشاء صفحة الأسئلة الشائعة (FAQ) في التوثيق، أو صفحات ويكي أو منتدى لتتيح للآخرين المساعدة والمشاركة في الإجابة عن الأسئلة. وفي كل مرة يبلِّغ فيها أحد المستخدمين عن مشكلة، فحاول أن تكون لطيفًا معه قدر الإمكان، فتفاعل المستخدمين معك يعني أنَّ المشروع قد أعجبهم ويريدون جعله أفضل. محاولة تنظيم القضايا ستجعل مشروعك محدثًا دومًا وسيشعر المستخدمون أنهم يأثرون فيه، لذا احذف القضايا التي تقع خارج نطاق مشروعك أو القضايا القديمة، وضع أولويات للبقية لكي يكون تقدمك في المشروع مستمرًا. حفِّز المساهمين كلما رحّبتَ بالمساهمين الجدد وكافأتهم على جهودهم لوجدت أنَّك تحفِّز مساهمين جدد ليشاركوا في مشروعك، ولكي تجذب المساهمين إلى المشروع فاحرص على تضمين ملف CONTRIBUTING.md في المجلد الرئيسي لمستودعك، وإشارة إلى ذاك الملف في README.md. إذا أردتَ كتابة ملف جيد للمساهمين الجدد فيجب أن يتضمن كيفية بدء العمل على المشروع كمطوِّر، فقد تكتب دليلًا يوضح ذلك خطوةً بخطوة، أو قائمةً من الأمور التي يجب على المطورين اتباعها وتنفيذها، شارحًا كيف يمكن أن يدمجوا الشيفرة التي كتبوها بشيفرة المشروع عبر طلبية pull. إضافةً إلى توثيق كيفية المساهمة في المشروع، فلا تنسَ أن تبقي شيفرات المشروع منظمة وسهلة القراءة، فإذا كانت الشيفرة سهلة الفهم وفيها تعليقات كثيرة تشرح ما تفعله وطريقة استخدامها موحدة ومتناسقة مع بعضها بعضًا فسيساهم ذلك في تحفيز المساهمين المحتملين على المشاركة في المشروع. أقترح أيضًا أن تبقي على قائمة بالمساهمين، فيمكنك أن تجذب المساهمين عبر إضافتهم إلى القائمة بغض النظر عن حجم مشاركتهم (حتى تصحيح الأخطاء اللغوية هو مشاركة ومساهمة فعالة في المشروع، ويمكن أن تؤدي إلى مزيدٍ من المساهمات مستقبلًا). وهذا يعني أنَّك تقدِّر عمل المساهمين في المشروع وتشير إليهم أمام جميع مستخدمي مشروعك، مما يحمِّس بقية المستخدمين على المشاركة. ابنِ مجتمعًا حول مشروعك بتمكين مستخدميك عبر التوثيق وبالتجاوب مع القضايا وبتحفيزهم للمشاركة، فأنت في طريقك لبناء مجتمع حول مشروعك المفتوح المصدر، فالمستخدمون السعيدون بتجاوبك معهم والذين تعدُّهم على أنهم مساهمون سيحاولون الترويج مشروعك ما استطاعوا. إضافةً إلى ما سبق، يمكنك الترويج لمشروعك بمختلف السبل: التدوين تسجيل ونشر فيديوهات تعريفية إنشاء قائمة بريدية النشاط على مواقع التواصل الاجتماعي التعاون مع المشاريع الشبيهة أو المتعلقة بمشروعك والترويج لها. عليك أن تُناسِب ترويجك للمشروع مع مجاله وعدد أعضاء الفريق الفعالين والمساهمين الذين يعملون معك. فعندما ينمو المجتمع حول مشروعك، فيمكنك أن توفِّر مساحة أكبر للمساهمين والمستخدمين والقائمين على المشروع ليتفاعلوا، بعض تلك الخيارات تتضمن: برمجيات الويكي التي توفِّر توثيقًا مصانًا من المجتمع المنتديات لمناقشة الميزات المحتملة وللإجابة على الأسئلة قائمة بريدية للتفاعل مع المجتمع عبر البريد الإلكتروني ضع ببالك قاعدة مستخدمي مشروعك ومجاله بما في ذلك عدد الأشخاص القائمين عليه والموارد المتاحة لك قبل أن تتوسّع في المجالات السابقة، واستشر مجتمعك عن الخيار الأفضل قبل الإقدام عليه. وأهم من ذلك كله أن تكون لطيفًا معهم وتريهم أنَّك تهتم بهم عبر تفاعلك معهم، أعلمُ أنَّ الاتسام بصفة اللباقة طوال الوقت ليس أمرًا سهلًا، لكن ستؤتي أُكلها على المدى البعيد. الخلاصة يلعب صائن المستودع دورًا مهمًا في مجتمع البرمجيات مفتوحة المصدر الكبير. وصحيحٌ أنَّ هذا الدور يأخذ وقتًا وعملًا كبيرًا، لكن الخبرة التي تكتسبها خلال هذا العمل ستفيدك كمطوِّر وكمساهم، ولا تنسَ أنَّ الصائن اللطيف واللبق سيساعد في دفع عجلة تطوير المشروع الذي يهتم لأجله. ترجمة –وبتصرّف– للمقال Maintaining Open-Source Software Projects لصاحبته Lisa Tagliaferri. حقوق الصورة البارزة محفوظة لـ Freepik
  4. إذا طبّقنا بضعة انتقالات (transitions) على عناصر الصفحة فقد تؤدي إلى نتيجة رائعة إذا خططنا لها جيدًا، وسنتعلم في هذا المقال كيف نستخدم الانتقالات لدب الحياة في محتوى الصفحة، وسنخطط ونبني تأثيرات مرور الفأرة فوق العناصر لتبدو بأجمل مظهر. الانتقالات أم الحركات الانتقالات (transitions) رائعة للانتقال بسلاسة من حالة إلى أخرى (والعودة إلى الحالة الأصلية مجددًا) في المتصفح، وقد تبدو أنها بديلٌ أبسط من الحركات (animation) التي تستعمل keyframes و animation، لكن لكلٍ ميزاتها وفوائدها. فمثلًا، لن تستفيد من الانتقالات إذا كنت تريد حدوث حركة عند تحميل الصفحة، أو إذا أردتَ أن تستمر الحركة طوال الوقت؛ أما إذا كانت لديك حالتين وأردتَ التحريك بينهما بسهولة فستستفيد حينئذٍ من الانتقالات. إذا كنتَ مهتمًا بالفروقات بين الانتقالات والحركات فأنصحك بمراجعة هذه المقالة. سنبني في هذا الدرس مشهدًا من الفضاء وسنضيف إليه تأثير مرور الفأرة فوقه لعرض بعض المعلومات الإضافية عن الكوكب، وسنفِّكر بحالتَي العناصر وما هي الخاصيات التي سنستخدمها للحصول على انتقال سلس وجميل. يمكنك الاطلاع على المثال الكامل لأخذ فكرة عن ما سنفعله. See the Pen &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh/pen/qmNgXW/&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh/pen/qmNgXW/&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;Planet hover effect part 3: with transition&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; by Donovan Hutchinson (&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;@donovanh&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;) on &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;CodePen&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;. ضبط الحالتين أكثر الأمور التي تأخذ وقتًا وجهدًا عند إنشاء الانتقالات هي الحالة الأولية والحالة النهائية للعنصر، فيجب أن نُفكِّر كيف سيبدو العنصر قبل تطبيق الانتقال وماذا يجب أن يتغيّر في مظهره بعد حدوث الانتقال. عندما أُنشِئ الانتقالات المعقدة نسبيًا فلا أهتم بالحركة نفسها إلى أن يعجبني مظهر العناصر في الحالتين، ومن هذا المنطلق فسنهتم بالخاصيات التي سنستخدمها في حالة hover لأن هذه الخاصيات ستخضع إلى حركة. قبل الخوض في موضوع الانتقالات فلنضبط الحالتين أولًا. حالة البداية سيكون كوكب الأرض في منتصف المشهد بدايةً، وسيدور القمر حوله. شيفرة HTML تتضمن عنصر article الذي نضع فيه عنصرَي earth و moon، لاحظ أنَّ عنصر moon موجود داخل حاوية باسم moon-container لأنها ستساعدنا بموضع القمر لاحقًا. <article class="earth-demo"> <div class="earth"> <img src="https://cssanimation.rocks/images/random/earth.png"> </div> <div class="moon-container"> <div class="moon"> <img src="https://cssanimation.rocks/images/random/moon.png"> </div> </div> </article> هذه هي أنماط CSS التي سنستخدمها، سنجعل موضع العنصر earth مساويًا للقيمة absolute وسنستخدم الدالة calc لتوسيط الأرض رأسيًا وأفقيًا. .earth { position: absolute; top: calc(50% - 100px); left: calc(50% - 100px); } وسنُحدِّد موضع الصورة ونعطيها طولًا وعرضًا: .earth img { height: 200px; position: absolute; top: 0; left: 0; width: 200px; } وسنفعل المثل تقريبًا للقمر، إذ سنبدأ بوضع الحاوية في منتصف الشاشة: .moon-container { position: absolute; top: calc(50% - 25px); left: calc(50% - 25px); } ثم سنضبط أبعاد القمر ونُطبِّق الحركة spin عليه (والتي سنعرِّفها لاحقًا)، وهذا ما سيجعل القمر يدور حول الأرض. .moon { animation: spin 20s linear infinite; background: none; height: 50px; pointer-events: none; transform-origin: 25px; width: 50px; } عند هذه المرحلة سيكون القمر متموضعًا في منتصف الشاشة وفوق الأرض، لذا لنستخدم الخاصية transform لتحريك القمر إلى خارج الحاوية الخاصة بعيدًا عن الأرض. .moon img { height: 50px; transform: translateX(-160px) translateY(-160px); width: 50px; } هذا يعني أنَّ عنصر moon سيدور فوق الأرض، لكن الصورة ستدور حول الأرض. لنضف الآن حواف مدورة للعنصر لكي تظهر حواف الأرض والقمر بدقة وسنستعمل الخاصية box-shadow لإعطائهما توهجًا أزرقًا: .earth img, .moon img { border-radius: 50%; box-shadow: 0 0 12em 1em rgba(110, 140, 200, .6); } في النهاية، سنُعرِّف الحركة spin لتدوير القمر، وهذه الحركة بسيطة، إذ سندوِّر القمر حول المحور Z بزاوية 360 درجة. @keyframes spin { to { transform: rotateZ(360deg); } } هذا هو ناتج هذه المرحلة: See the Pen &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh/pen/aWZPeP/&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh/pen/aWZPeP/&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;Planet hover effect part 1: initial stage&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; by Donovan Hutchinson (&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;@donovanh&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;) on &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;CodePen&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;. عرض المزيد من المعلومات نريد أن نظهر معلومات مفيدة حول كوكب الأرض عند مرور الفأرة فوقه، ربما ستساعد هذه المعلومات الفضائيين في معرفة بعض الأمور الأساسية عن كوكبنا قبل أن يزورونا :-) . علينا قبل ضبط حالة hover أن نضيف هذه المعلومات، وسنبدأ بإضافة عنصر div ذي المعرِّف more-info الذي يحتوي على بعض النصوص: <article class="earth-demo"> <div class="earth"> <div class="more-info"> <h1>Earth</h1> <ul> <li>Third planet from the Sun</li> <li>Atmosphere: 21% oxygen</li> <li>Liquid water on surface</li> <li>Only planet that has life (that we know of)</li> </ul> </div> <img src="https://cssanimation.rocks/images/random/earth.png"> </div> <div class="moon-container"> <div class="moon"> <img src="https://cssanimation.rocks/images/random/moon.png"> </div> </div> </article> أضفنا هذه المعلومات داخل حاوية earth لأننا نريد جعلها جزءًا من التأثير، أي عند مرور الفأرة فوق النص فسيبقى على الشاشة. سنضيف بعض أنماط CSS إلى عنصر more-info: .earth .more-info { background-image: linear-gradient(to bottom, rgba(10,10,10,1), black); border-radius: 1em; color: #fff; opacity: 0; padding: 1em; transform-origin: 0 0; transform: scale(.8); width: 400px; } .earth .more-info h1 { margin: 0 0 1em; text-align: right; } ضبطنا هنا لون الخلفية والحواف المنحنية والحاشية وعرض العنصر، وغيّرنا قياسه قليلًا باستخدام transform وضبطنا transform-origin إلى الزاوية العليا اليسرى لكي يتغيّر قياسه بدءًا من تلك النقطة. خاصية opacity للعنصر more-info تساوي الصفر أي أنَّ العنصر شفاف تمامًا ولن يكون مرئيًا، وقد نضيف الخاصية visibility لكي نضمن أنَّ المحتوى لا يتداخل مع بقية العناصر، لكننا لن نفعل ذلك في مثالنا هذا. إنشاء انتقال للخاصيات المطلوبة عندما نضبط تأثير الانتقال فمن المهم أن نأخذ الأداء بالحسبان، فبعض الخاصيات مثل الارتفاع والحاشية (padding) وحجم الخط و background-position لن يكون أداؤها جيدًا إذا أجرينا تأثير الانتقال عليها، والسبب وراء ذلك هو أنَّها تجعل المتصفح يُعيد حساب الكثير من التفاصيل في تخطيط الصفحة عندما تتغير. لذا من الأفضل استخدام الخاصيتين opacity و transform عند إجراء حركات لأن أداءها جيد ولا تسبب «تعليق» في المتصفح. سنستخدم في هذا المثال الخاصيتين opacity و transform إذ سيُصغَّر العنصر more-info قليلًا باستخدام transform وكان شفافًا تمامًا (قيمة opacity تساوي الصفر). أما في حالة hover فسنغيّر شفافية العنصر more-info لكي يصبح مرئيًا وسنزيح الكوكب إلى الجانب. حالة مرور الفأرة فوق العناصر لنبدأ بضبط حالة ‎.earth:hover، إذا كنتَ ستستخدم Sass فيمكنك اختصار الكثير من الشيفرات التي سنكتبها، لكنني سأستخدم CSS في هذا الدرس. لنحرِّك الكوكب جانبًا بادئ الأمر: .earth:hover img { transform: translateX(-75px) translateY(-75px) scale(.5); } خاصية transform السابقة ستدفع الكوكب إلى اليسار بمقدار 75 بكسل وستصغره إلى 50% من حجمه. لنقم بشيءٍ مشابه إلى القمر: .earth:hover ~ .moon-container { transform: translateX(-75px) translateY(-75px) scale(.5); } .earth:hover ~ .moon-container img { transform: translateX(-140px) translateY(-140px); } نفّذنا خدعةً هنا إلى صورة القمر ألا وهي استخدام transform لتقريبه إلى الأرض. لنُظهِر الآن العنصر more-info: .earth:hover .more-info { opacity: 1; transform: none; } ضبطنا الشفافية إلى 1 وهذا يعني أنَّ العنصر أصبح ظاهرًا، وضبطنا الخاصية transform إلى none وهذا يعني أنَّ العنصر سيعود إلى حجمه الطبيعي. هذه هي النتيجة الحالية، مرر الفأرة فوق الكوكب لتشاهد مربع المعلومات. See the Pen &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh/pen/bWezpR/&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh/pen/bWezpR/&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;Planet hover effect part 2: basic hover effect&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; by Donovan Hutchinson (&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;@donovanh&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;) on &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io&amp;amp;amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;CodePen&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;. تطبيق تأثير الانتقال لقد أنجزنا الأمور الصعبة، وكل ما بقي علينا لنفعل هو إخبار المتصفح كيف سيتنقل بين الحالتين. ولحسن الحظ لن نحتاج إلى كتابة شيفرات طويلة، وإنما يمكن فعل ذلك بخاصية CSS وحيدة: .earth-demo * { transition: all 4s cubic-bezier(0,1.5,.3,1); } لنشرح القاعدة السابقة بالتفصيل. تُطبَّق القاعدة السابقة على كل العناصر الموجودة داخل عنصر earth-demo (وذلك باستخدام رمز النجمة *). ثم سنطبِّق تأثير الانتقال transition لجميع الخاصيات بمدة 4 ثواني وباستخدام دالة التوقيت cubic-bezier، وهذه الدالة ستبدأ بسرعة ثم تتباطأ حتى النهاية، وفي النهاية ستتخطى القيم المُحدَّدة في الحالة hover ثم ستعود إلى القيم التي ضبطناها. وقبل أن ننظر إلى النتيجة النهائية، فدعنا نضيف تأخيرًا بسيطًا إلى عناصر القائمة، فمن الجميل أن تظهر عناصر القائمة تلو بعضها بتأثيرٍ حركيٍ جميل. يمكننا فعل ذلك باستخدام الخاصية transition-delay. تأخير تأثير الانتقال سنضبط بدايةً شفافية تلك العناصر إلى الصفر، أي سيكونوا غير مرئيين قبل أن يبدأ تأثير الانتقال. .earth-demo h1, li { opacity: 0; } وعندما يبدأ الحدث hover فسنُظهرهم جميعًا: .earth-demo:hover h1, li { opacity: 0; } علينا الآن تأثير ظهور عناصر القائمة الأربعة، وذلك باستخدام المُحدِّد nth-child: .earth-demo:hover li:nth-child(1) { transition-delay: 0s; } .earth-demo:hover li:nth-child(2) { transition-delay: 0.2s; } .earth-demo:hover li:nth-child(3) { transition-delay: 0.4s; } .earth-demo:hover li:nth-child(4) { transition-delay: 0.6s; } الشيفرة السابقة ستُضيف تأخيرًا إلى كل عنصرٍ من عناصر القائمة، ولأننا استخدمنا المُحدِّد * فيما سبق فهذا يعني أنَّ كل عنصر من هذه العناصر سيُطبَّق عليه تأثير الانتقال، وكل ما علينا تحديده هو زمن التأخير. هذه هي النتيجة النهائية: See the Pen &amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh/pen/qmNgXW/&amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh/pen/qmNgXW/&amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;gt;Planet hover effect part 3: with transition&amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;gt; by Donovan Hutchinson (&amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh&amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io/donovanh&amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;gt;@donovanh&amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;gt;) on &amp;amp;amp;amp;amp;amp;amp;amp;lt;a data-cke-saved-href=&amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io&amp;amp;amp;amp;amp;amp;amp;#39; href=&amp;amp;amp;amp;amp;amp;amp;#39;https://codepen.io&amp;amp;amp;amp;amp;amp;amp;#39;&amp;amp;amp;amp;amp;amp;amp;amp;gt;CodePen&amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;gt;. لقد فعلناها! حركة معقدة نسبيًا أنجزناها باستخدام خاصية transition وحيدة. تعلمنا في هذا الدرس كيف نخطط ونبني مثالًا متكاملًا يستخدم الانتقالات لإنشاء حركات معقدة، وحرصنا أن تكون الانتقالات سلسلة وتبدو بشكلٍ جميل. الخلاصة الخدع البسيطة التي نقوم بها عبر الحركات والانتقالات هي التي تجعل موقعنا مميزًا وجميلًا ترجمة –وبتصرّف– للمقال Transitions in space لصاحبه Donovan Hutchinson
  5. بروتوكول نقل الملفات FTP (اختصار للعبارة File Transfer Protocol) هو بروتوكول شبكي كان شائعًا جدًا فيما قد سلف لنقل الملفات بين الخادوم والعميل، لكن استبدلته الطرائق الأكثر أمانًا وسرعةً لنقل الملفات، فكثيرٌ من مستخدمي الإنترنت يتوقعون تنزيل الملفات مباشرةً من متصفح الويب عبر بروتوكول http (أو https)، أما مستخدمي سطر الأوامر فيستعملون بروتوكولات أكثر أمانًا مثل scp أو sFTP. لكن ما يزال بروتوكول FTP مستخدمًا في التطبيقات القديمة أو للحالات التي لها متطلبات خاصة، فلو كنتَ تستطيع اختيار ما هو البروتوكول الذي ستستخدمه، فأنصحك بالنظر في بقية الخيارات الحديثة؛ لكن إذا كنت تحتاج إلى استخدام FTP فخادوم vsftpd هو خيارٌ ممتازٌ إذ إنَّ أداءه ممتاز وآمن ومستقر، ويوفِّر قدرًا كبيرًا من الحماية ضد كثيرٍ من المشاكل الأمنية الموجودة في خودايم FTP الأخرى، إضافةً إلى أنه الخادوم الافتراضي لخدمة FTP للعديد من توزيعات لينكس. سنتعلم في هذا الدرس كيفية ضبط خادوم vsftpd للسماح للمستخدمين برفع ملفاتهم إلى مجلد المنزل الخاص بهم باستخدام بروتوكول FTP مع تأمين معلومات الدخول عبر تشفير SSL/TLS. المتطلبات المسبقة خادوم أوبنتو 16.04 مع وصول إلى مستخدم يملك امتيازات الجذر عبر الأمر sudo: إذ سنُطبِّق الأوامر المذكورة في هذا الدرس عبر مستخدمٍ ليس جذرًا لكنه يمتلك امتيازات الجذر عبر الأمر sudo. يمكنك إنشاء مستخدم له امتيازات الجذر باستخدام الأمر sudo باتباع درس «الإعداد الابتدائي لخادوم أوبنتو 14.04](https://academy.hsoub.com/devops/servers/الإعداد-الابتدائي-لخادوم-أوبنتو-1404-r4/)». يمكننا أن نبدأ بتطبيق هذا الدرس بعد أن يكون الخادوم جاهزًا. الخطوة الأولى: تثبيت vsftpd سنبدأ بتحديث فهرس الحزم في خادومنا ثم تثبيت خادوم vsftpd: sudo apt-get update sudo apt-get install vsftpd عند إكمال التثبيت، فسننسخ ملف الضبط الافتراضي لنأخذ نسخةً احتياطيةً منه، ولنعدِّل الضبط كما نشاء. sudo cp /etc/vsftpd.conf{,.orig} بعد أن أخذنا نسخةً احتياطيةً من ملف الضبط، فحان الوقت الآن لإعداد الجدار الناري. الخطوة الثانية: فتح المنافذ الضرورية في الجدار الناري سنتحقق أولًا من حالة الجدار الناري لنرى إن كان مفعلًا أم لا، فإذا كان مفعلًا فعلينا السماح باتصالات FTP عبره لكي لا نواجه مشاكل عندما نجرِّب الخادوم. sudo ufw status نجد من الناتج الآتي أنَّ خدمة SSH مسموحٌ لها فقط: Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) لاحظ أنَّ الناتج قد يكون مختلفًا عندك، فقد لا توجد أيّة قواعد لجدارك الناري أو لديك قواعد إضافية. ولمّا كان الجدار الناري لا يسمح إلا لاتصالات SSH فعلينا إضافة قواعد للسماح لاتصالات FTP، وسنحتاج إلى فتح المنفذين 20 و 21 لخدمة FTP، والمنفذ 990 لنستعمله لاحقًا عندما نضبط تشفير TLS، والمنافذ من 40000 إلى 50000 كمنافذ غير المباشرة (passive ports) التي نخطط لضبطها لاحقًا في ملف الضبط: sudo ufw allow 20/tcp sudo ufw allow 21/tcp sudo ufw allow 990/tcp sudo ufw allow 40000:50000/tcp sudo ufw status يجب أن تبدو قواعد الجدار الناري كما يلي: Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 990/tcp ALLOW Anywhere 20/tcp ALLOW Anywhere 21/tcp ALLOW Anywhere 40000:50000/tcp ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 20/tcp (v6) ALLOW Anywhere (v6) 21/tcp (v6) ALLOW Anywhere (v6) 990/tcp (v6) ALLOW Anywhere (v6) 40000:50000/tcp (v6) ALLOW Anywhere (v6) يمكننا الانتقال إلى الخطوة التالية بعد تثبيتنا لخادوم vsftpd وفتح المنافذ الضرورية. الخطوة الثالثة: تهيئة مجلد المنزل للمستخدم سنُنشِئ في هذا الدرس مستخدمًا جديدًا، لكن قد يكون لديك مستخدم موجود في نظامك ويحتاج إلى وصول FTP، وسنحرص على الحفاظ على وصول المستخدم إلى بياناته، لكن مع ذلك أنصحك بإنشاء مستخدم جديد إلى أن تضبط الخادوم وتجرّبه. سنُنشِئ بدايةً مستخدمًا جديدًا للتجربة: sudo adduser sammy أسنِد كلمة المرور إلى الحساب عند طلبها، ويمكنك تجاهل بقية الأسئلة بالضغط على زر Enter. تكون خدمة FTP أكثر أمانًا إذا كان المستخدمون محدودين بمجلدٍ معيّن، ويمكن لخادوم vsftpd فعل ذلك باستخدام chroot، فعند تفعيل chroot للمستخدمين المحليين، فلن يسمح لهم بالوصول إلى شيءٍ خارج مجلد المنزل الخاص بهم افتراضيًا، لكن خادوم vsftpd يحاول تأمين المجلد بعدم السماح بالكتابة عليه من قبل المستخدم (عبر سطر الأوامر)، ولا بأس بذلك للمستخدمين الجدد الذين يجب أن يتصلوا عبر FTP فقط، لكن إذا كان لدينا مستخدم موجود مسبقًا ويجب أن يستطيع الكتابة إلى مجلد المنزل الخاص به عبر سطر الأوامر فهذا لن يكون مناسبًا أبدًا. وبدلًا من إزالة إذن الكتابة من مجلد المنزل، فسنُنشِئ مجلد ftp لكي يكون chroot وسنُنشِئ داخله مجلد files يمكن الكتابة عليه ليحتوي على الملفات. لنُنشِئ مجلد ftp ونضبط ملكيته ونحذف إذن الكتابة منه بالأوامر الآتية: sudo mkdir /home/sammy/ftp sudo chown nobody:nogroup /home/sammy/ftp sudo chmod a-w /home/sammy/ftp لنتأكد من الأذونات: sudo ls -la /home/sammy/ftp الناتج: total 8 4 dr-xr-xr-x 2 nobody nogroup 4096 Aug 24 21:29 . 4 drwxr-xr-x 3 sammy sammy 4096 Aug 24 21:29 .. لنُنشِئ الآن المجلد الذي يحتوي على الملفات التي ستُرفَع ونضبط ملكيته إلى المستخدم: sudo mkdir /home/sammy/ftp/files sudo chown sammy:sammy /home/sammy/ftp/files لنتحقق أيضًا من أذونات المجلد files: sudo ls -la /home/sammy/ftp الناتج: total 12 dr-xr-xr-x 3 nobody nogroup 4096 Aug 26 14:01 . drwxr-xr-x 3 sammy sammy 4096 Aug 26 13:59 .. drwxr-xr-x 2 sammy sammy 4096 Aug 26 14:01 files وفي النهاية، لنضف ملفًا باسم test.txt لكي نستخدمه عند التجربة لاحقًا: echo "vsftpd test file" | sudo tee /home/sammy/ftp/files/test.txt بعد أن أصبح مجلد ftp آمنًا، وأعطينا المستخدم الأذونات اللازمة على مجلد files، فيمكننا الاهتمام الآن بموضوع الضبط. الخطوة الرابعة: ضبط وصول FTP خطتنا هي السماح للمستخدم الذي يملك وصولًا محليًا إلى سطر الأوامر بالاتصال عبر FTP، وهنالك خيارا ضبط رئيسيان مضبوطان في ملف vsftpd.conf. لنبدأ أولًا بفتح ملف الضبط للتأكد أنَّ التعليمات المذكورة فيه تُطابِق ما يلي: sudo nano /etc/vsftpd.conf محتوى الملف: . . . # Allow anonymous FTP? (Disabled by default). anonymous_enable=NO # # Uncomment this to allow local users to log in. local_enable=YES . . . علينا الآن تغيير بعض القيم في الملف، ولكي نسمح للمستخدم برفع الملفات فسنزيل رمز التعليق قبل التعليمة write_enable لكي يصبح السطر كما يلي: . . . write_enable=YES . . . سنُزيل رمز التعليق قبل التعليمة chroot_local_user لمنع المستخدم الذي يتصل عبر FTP من الوصول إلى أيّة ملفات خارج المجلد المضبوط: . . . chroot_local_user=YES . . . علينا إضافة التعليمة user_sub_token لكي نستطيع وضع اسم المستخدم في مسار local_root، وهذا لكي يعمل الضبط دون مشاكل لهذا المستخدم ولأي مستخدم آخر قد نضيفه مستقبلًا: user_sub_token=$USER local_root=/home/$USER/ftp سنُحدِّد مجال المنافذ المستخدم لاتصالات FTP غير المباشرة (passive FTP) لكي نحرص على توافر اتصالات كافية: pasv_min_port=40000 pasv_max_port=50000 تذكر أننا فتحنا هذه المنافذ سابقًا في الجدار الناري، أي لو استخدمتَ مجالًا مختلفًا عمّا سبق فاحرص على تحديث ضبط الجدار الناري بما يتوافق مع ذلك. ولأننا نخطط للسماح بوصول إلى FTP لمستخدمين معينين، فسنعدِّل في الضبط لكي نسمح بالوصول إلى قائمة معيّنة من المستخدمين: userlist_enable=YES userlist_file=/etc/vsftpd.userlist userlist_deny=NO التعليمة userlist_deny تُحدِّد ما الذي يجب فعله مع المستخدمين المذكورين في القائمة، فلو ضُبِطَت إلى YES فسيمنعون من الوصول إلى FTP، وإذا كانت NO فلن يسمح بالوصول إلى FTP إلا للمستخدمين المذكورين في القائمة. بعد أن تنتهي من إضافة الأسطر السابق فاحفظ الملف واخرج من المحرر النصي. علينا الآن إنشاء ملف القائمة وإضافة اسم المستخدم إليه، يمكننا استخدام الخيار ‎-a الخاص بالأمر tee لإسناد السطر إلى نهاية الملف: echo "sammy" | sudo tee -a /etc/vsftpd.userlist لنتأكد من محتوى الملف: cat /etc/vsftpd.userlist الناتج: sammy أعد تشغيل الخادوم لتطبيق التغييرات التي أجريناها في ملف الضبط: sudo systemctl restart vsftpd نحن جاهزون الآن للتجربة. الخطوة الخامسة: تجربة الوصول إلى FTP ضبطنا الخادوم للسماح للمستخدم sammy فقط بالوصول إلى FTP، لنتأكد من صحة ذلك. يجب ألّا يُسمَح للاتصال من المستخدمين المجهولين (anonymous users)، إذ عطلنا ذلك في الضبط، وسنجرِّب ذلك بمحاولة الاتصال بشكل مجهول، فإذا كان ضبطنا صحيحٌ فيجب ألّا يسمح لنا بالوصول إلى الخادوم: ftp -p 203.0.113.0 الناتج: Connected to 203.0.113.0. 220 (vsFTPd 3.0.3) Name (203.0.113.0:default): anonymous 530 Permission denied. ftp: Login failed. Ftp> أغلِق الاتصال: bye يجب ألّا يتمكن أيّ مستخدمٍ عدا sammy من الاتصال: وسنتحقق من ذلك عبر وضع اسم المستخدم الذي يملك امتيازات الجذر، ويجب ألّا يُسمَح له أيضًا قبل أن يُطلَب منه إدخال كلمة المرور: ftp -p 203.0.113.0 الناتج: Connected to 203.0.113.0. 220 (vsFTPd 3.0.3) Name (203.0.113.0:default): sudo_user 530 Permission denied. ftp: Login failed. Ftp> أغلِق الاتصال: bye يجب أن يتمكن المستخدم sammy من الاتصال، ومن قراءة وكتابة الملفات، لذا لنجرِّب ذلك: ftp -p 203.0.113.0 الناتج: Connected to 203.0.113.0. 220 (vsFTPd 3.0.3) Name (203.0.113.0:default): sammy 331 Please specify the password. Password: your_user's_password 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. Ftp> سندخل إلى المجلد files، ثم سنستعمل الأمر get لنقل ملف التجربة الذي أنشأناه سابقًا إلى جهازنا المحلي: cd files get test.txt الناتج: 227 Entering Passive Mode (203,0,113,0,169,12). 150 Opening BINARY mode data connection for test.txt (16 bytes). 226 Transfer complete. 16 bytes received in 0.0101 seconds (1588 bytes/s) ftp> سنحاول الآن إعادة رفع الملف باسمٍ جديد للتأكد من إمكانية الكتابة على المجلد: put test.txt upload.txt الناتج: 227 Entering Passive Mode (203,0,113,0,164,71). 150 Ok to send data. 226 Transfer complete. 16 bytes sent in 0.000894 seconds (17897 bytes/s) أغلِق الاتصال: bye بعد أن تأكدنا أنَّ الخادوم يعمل كما ضبطناه، فيمكننا إتباع إجراءات إضافية لتأمين الخادوم. الخطوة السادسة: جعل عمليات النقل آمنة لما كان بروتوكول FTP لا يشفِّر أيّة بيانات عند نقلها، بما في ذلك معلومات المستخدم، فعلينا تفعيل تشفير SSL/TLS لتأمين تلك البيانات، وأوّل خطوة هي إنشاء شهادات SSL لاستخدامها مع vsftpd. سنستخدم openssl لإنشاء شهادة جديدة، ونستخدم الخيار ‎-days لجعلها صالحةً لمدة سنة، وسنضيف –في الأمر نفسه– مفتاح ‎2048-bit RSA خاص، ثم بإسناد القيمة ذاتها إلى الخيارين ‎-keyout و ‎-out فستكون الشهادة والمفتاح الخاص في الملف نفسه. هذا هو الأمر الذي سنُطبِّقه: sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem سيُطلَب منّا توفير معلومات عن الشهادة التي سنُنشِئها، ضع المعلومات الخاصة بك عند الإجابة عن الأسئلة: Generating a 2048 bit RSA private key ............................................................................+++ ...........+++ writing new private key to '/etc/ssl/private/vsftpd.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:NY Locality Name (eg, city) []:New York City Organization Name (eg, company) [Internet Widgits Pty Ltd]:Hsoub Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []: Email Address []: بعد أن أنشأنا الشهادات، فعلينا الآن تعديل ضبط vsftpd مجددًا: sudo nano /etc/vsftpd.conf ستجد قرب نهاية الملف سطرين يبدآن بالسابقة rsa_‎، أضف قبلهما رمز التعليق ليصبحا كما يلي: # rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem # rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key أضف السطرين الآتيين بعدهما، اللذان يشيران إلى الشهادة والمفتاح الخاص اللذين أنشأناهما سابقًا: rsa_cert_file=/etc/ssl/private/vsftpd.pem rsa_private_key_file=/etc/ssl/private/vsftpd.pem علينا الآن جعل استخدام SSL إجباريًا، مما يمنع العملاء غير القادرين على التعامل مع تشفير TLS من الاتصال بخادومنا، وهذا ضروري للحرص على تشفير جميع المعلومات المنقولة لكن قد يجبر المستخدم على تغيير عميل الاتصال. عدِّل قيمة التعليمة ssl_enable إلى YES: ssl_enable=YES أضف بعد ذلك الأسطر الآتية لمنع الاتصالات المجهولة عبر SSL، ولإجبار استخدام SSL لتسجيل الدخول ولنقل البيانات: allow_anon_ssl=NO force_local_data_ssl=YES force_local_logins_ssl=YES علينا ضبط الخادوم استخدام TLS بدلًا من SSL عبر إضافة الأسطر الآتية: ssl_tlsv1=YES ssl_sslv2=NO ssl_sslv3=NO علينا بعد ذلك إضافة تعليمتين إضافيتين، الأولى تسمح بعدم استخدام SSL عند إعادة استخدام الجلسة (session reuse) لأنها لا تعمل مع أغلبية عملاء FTP، وسنطلب استخدام حزم عالية التشفير، وهذا يعني أنَّ طول المفتاح أكبر أو يساوي 128 بت: require_ssl_reuse=NO ssl_ciphers=HIGH بعد أن تنتهي من التعديلات السابقة، فاحفظ الملف وأغلق المحرر. علينا الآن إعادة تشغيل الخادوم لتأخذ التعديلات مجراها: sudo systemctl restart vsftpd لم نعد نتمكن الآن من استخدام عميل FTP غير الآمن الذي يعمل من سطر الأوامر، فلو جربناه فسنشاهد الناتج الآتي: ftp -p 203.0.113.0 Connected to 203.0.113.0. 220 (vsFTPd 3.0.3) Name (203.0.113.0:default): sammy 530 Non-anonymous sessions must use encryption. ftp: Login failed. 421 Service not available, remote server has closed connection ftp> سنتحقق من الاتصال في الخطوة القادمة باستخدام عميل يدعم تشفير TLS. الخطوة السابعة: تجربة الاتصال عبر TLS باستخدام FileZilla أغلبية عملاء FTP الحديثين يدعمون تشفير TLS، وسنشرح كيفية الاتصال عبر عميل FileZilla لأنه يعمل على جميع أنظمة التشغيل؛ راجع توثيق عميلك المفضل لتعرف كيف يمكن الاتصال عبر TLS فيه. عندما تفتح برنامج FileZilla فسنجد أيقونة Site Manager تحت قائمة File مباشرةً، أي أنَّها أوّل أيقونة في الشريط العلوي. اضغط عليها: ستُفتَح نافذة جديدة، اضغط فيها على زر «New Site» في الركن السفلي الأيسر: ستجد ظهور «New site» تحت أيقونة «My Sites»، يمكنك تسمية الموقع الآن أو إعادة تسميته لاحقًا بالضغط على زر «Rename». عليك أن تملأ حقل «Host» بعنوان IP أو اسم نطاق الموقع، وعليك أن تختار «Require explicit FTP over TLS» في قائمة «Encryption» أما لخيار «Logon Type» فاختر «Ask for password»، ثم أدخِل اسم المستخدم في حقل «User»: اضغط على زر «Connect» في أسفل النافذة، وستُسأل عن كلمة مرور المستخدم: اضغط على «OK» لتتصل، يجب أن يكون اتصالك مع الخادوم مشفرًا بتشفير TLS/SSL. بعد أن تقبل الشهادة، فانقر نقرًا مزدوجًا على مجلد files واسحب الملف upload.txt وأفلته في القسم اليساري من البرنامج لكي تبدأ بتنزيله: بعد ذلك، يمكنك أن تنقر بالزر الأيمن على الملف المحلي وتعيد تسميته إلى upload-tls.txt وتسحبه مجددًا إلى الخادوم لكي ترفعه عليه. لقد تمكنا من تنزيل الملفات ورفعها بأمان مع تفعيل تشفير SSL/TLS. الخطوة الثامنة: تعديل الوصول إلى سطر الأوامر (خطوة اختيارية) إن لم تتمكن من استخدام تشفير TLS بسبب محدوديات العميل، فيمكنك تأمين الخادوم قليلًا بمنع مستخدم FTP من تسجيل الدخول إلى سطر الأوامر، إحدى الطرائق البسيطة لفعل ذلك هي إنشاء صدفة (shell) خاصة. أكرِّر أنَّ الخطوة السابقة لا توفِّر أيّ تشفير، وإنما الغرض منها هو تقليل الوصول إلى حسابات المستخدمين المسموح لهم بالاتصال عبر FTP فقط. علينا أولًا إنشاء ملف باسم ftponly في مجلد ‎/bin: sudo nano /bin/ftponly سنضيف الآن رسالةً تخبر المستخدم أنَّه ليس قادرًا على تسجيل الدخول، أضف ما يلي يلي إلى الملف: #!/bin/sh echo "This account is limited to FTP access only." عدِّل الأذونات لجعل الملف قابلًا للتنفيذ: sudo chmod a+x /bin/ftponly افتح الملف الذي يضم قائمةً بالصدفات (shells) الصالحة للاستخدام في النظام: sudo nano /etc/shells وأضف في نهاية الملف: . . . /bin/ftponly عدِّل الصدفة الافتراضية للمستخدم عبر الآمر الآتي: sudo usermod sammy -s /bin/ftponly جرِّب الآن تسجيل الدخول بحساب المستخدم sammy: ssh sammy@203.0.113.0 ستجد رسالةً شبيهةً بالرسالة الآتية: This account is limited to FTP access only. Connection to 203.0.113.0 closed. هذا يؤكد أنَّ المستخدم غير قادر على تسجيل الدخول إلى الخادوم عبر الأمر ssh، ويُسمَح له بالوصول إلى FTP فقط. الخلاصة لقد شرحنا في هذا الدرس كيفية ضبط خادوم FTP للمستخدمين الذين يملكون حسابًا محليًا على النظام، أما إذا أردتَ استخدام مصدر خارجي للاستيثاق، فيمكنك إلقاء نظرة على دعم خادوم vsftpd للمستخدمين الوهميين (virtual users). هنالك خياراتٌ واسعة لدعم استخدام PAM مما يجعلك قادرًا على إدارة المستخدمين في نظام استيثاق مختلف مثل LDAP أو Kerberos. ترجمة –وبتصرّف– للمقال How To Set Up vsftpd for a User’s Directory on Ubuntu 16.04لصاحبته Melissa Anderson
  6. هنالك الكثير من الواجهات البرمجية المبنية على JSON التي توفر وصولًا عبر دوال من جهة الخادوم فقط، فلو أردنا استخدام عميل JavaScript مع تلك الواجهات البرمجية الخارجية، فسنحتاج إلى ضبط خادومنا للوصول إلى تلك الواجهات البرمجية الخارجية ثم تخديم تلك البيانات عبر Ajax أو عبر نقطة نهاية (endpoint) خاصة بك. ولحسن الحظ، فعل ذلك سهلٌ جدًا في ووردبريس. سأريك في هذا الدرس كيفية الحصول على أجور الشحن عبر Easy Post API باستخدام نقطة نهاية في ووردبريس. لتبسيط هذا الدرس (وجعله قصيرًا) فسنرسل ستة معاملات (وهو عدد كاف لواجهة Easy Post البرمجية لإعادة أجور الشحن): عرض الطرد ارتفاع الطرد طول الطرد وزن الطرد كود Zip للمرسل كود Zip للمستقبل ضبط نقطة نهاية JSON أوّل خطوة هي ضبط المسار الذي ستُخدَّم منه بيانات JSON، وفي هذه الحالة هو: /wp-json/easy-post/v1/rates/ الشيفرة: /** * Sets up a JSON endpoint at /wp-json/easy-post/v1/rates/ */ function easy_post_api_init() { $namespace = 'easy-post/v1'; register_rest_route( $namespace, '/rates/', array( 'methods' => 'GET', 'callback' => 'easy_post_return_rates', ) ); } add_action( 'rest_api_init', 'easy_post_api_init' ); عرض البيانات تتوقع نقطة النهاية إرسال ست قيم من البيانات كطلبية، وستستخدمها للحصول على البيانات من الواجهة البرمجية الخارجية، فلو لم تكن تلك القيم موجودةً فستستعمل القيم الافتراضية، وسنحرص أن تكون تلك القيم رقميةً فقط. مثال عن رابط URL مع قيم لكل المعاملات: /wp-json/easy-post/v1/rates/?zip=78701&width=10&length=10&height=10&weight=10&shipping_zip=78751 الشيفرة: /** * عرض مخرجات Easy Post عبر النهاية الطرفية * * نستخدم القيم المبدئية في حال عدم ذكر بيانات في الطلب، إلا أن إعادة خطأ ربما تكون فكرة أفضل. * Valid URL: /wp-json/easy-post/v1/rates/?zip=78701&width=10&length=10&height=10&weight=10&shipping_zip=78751 */ function easy_post_return_rates( WP_REST_Request $request ) { // الإعدادات المبدئية للشحن $defaults = array( 'zip' => 78701, 'width' => 10, 'length' => 10, 'height' => 10, 'weight' => 16, 'shipping_zip' => 94105 ); // الحصول على المعطيات من الطلب $params = $request->get_query_params(); // التأكد من توفر جميع المعطيات $params = array_replace( $defaults, $params ); // تنظيف المفاتيح $params = array_map( "absint", $params ); // إنشاء قيم مفاتيح فريدة لتحديد قيم البيانات المؤقتة transient أو العثور عليها $key = 'easy_post_' . implode( "_", $params ); /** * نحتفظ بالإجابة في قيمة مؤقتة transient ضمن قاعدة بيانات ووردبريس * لتجنب إرسال الكثير من الطلبات في وقت قصير * * تنتهي صلاحية هذه البيانات بعد عشر دقائق */ if ( false === ( $data = get_transient( $key ) ) ) { $data = easy_post_make_request( $params ); $response = new WP_REST_Response( $data ); // التخبئة لمدة عشر دقائق set_transient( $key, $response, 60 * 10 ); } else { // إرجاع القيمة المخبّأة return get_transient( $key ); } return $response; } الحصول على البيانات الدالة easy_post_make_request()‎ هي الدالة التي تطلب البيانات من الواجهة البرمجية الخارجية، والغرض من أغلبية الشيفرات التي هنا هي تجهيز الطلبية ضمن مصفوفة يمكن لواجهة Easy Post البرمجية أن تعالجها: /** *العثور على البيانات من الواجهة البرمجية لـ Easy Post باستخدام الدالة wp_remote_post */ function easy_post_make_request( $params ) { $to_address = array( 'zip' => $params['shipping_zip'], 'country' => 'US' ); $from_address = array( 'zip' => $params['zip'], 'country' => 'US' ); $parcel = array( 'length' => $params['length'], 'width' => $params['width'], 'height' => $params['height'], 'weight' => $params['weight'] ); $request = array( 'shipment' => array( 'to_address' => $to_address, 'from_address' => $from_address, 'parcel' => $parcel ) ); $args = array( 'method' => 'POST', 'blocking' => true, 'headers' => array( 'Content-Type' => 'application/json' ), 'timeout' => 15, 'sslverify' => false, 'body' => json_encode( $request ) ); // ضع مفتاح API الخاص بك مكان EASYPOST_TEST_API_KEY $api_url = 'https://' . EASYPOST_TEST_API_KEY . ':@api.easypost.com/v2/shipments'; $response = wp_remote_post( $api_url, $args ); if ( ! is_wp_error( $response ) ) { $response = json_decode( $response['body'] ); } return $response; } استخدام البيانات عندما نحاول الوصول إلى نقطة النهاية التي أنشأناها، فإن بيانات JSON التي جلبناها من Easy Post ستظهر لنا: يمكنك الآن الحصول على أجور الشحن ديناميكيًا في موقعك باستخدام نقطة النهاية التي أنشأناها في هذا الدرس. يمكنك الاطلاع على كامل الشيفرة هنا. ترجمة –وبتصرّف– للمقال How to Set JSON Endpoints in WordPress to Access an External API لصاحبه Devin Price حقوق الصورة البارزة محفوظة لـ Freepik
  7. أعلم أنَّه ليس من السهل الاعتراف بالأخطاء التي تقوم بها، لكن الخطأ هو جزءٌ رئيسي من كل عمليات التعليم، بدءًا من التعلم كيفية المشي إلى تعلم لغة برمجة جديدة مثل بايثون. هذه قائمة بثلاثة أخطاء التي وقعتُ فيها أثناء تعلمي لبايثون، عرضتها هنا لكي يحاول مبرمجو بايثون الجدد تفاديها وعدم الوقوع فيها، وهذه الأخطاء أدت إلى حدوث مشاكل كبيرة أخذت من وقتي ساعات حتى حللتها. الخطأ الأول: استخدام أنواع البيانات القابلة للتغير كوسائط افتراضية عند تعريف الدالة لنقل أنَّ لديك دالة صغيرة التي تبحث عن روابط في الصفحة الحالية وتستطيع إضافتها إلى قائمة (list) معيّنة. def search_for_links(page, add_to=[]): new_links = page.search_for_links() add_to.extend(new_links) return add_to لا يبدو أنَّ هنالك أيّ خطأ في الدالة السابقة، وهذا صحيح، فهي تعمل لكن هنالك مشاكل فيها؛ فلو مررنا قائمةً (list) إلى المعامل add_to فستعمل كما يجب، لكن ماذا يحدث لو تركنا القيمة الافتراضية دون تعديل؟ جرِّب تنفيذ الشيفرة الآتية: def fn(var1, var2=[]): var2.append(var1) print var2 fn(3) fn(4) fn(5) ستتوقع رؤية الناتج الآتي: [3] [4] [5] لكنك ستُفاجأ بالناتج الآتي: [3] [3, 4] [3, 4, 5] لماذا؟! يمكنك أن تستنتج أن القائمة (list) نفسها ستستعمل في كل مرة، فعندما نكتب دالة مثل الدالة السابقة في بايثون فسيتم تهيئة القائمة (list) كجزءٍ من تعريف الدالة، أي أنها لن تُهيّئ كل مرة تُستدعى فيها الدالة، وهذا يعني أنَّ الدالة ستحتفظ بكائن القائمة نفسه مرارًا وتكرارًا، ما لم تُحدِّد قيمةً أخرى له: fn(3, [4]) الناتج: [4, 3] الناتج يماثل ما قد توقعناه. الطريقة الصحيحة لفعل ذلك هي: def fn(var1, var2=None): if not var2: var2 = [] var2.append(var1) لنعد كتابة الدالة السابقة: def search_for_links(page, add_to=None): if not add_to: add_to = [] new_links = page.search_for_links() add_to.extend(new_links) return add_to نقلنا عملية التهيئة من مكان تعريف الدالة إلى داخلها مما يعني أنَّ عملية التهيئة ستتم في كل مرة تُشغَّل فيها الدالة. لاحظ أنَّ ذلك ليس ضروريًا إذا كنتَ تستعمل أنواع بيانات غير قابلة للتعديل مثل tuple أو string أو int. وهذا يعني أنَّك تستطيع تعريف دالة كما في الدالة الآتية دون إمكانية حدوث أخطاء غير متوقعة: def func(message="my message"): print message الخطأ الثاني: استخدام أنواع البيانات القابلة للتعديل كمتغيرات في الأصناف هذا الخطأ شبيهٌ كثيرًا بالخطأ السابق. تمعّن في الشيفرة الآتية: class URLCatcher(object): urls = [] def add_url(self, url): self.urls.append(url) الشيفرة السابقة تبدو طبيعية جدًا، فلدينا كائن لتخزين روابط URL، وعند استدعائنا للدالة add_url فسنمرر إليها رابط URL لتخزِّنه، صحيح؟ لنجرِّبها: a = URLCatcher() a.add_url('http://www.google.') b = URLCatcher() b.add_url('http://www.bbc.co.') الناتج: b.urls ['http://www.google.com', 'http://www.bbc.co.uk'] a.urls ['http://www.google.com', 'http://www.bbc.co.uk'] ما هذا؟! لم نتوقع ذلك. إذ أنشأنا كائنين منفصلين a و b، وأسندنا رابطًا للكائن a مختلفًا عن رابط الكائن b، فكيف امتلك كلا الكائنين الرابطين نفسهما؟ اتضح أنَّ هذه المشكلة شبيهة جدًا بالمشكلة في المثال الأول، فقائمة (list) عناوين URL قد تمت تهيئتها عند تعريف الصنف (class)، وبالتالي أمست جميع الكائنات المُنشَأة من ذاك الصنف تستعمل القائمة نفسها. هنالك بعض الحالات التي نستفيد فيها من هذه الميزة، لكنها ستضرك في أغلبية الأوقات، فلو أردتَ تخزين بيانات كل كائن على حدة فيمكنك تعديل الشيفرة لتصبح كما يلي: class URLCatcher(object): def __init__(self): self.urls = [] def add_url(self, url): self.urls.append(url) أصبحت قائمة urls تُهيّئ عند إنشاء الكائن، وعندما نُنشِئ كائنين فستُهيّئ قائمتان منفصلتان. الخطأ الثالث: عملية إسناد قيم إلى نوع بيانات قابل للتعديل هذا الخطأ أربكني لفترة حتى فهمته، دعنا نستعمل نوع بيانات قابل للتعديل مثل dict: a = {'1': "one", '2': 'two'} لنفترض أننا نريد أخذ قيمة المتغير a واستعمالها في مكانٍ آخر دون تعديل القيمة الأصلية: b = a b['3'] = 'three' أليس هذا بسيطًا؟ لننظر الآن إلى القيمة المخزّنة في المتغير a التي لم نُعدِّلها قط: {'1': "one", '2': 'two', '3': 'three'} ماذا؟! كيف ستبدو قيمة المتغير b إذًا؟ {'1': "one", '2': 'two', '3': 'three'} دعنا نعود خطوةً إلى الوراء وننظر ماذا يحدث لو استعملنا أنواع البيانات غير القابلة للتعديل، مثل tuple: c = (2, 3) d = c d = (4, 5) قيمة c هي: (2, 3) بينما قيمة d هي: (4, 5) لقد جرى كل شيءٍ على ما يرام، لذا ماذا حدث في مثالنا؟ عند استخدام أنواع البيانات القابلة للتعديل فسنحصل على شيءٍ شبيهٍ بالمؤشرات (pointers) في لغة C، فعندما قلنا أنَّ b = a في الشيفرة السابقة فهذا يعني أنَّ المتغير b أصبح يُشير إلى a، وكلا المتغيرين يشير إلى نفس الكائن في ذاكرة بايثون؟ هل هذا مألوف لديك؟ ذلك لأن هذه المشكلة شبيهة بالمشاكل السابقة، وكنتُ أنوي تسمية هذا الدرس باسم «المشاكل التي تحدث مع أنواع البيانات القابلة للتعديل». هل يحدث الأمر نفسه مع القوائم (list)؟ نعم. وكيف سنلتف على المشكلة؟ حسنًا، يجب أن نكتب الشيفرة الآتية التي تنسخ القائمة: b = a[:] السطر السابق سيؤدي إلى نسخ مرجعية كل عنصر من عناصر القائمة ووضعه في قائمة جديدة، لكن لنأخذ حِذرنا فإذا كان نوع بيانات أحد الكائنات الموجودة في القائمة قابلًا للتعديل فسيؤدي ذلك إلى الحصول إلى مرجعية لتلك الكائنات بدلًا من نسخها. تخيل وجود قائمة على قطعة من الورق، ففي المثال الأصلي كان ينظر الشخص A والشخص B إلى الورقة نفسها، فلو عدّل شخصٌ ما القائمةَ فسيرى كلا الشخصين التعديلات التي أجريت على القائمة، وعندما نسخنا المرجعيات فأصبح لكل شخصٍ قائمته الخاصة به، لكن لنفترض أنَّ تلك القائمة تحتوي على أماكن يمكن البحث فيها عن طعام، فلو كانت «الثلاجة» موجودة في القائمة فحتى لو نسخها الشخص A و B فما تزال تشير إلى الثلاجة نفسها؛ فلو أتى الشخص A وعدّل محتويات الثلاثة (لنفترض أنه أكل جميع الحلويات فيها) فسيلاحظ الشخص B أن الحلويات قد اختفت من الثلاثة. ولا توجد طريقة سهلة للالتفاف على هذه المشكلة، وهذا أمرٌ مهمٌ عليك تذكره عندما تبرمج لكي تكتب شيفرتك بطريقة لا تسبِّب أيّة مشاكل. تعمل أنواع dict بنفس الطريقة، ويمكنك إنشاء نسخة كاملة باستعمال الدالة copy()‎: b = a.copy() أكرِّر أنَّ ذلك سيُنشِئ متغيرًا جديدًا من نوع dict يُشير إلى نفس العناصر الموجودة في المتغير الأصلي، وبالتالي لو كان لدينا قائمتان متماثلتين وعدّلنا كائنًا قابلًا للتعديل مُشار إليه عبر مفتاح موجود في المتغير a فيمكن معرفة تلك التعديلات من داخل المتغير b. الإشكاليات التي تواجهنا مع أنواع البيانات القابلة للتعديل تكون نتيجةً لمرونة تلك الأنواع، حيث لا تُشكِّل أيٌّ مما سبق مشكلةً حقيقة، وإنما هي أمور ضرورية يجب أخذها بالحسبان لتنجب المشاكل. وعمليات النسخ الكاملة التي ذكرناها آنفًا لن تكون ضروريةً في 99% من الحالات، أي يجب تعديل برنامجك لكي لا يحتاج إلى استخدام تلك النسخ من الأساس. ترجمة –وبتصرّف– للمقال ‎3 mistakes to avoid when learning to code in Python لصاحبه Pete Savage
  8. التدوين الصوتي هو طريقةٌ رائعةٌ لمشاركة المعلومات وبناء المجتمعات التي تتشارك بالاهتمامات، وهذا الدرس يمثِّل دليلًا لكيفية البدء بالتدوين الصوتي. السبب الرئيسي وراء قدرتي على إعطاء نصائح بالتدوين الصوتي هو أنني أدوِّن صوتيًا لما يقارب ثلاث سنوات. مدونتي الصوتية باسم Sysadministrivia تتضمن كلامًا عن إدارة الأنظمة. ما هو التدوين الصوتي؟ انتشر التدوين الصوتي انتشارًا كبيرًا في مختلف المجالات وأصبح شائعًا جدًا، إذ ينشر بعض الأشخاص تدوينات صوتية لمختلف جوانب حياتهم مثل جلسات الألعاب الإلكترونية التي يلعبونها. يعمل التدوين الصوتي بتسجيلك للصوت (أو الفيديو لأن البرمجيات قد تطورت حديثًا)، واستخدام صيغة بيانات قياسية لتنبيه المستمعين أنَّك نشرت التدوينة الصوتية podcast مباشرةً. صيغة RSS (المسؤولة عن إذاعة خبر نشر التدوينة) ومواصفة XML معينة (وهي صيغة البيانات القياسية) تجعل إنشاء هذه التنبيهات التلقائية أمرًا ممكنًا. كيف أستطيع البدء بالتدوين الصوتي؟ كل ما يلزمك هو حاسوب ونظام تشغيل. فمن البدهي أنَّك تحتاج إلى حاسوب، ولا يهم ما هو نظام تشغيلك، لكنني أنصحك باستخدام لينكس أو نظام من عائلة BSD. برمجيات تسجيل وتحرير الصوت يمكنك استخدام برمجيات متعددة المنصات (أي تعمل على أكثر من نظام تشغيل) لتسجيل الصوت مثل Audacity أو إذا كنتَ تفضِّل تحكمًا أكثر فانظر إلى Ardour. تحتوي صفحة hosts في موقع Sysadministrivia على قائمة بمواصفات العتاد التي نستعملها في التدوين (بما في ذلك الميكروفون والسماعات الرأسية والمعدات الأخرى)؛ لا أنصحك بشراء عتاد معيّن إذ هنالك مختلف أنواع الميكروفونات لتسجيل الكلام. سنحتاج إلى ميكروفون على شكل قلب (cardioid أو supercardioid) إذا كنت ستتحدث بالقرب من الميكروفون ، أو استخدام ميكروفون أحادي الاتجاه (omnidirectional) إذا أردتَ تسجيل ما يدور في غرفة مليئة بالأشخاص باستعمال ميكروفون وحيد، واحرص على أن تكون تلك الميكروفونات ذات مكثّف (condenser) لأنها أفضل لتسجيل الحديث، وسماعات الرأس ضرورية إذا كنت ستدون مع شخص آخر ليس في غرفتك نفسها. لمزيدٍ من المعلومات حول ذلك فأنصحك بقراءة قسم «Uploading» في التدوينة How to run your own podcast. استضافة الموقع ستحتاج إلى استضافة لتضع فيها الملفات الصوتية وملف XML الذي سيذيع خبر نشر التدوينات الجديدة، وموقع إلكتروني (ليس من الضروري امتلاك موقع، لكنني أنصحك بذلك بشدة). يمكنك بشكلٍ بديل أن ترفع الملفات الصوتية (أو الفيديو) إلى خدمة مثل YouTube أو SoundCloud واستخدام ميزة الاشتراك فيها لنشر خبر صدور صدور تدوينة جديدة؛ لكن دون استخدام RSS (أو XML) فهذا يعني أنَّ تدويناتك ليست تدوينات صوتية (podcast) تقنيًا، لأن هذه المواقع تطلب من مستخدميك أن يسجلوا حسابًا فيها، والتدوينات الصوتية يجب أن تسمح للمستمعين أن يبقوا مجهولين تمامًا. صيغة الملفات حسنًا، التدوينات الصوتية ليست «حرة» تمامًا، لاستخدام صيغة MPEG-1/2 Audio Layer III المعروفة باسمها المختصر MP3. هذه الصيغة محمية ببراءة اختراع ولا تتوافق مع مبادئ البرمجيات الحرة؛ لكن يمكن استخدام صيغة بديلة عنها وهي OGG لكنها ستجعل نشرك لها محدودًا، إلا أنَّ بإمكانك توفير تدوينة صوتية podcast و oggcast، وصيغة ملفات XML لهما متشابهة جدًا (لكن مع بعض الاختلافات التي يمكن تعلمها بسهولة). ملفات «التغذية» أفصل عادةً بين مختلف ملفات التغذية (feed files، التي تكون بصيغة XML)، لمختلف الخدمات مثل iTunes و Google Play والتدوينات الصوتية التقليدية (podcasts) و oggcasts. لاحظ أنَّ متصفح Firefox سيحاول تفسير (أو عرض) هذه الملفات باستخدام عميل RSS المضمّن فيه، ولعرض ملفات XML الفعلية فاستخدام الأمر curl أو wget مع الروابط السابقة، أو اعرض مصدر الصفحة في متصفحك. الطريقة السابقة تسمح لي باستخدام وسوم XML خاصة بكل خدمة، وللمزيد من التفاصيل التقنية راجع التدوينة How to run your own podcast. الموقع الإلكتروني أستخدمُ نظام إدارة محتوى باسم Textpattern مع بعض التعديلات، لكن الكثير من المدونين الصوتيين يستعملون ووردبريس مع إضافة PowerPress. كيف أوسِّع من جمهوري؟ الترويج Syndication أسهل طريقة لجلب مستمعين إلى تدويناتك الصوتية هي خدمات الترويج، فيوفر موقع DistroWatch ترويجًا لبعض تدوينات oggcast الصوتية. وأشهر الخدمات للترويج هي iTunes (لمزيدٍ من المعلومات راجع صفحة iTunes Connect Resources and Help page) و Google Play (زر صفحة Podcasts in Google Play Music page)، ويمكن أن تساعدك مواقع وخدمات الترويج الأصغر في زيادة متابعيك، لكن iTunes و Google Play هي أشهرها لسهولة الوصول إليها من مستخدمي iOS و أندرويد. وسائل التواصل الاجتماعي لا تنسَ التواصل المباشر على مواقع التواصل الاجتماعي، فيمكن أن تستعمل تويتر كطريقة أخرى لنشر تدويناتك الصوتية الحديثة، وسيسمح لك بالتواصل مباشرةً مع جمهورك. أمور متفرقة هنالك تقنيات أخرى لإشهار تدويناتك مثل بيع البضائع أو استضافة ضيوف في حلقاتك، والمشاركة في الأحداث المحلية والمنظمات الخيرية، لكن هذه التقنيات ستكون فعالة أكثر بعد أن يكون عندك جمهور. كيف أستفيد ماديًا من التدوين الصوتي؟ عليك أن تبدأ مشوارك في التدوين الصوتي لرغبتك في إنتاج ومشاركة محتوى مع فئة من الناس الذين يتشاركون الاهتمامات، فالإجابة باختصار هي: لن تتمكن من الاستفادة ماديًا (أو ربما تتمكن من ذلك إن كنتَ محظوظًا). لكن التدوين الصوتي في أغلبية الأوقات يكون نابعًا من رغبتك بمشاركة ما تعرفه مع الآخرين (كما في البرمجيات الحرة). ترجمة –وبتصرّف– للمقال A quick-start guide to podcasting لصاحبه Brent Saner
  9. سيأتي حينٌ يحس فيه كل مطوِّر وب جديد بأنَّ شيئًا ما ينقصه عندما يطلب منه أحد الخبراء أن يفتح سطر الأوامر، لكن لا بأس في ذلك، فلكنا مرّ بذلك عندما ذهب إلى منتدى أو اجتماع محلي للقاء مطوري وب الآخرين. هذا الدرس مناسب لكل شخص لا يعرف ما هو سطر الأوامر، وهو ملائمٌ أيضًا لمن له دراية بسطر الأوامر إذ سيتضمّن بعض التفاصيل والملاحظات والتي ستجدها مفيدة وستتعلم منها. لن يشرح هذا الدرس ماذا عليك أن تكتب في الطرفية (terminal، وهي نافذة البرنامج التي تصل إلى سطر الأوامر عبرها) للقيام بأمور معينة، وإنما الهدف هنا هو شرح المفاهيم الأساسية لجعل واجهة سطر الأوامر (command line interface) مألوفةً لك، وبعد أن تتمكّن من الأساسيات فستجد أن فهم أحد الأوامر سهلٌ جدًا وليس عسيرًا كما تظن. ظهرت واجهة سطر الأوامر قبل الواجهات الرسومية أوّل معلومة تساعدك في فهم سطر الأوامر هي استيعاب أنَّ سطر الأوامر قد أتى في الفترة الأولى من وجود الحواسيب، إذ إنَّ البرامج الحالية رسومية فهي تعرض عدِّة نوافذ تابعة للبرنامج للمستخدم، ويظهر أيضًا «سطح المكتب» خلف تلك النوافذ. هذه النوافذ تساعد المستخدمين في استخدام الحاسوب، لكنها مجرد واجهة بسيطة وجميلة للتعامل مع نظام التشغيل. وقبل ظهور الواجهات الرسومية، كان هنالك ما يسمى «طرفيات»، والطرفية هي الوسيلة التي نصل فيها إلى سطر الأوامر (يجدر بالذكر أنَّ الطرفيات هي أجهزة فيزيائية كانت موجودة في الأيام الأولى للحواسيب، وهي جهاز يضم شاشة سوداء وتُظهِر نصًا أبيض، وفيها لوحة مفاتيح مدمجة)، تستطيع أن تقول أنَّ سطر الأوامر هو طريقةٌ مختلفة لتشغيل البرامج كما هي البرامج الرسومية في أنظمة ويندوز أو ماك أو لينكس. إلا أنَّ الاختلاف الرئيسي بينها وبين البرامج الرسومية هي أنَّ البرامج التي تعمل من سطر الأوامر لا توفر واجهةً جميلةً لتتعامل معها، ومستخدمو الحاسوب الذين عاصروا الطرفيات لديهم خبرةٌ كبيرةٌ مع الحواسيب، وتسمعهم يقولون أنَّ الواجهات الرسومية سببت في تقليل إنتاجيتهم، وما يزال أولئك الأشخاص موجودين في هذا العصر. تستطيع أن تستخدم الفأرة وتنقر نقرًا مزدوجًا على أيقونة البرنامج لتشغيله، أما في سطر الأوامر فعليك أن تكتب اسم الأمر (والذي هو اسم البرنامج في أغلبية الحالات)، وربما تضيف بضعة خيارات لتتحكم في سلوكه، ثم تنفِّذ الأمر. لاحظ أنني ذكرتُ استخدام الفأرة بوضوح في الفقرة السابقة وذلك لأنَّها أكبر الفروقات بين الواجهات الرسومية والسطرية، إذ لا تستعمل الفأرة في بيئة سطر الأوامر فالطرفيات كانت موجودة قبل انتشار استخدام الفأرة للتعامل مع الحاسوب، لذا ستجد أنَّ طريقة التفاعل الرئيسية مع سطر الأوامر هي استخدام لوحة المفاتيح. فرقٌ رئيسيٌ آخر هو أنَّ الواجهات الرسومية تكون في وضعية «الانتظار» غالب الوقت عندما يكون البرنامج «قيد التشغيل»، ولأنَّ البرامج التي تعمل من سطر الأوامر كانت من العصر الأول للحاسوب، فلم تكن هنالك مساحة فارغة لإظهار جميع البرمجيات «قيد التشغيل»، فهي تنفَّذ بسرعة كبيرة ثم تتوقف، أي أنَّ من غير الشائع أن يطول تنفيذ أمرٍ ما في سطر الأوامر أكثر من عدِّة ثواني (على الرغم من أنَّ بعضها قد يعمل لفترات طويلة مثل المحررات النصية). لنلخِّص الفروقات بين البرامج التي تعمل من سطر الأوامر والبرامج ذات الواجهة الرسومية: البرامج السطرية هي تطبيقات بسيطة تعمل مرة واحدة. على النقيض من أغلبية التطبيقات الرسومية التي تنتظر منك التفاعل معها، فإنَّ أغلبية التطبيقات السطرية تعمل بسرعة ثم تتوقف. تكون عادة الأوامر قصيرة لأن المستخدمين يريدون أن يكتبوا أقل ما يمكن لتنفيذ ما يشاؤون. لا تُستخدَم الفأرة (عادةً) في سطر الأوامر. الاختلافات بين أنظمة التشغيل يمكننا أن نعد سطر الأوامر على أنه طريقة مباشرة للتواصل مع الحاسوب، وهذا يتيح له قدرات أكثر، مما يجعله فعّالًا، لكن في المقابل هذا يعني أنَّ عليك معروفة المزيد من المعلومات حول طريقة عمل حاسوبك. أغلبية مستخدمي الحاسوب أولي المعرفة المتوسطة يعلمون أنَّ نظام ويندوز يختلف عن ماك ويختلف عن لينكس، لكنها يعلمون أنَّ بإمكانهم تشغيل متصفح Firefox أو برنامج ليبرأوفيس على تلك الأنظمة، لكن هذا ليس صحيحًا بالنسبة إلى سطر الأوامر. هنالك نوعان رئيسيان لسطر الأوامر عليك معرفتهما، النوع الأول هو سطر الأوامر للأنظمة الشبيهة بيونكس (Unix-like)، والنوع الثاني هو سطر أوامر نظام ويندوز. يُصنَّف نظام لينكس وماك على أنهما نظامان شبيهان بيونكس، وبالتي ستتعامل مع سطر الأوامر عبر ما يسمى «صدفة» (shell) باسم Bash (سنتحدث عن ذلك لاحقًا). صحيحٌ أنَّ هنالك اختلافات في طريقة التعامل مع مختلف أنظمة يونكس، لكنها ليست مهمة لمطوري الويب المحترفين، فهذه الاختلافات صغيرة ويمكنك تجاهلها إذا كنتَ مبتدئًا (لكن الحق يقال: ستواجه هذه الاختلاف في وقتٍ ما عندما تجد نفسك مرتاحًا في استخدام سطر الأوامر، وستجد أنَّ تلك الاختلافات لها أثرها). أما نظام ويندوز فهو خارج المنافسة في مجال سطر الأوامر، وهذا هو أحد الأسباب الرئيسية التي تجعل من مطوري الويب يهاجرون من ويندوز إلى لينكس أو ماك، إذ يختلف سطر الأوامر الموجود في نظام ويندوز عن بقية الأنظمة والأوامر ليست متشابهة، وسطر الأوامر فيه قديم وتراثي أضف إلى أنَّ مستخدمي ويندوز يخافون استخدامه. سطر الأوامر في ويندوز لا يمكني الجزم بواقع سطر أوامر ويندوز أو المنافع الآتية من استخدامه في أنظمة ويندوز (ويندوز 10 وما قبله) للقيام بمهام تطوير الويب من سطر الأوامر لأنني أستخدم لينكس منذ فترةٍ طويلة، لكنني سمعتُ شكوى ممن يستعملونه وصحيحٌ أنَّ أغلبية البرمجيات تعمل «نظريًا» في سطر أوامر ويندوز، لكنني سمعتُ أنها ليست عملية. أنا لا أقول لك أن تشتري جهاز ماك أو تثبِّت لينكس على جهازك (لكنني أحثّك على تجربة لينكس على أيّ حال) لتصبح مطوِّر ويب، لكنني أحب أن أشير إلى توافر ما يسمى «Bash on Ubuntu on Windows» في ويندوز 10 وبالتالي ستحصل على سطر أوامر شبيه بيونكس داخل نظام ويندوز، لذا جرِّبه وانظر إن كان مناسبًا لك. ولأغلبية أعمال تطوير الويب، خصوصًا في عالم البرمجيات مفتوحة المصدر الذي تقطنه ووردبريس، ستجد أنَّ الخواديم تُشغِّل إحدى توزيعات لينكس، وهذا يعني أنَّ عليك الاتصال مع الخواديم عبر سطر الأوامر، وهذا سهلٌ جدًا في ويندوز (عبر برمجية PuTTY) لكن هذه البرمجية غير مضمّنة افتراضيًا في ويندوز، وليست كمثيلاتها في بقية الأنظمة. العثور على الطرفية ذكرنا سابقًا أنَّك تستطيع الوصول إلى سطر الأوامر عبر الطرفية، والتي يمكنك تشغيلها في نظام ماك وأغلبية توزيعات لينكس التي توفِّر واجهةً رسوميةً عبر البحث عن تطبيقٍ باسم Terminal وتشغيله، ثم ستجد نافذة تتيح لك التفاعل مع حاسوبك بطريقة تختلف كثيرًا عمّا اعتدت عليه. أما في ويندوز فيسمى محاكي الطرفية باسم «موجِّه الأوامر» (Command Prompt)، الذي يسمح لك بتنفيذ البرامج بكتابة أمرٍ معيّن. يجدر بالذكر أنَّ هنالك أنواع مختلفة من محاكيات الطرفيات، فهنالك طرفية غنوم وطرفية كدي (Konsole) للينكس، وطرفية iTerm لنظام ماك، وهذه الطرفيات تختلف عن بعضها لكنها تؤدي الغرض نفسه ألا وهو الوصول إلى سطر الأوامر. أنواع الصدفات ملاحظة سريعة: هنالك أنواع مختلفة من الصدفات (وهي البرمجيات التي تتواصل عبرها مع سطر الأوامر)، فأغلبية الأشخاص يستخدمون صدفة باش (bash) (وإذا لم تكن تعرف ما هي الصدفة التي تعمل عليها فمن المرجح أنها باش). الاختلافات بين الصدفات هو موضوع معقد وخارج عن نطاق هذا الدرس، لكن كل ما أردتُ تنبيهك إليه هو أنَّك تشغِّل صدفة باش في نظامك (وليس ZSH أو FISH أو غيرها). كيف تصل إلى سطر أوامر خادومك آخر موضوع أريد أن أتحدث عنه في هذا الدرس هو أنَّك تستطيع أن تصل إلى سطر أوامر الخادوم نفسه (إلا إذا كان موقعك مستضافًا على استضافة مشتركة). لا تُشغِّل الخواديم واجهةً رسوميةً (السبب الرئيسي هو الأداء والحماية)، هذا يختلف عن حاسوبك الشخصي الذي يتيح لك التفاعل مع سطر الأوامر ومع الواجهات الرسومية في الوقت نفسه. في الحالات التي ترغب بالوصول فيها إلى سطر الأوامر في خادومك، فيمكنك فعل ذلك عبر SSH (اختصار للعبارة Secure Shell)، وهذه البرمجية تسمح لك بالوصول إلى سطر الأوامر في حاسوبٍ بعيد بأمان؛ وموضوع ضبط SSH خارج عن نطاق هذه المقالة، والغرض من ذكري له هو معرفة وجود طريقة للوصول إلى سطر الأوامر لحاسوبٍ بعيد بأمان. وأذكِّر أنَّ برمجية PuTTY التي ذكرناها سابقًا هي أشهر طريقة ليتصل عبرها مستخدمو ويندوز إلى SSH. أما مستخدمو ماك أو لينكس أو غيرهما فكل ما عليهم فعله للاتصال إلى حاسوبٍ بعيد هو استخدام الأمر ssh في سطر الأوامر. الخلاصة قد يبدو سطر الأوامر شيئًا غريبًا خصوصًا لمستخدمي الحاسوب الذين بدؤوا في استعماله بعد ظهور الواجهات الرسومية التي جعلت منه شيئًا غريبًا، لكن قد نضطر أحيانًا إلى استخدام سطر الأوامر لإنجاز بعض الأمور. أرجو أن تكون قد فهمتَ من المقالة أنَّ سطر الأوامر هو طريقة أخرى للتعامل مع الحاسوب، وقد تكون هي الطريقة الوحيدة للتعامل مع الحاسوب في بعض الحالات مثل الخواديم التي لا تُثبَّت عليها واجهة رسومية للحفاظ على مواردها. تذكّر أنَّنا سنتعامل مع نظام التشغيل في النهاية سواءً استعملنا الواجهة الرسومية أو السطرية، وهذا هو السبب وراء امتلاك نظام ويندوز لسطر أوامر مختلف تمامًا عن ماك أو لينكس؛ إذ يُصنَّف ماك ولينكس على أنهما شبيهان بنظام يونكس، وهذا هو السبب وراء تشابه سطر الأوامر فيهما. سطر الأوامر معقد ومتشابك وواسع، لذا لا تقلق إذا لم تجد نفسك مرتاحًا معه في البداية، إذ تستطيع استخدام أمر ما يوميًا ثم تكتشف أشياءً جديدةً كل فترة (مثل أوامر أخرى أو خيارات للأوامر التي تستعملها أو مفاهيم جديدة في سطر الأوامر). هنالك بعض الأوامر البسيطة التي تساعدك في الاعتياد على سطر الأوامر وفهمه، لذا أنصحك بتعلمها حتى لو لم تكن تستعملها كثيرًا. أعلم أنَّ بإمكانك فعل الكثير مع ووردبريس دون الحاجة إلى استخدام سطر الأوامر، لكنني أعتقد أنَّ من الضروري تعلّم سطر الأوامر لزيادة خبرتك في إدارة مواقع ووردبريس. أرجو أن تكون هذه المقالة قد وضحت لك بعض المفاهيم الغريبة، وإذا كنتَ مهتمًا بمزيدٍ من المعلومات حول سطر الأوامر فأنصحك بقراءة كتاب «سطر أوامر لينكس». ترجمة –وبتصرّف– للمقال What is the Command Line? CLIs from First Principles لصاحبه David Hayes
  10. تملك المتصفحات الحديثة أدوات تطوير مبينة فيها للتعامل مع لغة JavaScript وتقنيات الويب الأخرى، وهذه الأدوات تتضمن سطر الأوامر (Console) الذي يشبه سطر الأوامر الخاص بأنظمة يونكس، إضافةً إلى أدواتٍ لتفحص (inspect) شجرة DOM، وأدوات للتنقيح (debugging)، وتحليل نشاط الشبكة. يمكن استخدام سطر الأوامر (Console) لإنشاء سجل من المعلومات كجزءٍ من عملية تطوير تطبيقات JavaScript، ويسمح لك بالتفاعل مع صفحة الويب بتنفيذ تعليمات JavaScript على عناصر الصفحة. وهذا يعني أنَّ سطر الأوامر يسمح لك بكتابة وإدارة ومراقبة شيفرات JavaScript عند الحاجة. سنشرح في هذا الدرس كيفية التعامل مع سطر الأوامر باستعمال JavaScript في المتصفحات، وسنعطي لمحة عن أدوات التطوير الأخرى المبنية في المتصفحات والتي يمكنك استعمالها في عملية تطوير تطبيقات الويب. العمل مع سطر الأوامر (Console) في المتصفح أغلبية متصفحات الويب الحديثة التي تدعم لغة HTML و XHTML القياسية ستوفِّر لك وصولًا إلى سطر أوامر الذي يمكنك استخدامه (عبر لغة JavaScript) بما يشبه طريقة استخدام الطرفية (terminal) في أنظمة يونكس. سنشرح الآن كيفية الوصول إلى سطر الأوامر في متصفحَي Firefox و Chrome. متصفح Firefox لفتح Web Console في متصفح Firefox، فاضغط على زر القائمة ☰ في الزاوية العليا اليمنى بجوار شريط العنوان. ثم اضغط على زر Developer الذي يقع تحت أيقونة المفك، والذي سيفتح قائمة Web Developer، ومن ثم اضغط على خيار Web Console. وهذا سيفتح لوحةً في أسفل نافذة المتصفح: يمكنك أيضًا الدخول إلى سطر الأوامر عبر اختصار لوحة المفاتيح Ctrl+Shift+K على نظامَي لينكس وويندوز، أو Command+Option+K على ماك. يمكننا التفاعل مع سطر الأوامر باستخدام JavaScript بعد أن استطعنا فتحه. متصفح Chrome لفتح JavaScript Console في متصفح Chrome فيمكنك النقر على القائمة في الزاوية العليا اليمنى من نافذة المتصفح (التي يُرمَز لها بثلاث نقط عمودية) ومن ثم اختيار More Tools ثم Developer Tools. ستُفتح لوحةٌ جديدة فيها اللسان Console في الشريط العلوي الذي عليك أن تضغط عليه للوصول إلى سطر الأوامر (هذا إن لم يكن هذا اللسان مفعّلًا من البداية): يمكنك أيضًا الوصول إلى سطر الأوامر بالضغط على اختصار لوحة المفاتيح Ctrl+Shif+J في نظامَي لينكس وويندوز، أو Command+Option+J في نظام ماك، وهذا سيؤدي إلى فتح لسان Console مباشرةً. يمكننا التفاعل مع سطر الأوامر باستخدام JavaScript بعد أن استطعنا فتحه. التعامل مع سطر الأوامر يمكنك كتابة شيفرات JavaScript داخل سطر الأوامر. لنبدأ بإظهار تحذير يحتوي على السلسلة النصية Hello, World!‎: alert("Hello, World!"); بعد أن تضغط على زر Enter بعد كتابة سطر JavaScript السابق، فيمكن أن تشاهد نافذة التحذير الآتية في متصفحك: ملاحظة: سيُظهِر سطر الأوامر نتيجة تنفيذ التعابير البرمجية، وسيُظهِر undefined إذا لم تتم إعادة (return) قيمة من التعبير المُنفَّذ. بدلًا من عرض نوافذ تحذير التي علينا الضغط على زر OK للخروج منها، يمكننا معرفة ناتج تعابير JavaScript بطباعتها إلى سطر الأوامر عبر الدالة console.log. فلو أردنا طباعة السلسلة النصية Hello, World!‎ سنكتب التعبير البرمجي الآتي في سطر الأوامر: console.log("Hello, World!"); وسيُطبَع السطر الآتي في نافذة سطر الأوامر: Hello, World!‎ يمكننا استخدام JavaScript لإجراء حسابات رياضية في سطر الأوامر: console.log(2 + 6); الناتج: 8 وسيستطيع المتصفح إجراء حسابات على أرقام أكبر: console.log(34348.2342343403285953845 * 4310.23409128534); الناتج: 148048930.17230788 لا تغفل عن إمكانية إجراء عمليات مُقسَّمة على أكثر من سطر عبر استعمال المتغيرات: let d = new Date(); console.log("Today's date is " + d); الناتج: Today's date is Wed Jun 21 2017 15:49:47 GMT-0400 (EDT) إذا أردتَ تعديل التعبير الذي كتبته في سطر الأوامر، فاضغط على زر السهم العلوي ↑ في لوحة مفاتيحك للحصول على السطر السابق، وهذا ما يسمح لك بتعديله ثم تنفيذه مجددًا. يوفر لك سطر أوامر المتصفح القدرة على تجربة شيفرات JavaScript في الوقت الحقيقي بما يشبه واجهة سطر الأوامر في أنظمة يونكس. التعامل مع ملف HTML يمكنك أيضًا إجراء عمليات على ملف HTML موجود مسبقًا أو على مستند مولّد ديناميكيًا عبر سطر الأوامر؛ وهذا يسمح لنا بتجربة كيفية تعامل شيفرات JavaScript مع عناصر HTML وقواعد CSS وسكربتات JavaScript الموجودة في صفحة الويب. أبقِ في ذهنك أنّك إذا أعدتَ تحميل الصفحة بعد تعديلها في سطر الأوامر فستعود إلى حالتها الأصلية قبل التعديل، ولذا احرص على حفظ أيّة تعديلات تريد الإبقاء عليها. لنحفظ مستند HTML الآتي باسم index.html لكي نجِّرب تعديلها عبر سطر الأوامر: <!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Today's Date</title> </head> <body> </body> </html> إذا حفظتَ مستند HTML السابق في ملفٍ ما وفتحتَه باستخدام متصفحك المفضّل فيجب أن تشاهد صفحةً فارغةً عنوانها «Today’s Date». يمكنك الآن فتح سطر الأوامر لاستعمال JavaScript لتعديل الصفحة، وسنبدأ بكتابة شيفرة JavaScript لإضافة ترويسة في الصفحة: let d = new Date(); document.body.innerHTML = "<h1>Today's date is " + d + "</h1>" ستحصل على الناتج الآتي في سطر الأوامر: "<h1>Today's date is Sat Jun 24 2017 12:16:14 GMT-0400 (EDT)</h1>" يجب أن تبدو الصفحة الآن كما يلي: يمكنك أيضًا تعديل أنماط الصفحة، مثل لون الخلفية: document.body.style.backgroundColor = "lightblue"; الناتج: "lightblue" وكذلك الأمر مع لون النص في الصفحة: document.body.style.color = "white"; الناتج: "white" يجب أن تبدو الصفحة الآن كما يلي: يمكنك أيضًا إنشاء فقرة جديدة عبر العنصر <p>: let p = document.createElement("P"); بعد إنشاء العنصر، حان الوقت لإضافة عقدة نصية (text node) التي يمكننا إضافتها إلى الفقرة الجديدة: let t = document.createTextNode("Paragraph text."); سنضيفها الآن إلى الفقرة المُعرَّفة عبر المتغير p: p.appendChild(t); وأخيرًا سنضيف الفقرة المُخزَّنة في المتغير p والنص الموجود فيها إلى المستند: document.body.appendChild(p); إذا أكملتَ الخطوات السابقة، فيجب أن تبدو صفحة HTML السابقة كما يلي: يوفِّر لنا سطر الأوامر البيئة المناسبة لإجراء تجرب على صفحات HTML، لكن من المهم أن نبقي في ذهننا أنَّنا لا نعدل مستند HTML فعليًا عندما ننفذ التعليمات البرمجية في سطر الأوامر، وإنما ستذهب جميع تعديلاتنا إذا أعدنا تحديث الصفحة. لمحة عن أدوات التطوير الأخرى اعتمادًا على أدوات المطوِّر التي يوفرها متصفحك، فستقدر على استخدام أدوات أخرى لمساعدتك في عملية تطوير الويب، لنطلع على تلك الأدوات. عرض شجرة DOM في كل مرة يتم فيها تحميل صفحة الويب، فسيُنشِئ المتصفح ما يسمى شجرة DOM (اختصار للعبارة Document Object Model) للصفحة. شجرة DOM تتألف من كائنات التي تُمثِّل عناصر HTML ضمن البنية الهرمية للعناصر. وشجرة DOM متاحة ضمن لسان Inspector في متصفح Firefox أو لسان Elements في متصفح Chrome. تسمح لك هذه الأدوات بعرض وتعديل عناصر DOM وتسمح لك بمعرفة ما هي وسوم HTML المسؤولة عن عرض جزء معيّن من الصفحة. ويمكن أيضًا من هذا اللسان معرفة ما هي قيمة المعرِّف ID لصورةٍ معيّنةٍ على سبيل المثال. ستكون بنية الصفحة التي عدلناها (وقبل إعادة تحميل الصفحة) في لسان DOM كما يلي: يمكنك أيضًا رؤية ما هي قواعد CSS المطبقة في لوحة جانبية بجوار اللسان الذي يعرض بنية شجرة DOM، مما يسمح لك بمعرفة ما هي الأنماط المُطبّقة على عنصر DOM داخل مستند HTML أو عبر ملف أنماط CSS خارجي. هذه صورةٌ تظهر أنماط العنصر body في أدوات المطوِّر في Firefox: لتعديل عقدة من عقد DOM فانقر نقرًا مزدوجًا فوق العنصر المُحدَّد وأجرِ التعديلات اللازمة، فحاول مثلًا أن تحوِّل العنصر <h1> إلى <h2>. تذكَّر أنَّ الصفحة ستعود إلى حالتها الأصلية المحفوظة إذا أعدت تحميلها. لسان الشبكة يمكن في لسان الشبكة Network في أدوات المطوِّر الموجودة في متصفحك أن تراقب وتسجِّل الطلبيات الشبكية، إذ يُظهِر هذا اللسان جميع الطلبيات الشبكية التي يجريها المتصفح بما في ذلك ما طَلَبَهُ عند تحميل الصفحة، وكم استغرقت كل طلبية من الوقت، وسيوفِّر تفاصيل عن كل طلبية؛ وهذا سيساعد كثيرًا في معرفة سبل تحسين أداء الصفحة وتسريع تحميلها وتنقيح مشاكل الشبكة. يمكنك استخدام لسان الشبكة جنبًا إلى جنب مع سطر الأوامر، أي يمكنك بدء عملية تنقيح (debug) الصفحة في سطر الأوامر ثم الانتقال إلى لسان الشبكة لرؤية النشاطات الشبكية دون إعادة تحميل الصفحة. لتعلّم المزيد حول لسان الشبكة، فأنصحك بقراء working with Firefox’s Network Monitor أو getting started with analyzing Network performance with Chrome’s DevTools. التصميم المتجاوب عندما يكون موقع الويب متجاوبًا (responsive)، فهذا يعني أنَّه صُمِّمَ وطوِّرَ لكي يظهر ويعمل بشكل مناسب على مجال واسع من الأجهزة المختلفة مثل الهواتف المحمولة والحواسيب اللوحية والحواسيب المكتبة والمحمولة. قياس الشاشة وكثافة البكسلات ودعم اللمس هي عوامل مهمة يجب أخذها بالحسبان عند تطوير مواقع متجاوبة، ويجب عليك –كمطور ويب– أن تفكر في مبادئ التصميم المتجاوب عند إنشاء المواقع لإتاحتها للآخرين بغض النظر عن الجهاز الذي يصلون إلى موقعك عبره. يوفر لك متصفح Firefox و Chrome أدواتٍ للتأكد من تطبيقك لمبادئ التصميم المتجاوب أثناء إنشائك وتطويرك لمواقع وتطبيقات الويب. وستتمكن بوساطة تلك الأدوات أن تحاكي مختلف الأجهزة لكي تختبر تطبيقك وتحلّل مشاكله أثناء التطوير. اقرأ المزيد عن Responsive Design Mode في متصفح Firefox أو Device Mode في Chrome لتعلم طريقة الاستفادة من تلك الأدوات لإنشاء مواقع ويب تلبي احتياجات جميع المستخدمين. الخلاصة أخذنا في هذا الدرس لمحةً عن طريقة التعامل مع سطر الأوامر الموجود في المتصفحات الحديثة، بالإضافة إلى بعض المعلومات عن أدوات التطوير التي يمكنك الاستفادة منها في عملك. لتعلّم المزيد عن JavaScript فاقرأ كتاب تعلم JavaScript، وإذا كنتَ مهتمًا بمكتبة jQuery فأنصحك بالاطلاع على كتاب تعلم jQuery. ترجمة –وبتصرّف– للمقال How To Use the JavaScript Developer Console لصاحبته Lisa Tagliaferri
  11. Let’s Encrypt هي سلطة شهادات مفتوحة ومؤتمتة تستعمل بروتوكول ACME ‏(Automatic Certificate Management Environment) لتوفير شهادات TLS/SSL مجانية لأي عميل يحقق الشروط المطلوبة، وتلك الشهادات يمكن أن تستعمل لتشفير الاتصالات بين خادوم الويب وزوار موقعك. هنالك الكثير من العملاء المتاحة لبروتوكول ACME المكتوبة بمختلف لغات البرمجة، مع قدرة على الدمج مع أدوات الإدارة والخدمات والخواديم الشهيرة. أشهر عميل ACME باسم Certbot يُطوَّر حاليًا من Electronic Frontier Foundation. ويمكن لعميل Certbot ضبط تشفير TLS/SSL في خودايم أباتشي و Nginx إضافةً إلى التحقق من ملكية النطاق والحصول على الشهادات. سيشرح هذا الدرس سلطات الشهادات باختصار وكيف تعمل خدمة Let’s Encrypt، ثم سنتحدث عن بعض عملاء ACME. ما هي سلطة الشهادات؟ سلطات الشهادات (certificate authorities اختصارًا CAs) هي الجهات التي توقِّع شهادات TLS/SSL رقميًا لضمان وكفالة موثوقيتها. إذ تملك المتصفحات وأنظمة التشغيل قائمةً بسلطات الشهادات الموثوقة التي يمكن استعمالها للتحقق من شهادات أحد المواقع. حتى وقتٍ قريب، كانت أغلبية سلطات الشهادات خاضعة لشركات تجارية والتي تتقاضى أموالًا للحصول على خدمات توقيع الشهادات، لكن أتت خدمة Let’s Encrypt وجعلت هذه العملية مجانية للمستخدمين عبر أتمتة العملية كليًّا، وبالاعتماد على نظام الرعاية والمساهمات المالية لتمويل البنية التحتية اللازمة لتشغيل مثل هذه الخدمة. لمزيدٍ من المعلومات حول الشهادات والأنواع المختلفة من سلطات الشهادات، فاقرأ مقالة A Comparison of Let’s Encrypt, Commercial and Private Certificate Authorities, and Self-Signed SSL Certificates. كيف تعمل خدمة Let’s Encrypt بروتوكول ACME يُعرِّف كيفية تواصل العملاء مع الخواديم لطلب الشهادات والتحقق من ملكية النطاقات وتنزيل الشهادات، وهذا البروتوكول في صدد تحويله إلى معيار IETF رسمي. توفِّر خدمة Let’s Encrypt شهادات لنطاقات موثوقة، وهذا يعني أنَّها ستتحقق أنَّ الشهادة تأتي من شخصٍ يتحكم فعليًا بالنطاق، وذلك عبر إرسال العميل لرمز فريد (unique token) ثم إجراء طلبية ويب أو DNS للحصول على مفتاح مأخوذ من ذاك الرمز. على سبيل المثال، لو كنا سنجري تحقق عبر HTTP، فسيحسب العميل المفتاح من الرمز الفريد (unique token) ورمز الحساب (account token)، ثم يضع الناتج في ملف مُخدَّم من خادوم الويب، ثم يمكن لخواديم Let’s Encrypt أن تنزِّل الملف الموجود في المسار http://example.com/.well-known/acme-challenge/token فإذا كان المفتاح صحيحًا، فهذا يعني أن العميل قادرٌ على التحكم بالموارد الموجودة في النطاق example.com وبالتالي سيوقِّع الخادوم الشهادة ويتيحها للعميل. يُعرِّف بروتوكول ACME عدِّة طرائق للتحقق أنَّ العميل يملك النطاق، فاختبار HTTPS شبيه باختبار HTTP، لكن بدلًا من استخدام ملف نصي فسيوفِّر العميل شهادة موقعة ذاتيًا وفيها مفتاح التحقق. أما التحقق عبر DNS فيتم عبر وضع المفتاح في سجل DNS TXT. عميل Certbot Certbot هو أشهر عميل Let’s Encrypt، وهو متوافر في أغلبية توزيعات لينكس ويتضمن القدرة على الضبط التلقائي لخادومَي أباتشي و Nginx. يمكنك الحصول على الشهادة وتحديث ضبط أباتشي بتنفيذ الأمر الآتي بعد تثبيت عميل Certbot: sudo certbot --apache -d www.example.com سيسألك Certbot بعض الأسئلة ثم يجري عملية التحقق وينزِّل الشهادات ويُحدِّث ضبط أباتشي ويعيد تحميل الخادوم، ويمكنك بعد ذلك أن تنتقل إلى https://www.example.com في متصفح الويب الخاص بك وستشاهد القفل الأخضر مشيرًا إلى أنَّ الشهادة صحيحة والاتصال مشفّر. ولأن شهادات Let’s Encrypt صالحة لتسعين يومًا فقط، فمن المهم ضبط عملية تجديد مؤتمة. الأمر الآتي سيُجدِّد كل الشهادات الموجودة على الحاسوب: sudo certbot renew ضع الأمر السابق في جدول cron وشغِّله يوميًا، وستُجدَّد الشهادات تلقائيًا قبل ثلاثين يومًا من انتهاء صلاحيتها، وإذا أُنشِئَت الشهادة بادئ الأمر مع أحد الخيارين ‎--apache أو ‎--nginx فسيعيد Certbot تحميل الخادوم بعد نجاح عملية التجديد. إذا أردتَ معرفة المزيد من المعلومات حول جداول cron فأحيلك إلى درس كيف نستخدم المهام المجدولة باستخدامCron في أنظمة لينكس ويونكس. عملاء آخرين لأن بروتوكول ACME مفتوح وموثّق جيدًا، فقد طوِّرَ الكثير من العملاء البديلين، وهنالك قائمة بعملاء ACME في موقع Let’s Encrypt، وأغلبية العملاء لا يملكون ميزة ضبط خادوم الويب تلقائيًا التي يملكها Certbot لكن هنالك ميزات أخرى لها قد تجذبك: - هنالك عميل مكتوب بكل لغات البرمجة تقريبًا، بما في ذلك سكربتات الصدفة (shell scripts) ولغة Go و Node.js، وقد تستفيد من ذلك إن كنتَ تُنشِئ شهادات في بيئة مغلقة لا يمكن تضمين بايثون فيها ولا بقية اعتماديات Certbot. - بعض العملاء يمكن أن يعملوا دون امتيازات الجذر، فمن المستحسن تقليل كمية الشيفرات التي تعمل بامتيازات الجذر إلى أقل قدر ممكن. - الكثير من العملاء يمكنها أتمتة عملية التحقق عبر DNS عبر استخدام الواجهة البرمجية المناسبة لموفِّر خدمة DNS لإنشاء سجلات TXT تلقائيًا، والتحقق عبر DNS يسمح بتوليد شهادات لحالات الاستخدام الغريبة مثل تشفير خواديم الويب التي لا يمكن للعموم الوصول إليها. - بعض العملاء يمكن أن يندمج مع خودايم الويب أو الخواديم الوسيطة (proxy) العكسية، أو موزّعات الحِمل (load balancers) مما يسهِّل عملية الضبط والتشغيل. بعض أشهر تلك العملاء: - lego المكتوب بلغة Go، والذي يُثبَّت عبر ملفٍ ثنائيٍ وحيد، والذي يدعم عدد من مزودي خدمة DNS لتسهيل التحقق عبر DNS. - acme.sh وهو سكربت صدفة بسيط يمكن أن يعمل دون امتيازات الجذر، ويستطيع أن يتواصل مع أكثر من 30 مزودًا لخدمة DNS. - Caddy وهو خادوم ويب كامل مكتوب بلغة Go والذي يملك دعمًا مدمجًا فيه لخدمة Let’s Encrypt. يتوافر الكثير من العملاء، وأصبحت العديد من الخدمات والخواديم تؤتمت عملية إعداد TLS/SSL بدعم خدمة Let’s Encrypt فيها. الخلاصة لقد شرحنا أساسيات عمل خدمة Let’s Encrypt، وناقشنا أشهر العملاء المتوافرين، وإذا أردتَ معرفة كيفية إعداد هذه الخدمة مع بقية البرمجيات فأنصحك بالاطلاع على درس تنصيب شهادة SSL مجانية عبر خدمة Let’s encrypt على خادوم لينكس. ترجمة –وبتصرّف– للمقال An Introduction to Let’s Encrypt لصاحبه Brian Boucheron
  12. أهلًا بك في عالم العمل المستقل! سواءً كنت قد استقلتَ من عملك ذي الدوام الكامل أو كنتَ تتطلع إلى جني القليل من الأموال عبر بعض الأعمال الجانبية، فاعلم أنَّ العمل الحر في مجال ووردبريس قد يكون بدايةً ممتازةً لتأسيس مهنتك كمدير مواقع موثوق. لكن هنالك مشكلة وحيدة؛ فالكثيرون يبدؤون عملهم الحر مع ووردبريس ببناء المواقع. أنا لا أقول أنَّ ذلك خطأ، وإنما لبناء المواقع من الصفر ميزاتٌ كثيرة: ستتعلم التعامل مع ووردبريس بسرعة، بدءًا من خصائص لوحة التحكم مرورًا بالإضافات الضرورية التي عليك استعمالها. ستصبح ملمًا بشركات الاستضافة، ولوحة تحكم cPanel وما يتعلق بأمور إدارة الخادوم، وهذه المعرفة ضرورية لجميع العاملين في مجال ووردبريس. ستتعلم العمل جنبًا إلى جنب مع العملاء لبناء المواقع التي تلبي احتياجاتهم، فمهارة تطوير المواقع ذات القيمة الكبيرة عند المستخدمين هي مهارةٌ لا تقدّر بثمن. ستقع بمشكلات وسترتكب أخطاء وستتعلم منها، ولا تنسَ أنَّ الأخطاء واردة جدًا خصوصًا مع الأمور التقنية. التحديات الرئيسية ستظهر لك عندما تتوقف عن جني المال، فإذا كان عملك الحر لا يتضمن سوى بناء المواقع للآخرين فستقضي نصف وقتك في البحث عن مشاريع جديدة ولقاء العملاء المحتملين ومحاولة البقاء على قيد الحياة حتى تجد عميلك القادم. لكن لحسن الحظ، هنالك طريقٌ أفضل لبدء العمل الحر: بدلًا من بناء مواقع ووردبريس من الصفر، لِمَ لا تساعد مَن يملكون موقعًا بصيانته؟ أبزر ميزاتك! هنالك عشرات الآلاف من الشركات الصغيرة حول العالم التي تبني مواقع ووردبريس والتي تتنافس للحصول على عملائك. أضف إلى ذلك وجود «حيتان كبيرة» مثل WebDevStudios التي توفِّر حلول ووردبريس للعملاء المميزين. أفضل شيء يمكنك فعله في هذه المجال المكتظ هو جعل نفسك مميزًا، إحدى طرق فعل ذلك هي توفير الخدمات التي يحتاج لها الناس مثل الدعم التقني المستمر وأمور الحماية وتحسين السرعة والأداء وصيانة الموقع. ألا تعلم أنَّ كثيرًا من صاحبي المواقع يكرهون تحديث الإضافات لأنها قد تسبب أخطاء أو تضاربات؟ لِمَ لا تتعلم كيفية تحديث الإضافات بأمان وتطبِّقها على مواقع عملائك؟ لن تحتاج إلى تقفي آثار الزبائن! عندما يكون عملك الحر مقتصرًا على بناء مواقع ويب لمختلف العملاء، فالكثير من وقتك سيضيع بحثًا عن مشاريع جديدة (وليس بجني المال). إذا كنت توفر خدمة صيانة مواقع، فسيدفع لك العملاء شهريًا للحصول على خدماتك، وهذا يعني أنَّه طالما كان عملك متقنًا وكانت لديك خطة صيانة واضحة ومرنة وحافظتَ على عملائك فستحصل على إيراد متكرر كل شهر. وهذا يعني أنَّ دخلك سيصبح ثابتًا نسبيًا، وبالتالي تستطيع توظيف أموالك واستعمالها بشكل أكثر كفاءة. إقناع الناس بشراء خدمة الصيانة أسهل إذا كنتَ تريد إقناع عميلك بإنشاء موقع ويب جديد، فمن الصعب حثّه على دفع آلاف الدولارات قبل أن يحصل على أيّة فوائد حقيقية من الموقع؛ أضف إلى ذلك أنَّ الفترة الزمنية بين المقابلة الأوليّة (قبل بدء المشروع) إلى حين إطلاق الموقع قد تُقدَّر بالأشهر (إن لم يكن أكثر). أما تأسيس عمل متعلق بصيانة مواقع ووردبريس فهو أسهل، لأن كمية المال المدفوعة من العملاء أقل وسيدفعون شهريًا، وعملية إقناع الناس بالاشتراك بخطط شهرية أقل جهدًا ووقتًا. يمكنك التوسع بسهولة وأتمتة عملية الصيانة بناء مواقع ويب ذات جودة عالية هو أمرٌ في غاية الصعوبة، صدقني لقد جربتُ ذلك عندما بدأتُ مع ووردبريس. لكن كل زبون يحتاج إلى شيءٍ مختلف، وعليك قضاء الكثير من الوقت لنقاش أهداف شركته وتصاميم الموقع ثم تطبيق التعديلات التي طلبها العميل. وعند حلول نهاية المشروع، فلن تجد نفسك قد جنيتَ أيّة أرباح لأنك أنفقت ساعات وساعات للتعامل مع طلبات العميل وبالتالي انخفضت قيمة ساعة عملك. أجمل ما في خدمة صيانة المواقع هي القدرة على أتمتة أغلبية المهام، إذ يمكنك الاستفادة من إضافة ManageWP لإدارة عشرات ومئات وآلاف مواقع ووردبريس من لوحة تحكم واحدة. الوقت الذي عليك إنفاقه لصيانة مواقع عملائك يتضمن: إقناع العميل بخدمتك وتهيئة الخطة التي اختارها. التعامل مع التعديلات والأمور التي يخبرك بها عميلك. معالجة التنبيهات المؤتمتة التي تأتيك إذا كان هنالك تهديد أمني، أو انخفضت مستويات أداء الموقع، أو لم يكن الموقع يعمل. خلا ذلك، فكل شيءٍ مؤتمت وسيُرسَل لك تنبيه إذا حدث حادث. لن يسبب عملك في ضغط على وقتك لا أريد أن أضلِّلَك هنا، فكل عملٍ متقنٍ في هذا العالم يأخذ وقتًا وصبرًا وجهدًا كبيرًا، وصيانة مواقع ووردبريس بدلًا من تطوير مواقع جديدة من الصفر ليست أمرًا سحريًا يسمح لك بجني المال وأنت جالسٌ على أريكتك ومسترخٍ. بعد أن يكون لك نظام كفء للإدارة، فلن تأخذ عملية إدارة مواقع ووردبريس كثيرًا من وقتك، وستتمكن من التعامل مع أغلبية طلبات الدعم بسهولة مما يعني أنك تستطيع تفريغ قدر كبير من وقتك لتملأه بما تشاء. أكمل قراءة الرواية التي تركتها لعدم توافر وقت لها، واحضر مباراة كرة القدم لفريقك المفضل، واذهب إلى الحديقة وتناول قليلًا من المثلجات. أو انفق وقتك –كما فعلتُ أنا– بتطوير الأنظمة وإنشاء شركة وبتوظيف أشخاص وإدارة فريق عمل وتحويل العمل الحر إلى تجارة كاملة. الخلاصة أهم شيء عليك تذكره حول العمل الحر مع ووردبريس هو أنَّ التركيز الرئيسي للعمل يجب أن يكون النجاح في مساعدة العملاء؛ تذكر أنَّ السبب الرئيسي وراء تطور ووردبريس هو مجتمع البرمجيات مفتوحة المصدر، والذي في أساسه يعني أنَّ هدف ووردبريس هو مساعدة الآخرين. ترجمة –وبتصرّف– للمقال Kick Off Your WordPress Freelance Career With a Website Maintenance Service لصاحبه Joe Howard حقوق الصورة البارزة محفوظة لـ Freepik
  13. لغة Go (والتي يشار إليها golang أيضًا) هي لغة برمجة عصرية مفتوحة المصدر طورتها Google، وازداد انتشارها في كثير من الاستخدامات، وهي تنتهج منهج التبسيط (minimalist) في التطوير وتُسهِّل بناء برمجيات عملية ذات كفاءة عالية. سيشرح هذا الدرس كيفية تحميل وتثبيت Go 1.7، إضافةً إلى شرح تصريف (compile) وتنفيذ برنامج بسيط («!Hello World») على خادوم دبيان 8. المتطلبات المسبقة يفترض هذا الدرس أنَّ لديك وصولًا إلى خادوم دبيان 8 مضبوط فيه حساب مستخدم ليس جذرًا لكنه يمتلك امتيازات الجذر عبر الأمر sudo. الخطوة الأولى: تحميل حزمة لغة Go سنبدأ بتحميل حزمة Go على خادومنا من الموقع الرسمي. اذهب إلى صفحة تنزيل لغة Go الرسمية وابحث عن رابط URL لأرشيف النسخة الحالية من النسخة الثنائية (binary) من اللغة. احرص على أن تنسخ رابط آخر نسخة متوافرة ومتوافقة مع معمارية 64 بت. استعمل الأمر curl من مجلد المنزل لتحميل الأرشيف: curl -O https://storage.googleapis.com/golang/go1.7.4.linux-amd64.tar.gz وصحيحٌ أننا حمّلنا الملف من مصدر موثوق، إلا أنَّه من الأفضل التحقق من سلامة الملفات التي نحمّلها عبر الإنترنت، وهذا يعني أننا سنضمن أنَّ الملف لم يُعدَّل أو يتلاعب به أو يعطَب أثناء عملية التحميل. الأمر sha256sum يُظهِر رمزًا فريدًا من 256 بت: sha256sum go1.7*.tar.gz الناتج: 47fda42e46b4c3ec93fa5d4d4cc6a748aa3f9411a2a2b7e08e3a6d80d753ec8b go1.7.4.linux-amd64.tar.gz قارن الرمز الظاهر في ناتج الأمر السابق مع القيمة الموجودة في صفحة تحميل Go، إذا وجدتهما متطابقين فهذا يعني أنَّ عملية التحميل قد نجحت. لنحاول تثبيت لغة Go بعد أن تحققنا من سلامة الملف. الخطوة الثانية: تثبيت لغة Go سنستخدم الأمر tar لاستخراج محتويات الأرشيف، إذ يطلب الخيار x من الأمر tar أن يستخرج محتويات الملف، والخيار v أن يعرض مخرجات (والتي هي قائمة بالملفات التي ستُستخرَج)، أما الخيار f فيطلب من الأمر tar قراءة ملف الأرشيف المُحدَّد: tar xvf go1.7.4.linux-amd64.tar.gz يجب أن يُنشَأ مجلدٌ باسم go في مجلد العمل الحالي (وهو مجلد Home)، عليك الآن تبديل المستخدم المالك والمجموعة المالكة لمجلد go إلى الجذر، ثم نقله إلى مجلد ‎/usr/local: sudo chown -R root:root ./go sudo mv go /usr/local ملاحظة: على الرغم من أنَّ المسار ‎/usr/local/go هو المسار المنصوح به رسميًا، لكن بعض المستخدمين يفضلون استخدام مسارات مختلفة. عند هذه النقطة يجب تحديد مسار التثبيت عند استدعاء لغة Go من سطر الأوامر، ولجعل التعامل مع Go أسهل قليلًا ، سنضبط بعض المسارات. الخطوة الثالثة: ضبط مسارات Go سنضبط في هذه الخطوة بعض المسارات في البيئة (environment) عندك. لنضبط أولًا قيمة مجلد الجذر للغة Go، الذي يخبر Go أين عليها أن تبحث عن ملفاتها: sudo nano ~/.profile أضف السطرين الآتيين في نهاية الملف: export GOPATH=$HOME/work export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin إذا اخترت تثبيت Go في مجلد آخر، فأضف الأسطر الآتية بدلًا مما سبق، فلو ثبتنا Go في مجلد Home على سبيل المثال، فسنضيف: export GOROOT=$HOME/go export GOPATH=$HOME/work export PATH=$PATH:$GOROOT/bin:$GOPATH/bin بعد تعديل الملف بما هو مناسب، احفظ الملف وأغلق المحرر، ثم أعد قراءة ملف ‎.profile في جلسة bash الحالية: source ~/.profile لقد أنهينا تثبيت Go، لذا لنتأكد من ذلك بكتابة برنامج قصير. الخطوة الرابعة: تجربة Go بعد أن ثبتنا Go وضبطنا المسارات في خادومنا، يمكننا تجربتها للتأكد من أنها تعمل كما هو متوقع. أنشِئ مجلدًا جديدًا لبيئة عمل Go، وهو المكان الذي ستبني فيها Go ملفاتها: mkdir $HOME/work ثم أنشِئ هيكلة المجلدات اللازمة في ذاك المجلد لإنشاء برنامج بسيط، وسنستخدم my_project اسمًا لمشروعنا في هذا المثال: mkdir -p work/src/my_project/hello يمكنك الآن إنشاء ملف «Hello, World!‎» بلغة Go: nano ~/work/src/my_project/hello/hello.go ألصق الشيفرة الآتية داخل محررك، والذي يستخدم حزمة main في لغة go، ثم يستورد المكوِّن fmt، ثم يُنشِئ دالةً جديدةً لطباعة Hello, World!‎ عند تشغيله: package main import "fmt" func main() { fmt.Printf("Hello, World!\n") } سيطبع البرنامج السابق العبارة «Hello, World!‎» إلى الطرفية إذا عَمِلَ دون مشاكل، مما يشير إلى إمكانية تصريف تطبيقات Go بنجاح. احفظ الملف وأغلق المحرر، ثم صرِّف (compile) الملف بتنفيذ التعليمة install التابعة للغة Go: go install my_project/hello يمكنك تشغيل الملف بعد التصريف بتنفيذ الأمر: hello إذا شاهدت المخرجات الآتية فاعلم أنَّ لغة Go مثبتة بشكل صحيح: Hello, World! يمكنك معرفة مكان وجود الملف التنفيذي hello في نظامك باستخدام الأمر which: which hello الناتج: /home/user/work/bin/hello تأكدنا من أنَّ بيئة تطوير Go تعمل بسلاسة بعد تشغيلنا لبرنامج Hello World البسيط السابق. الخلاصة بعد تحميل وتثبيت آخر حزمة Go وضبط المسارات الخاصة بها، أصبح نظامك جاهزًا لتطوير تطبيقات Go. لاحظ أنَّ التطبيقات الاعتيادية تستخدم مكتبات وحزم أخرى، ولتعلم المزيد من المعلومات حول تلك المكونات، انظر إلى صفحة How to Write Go Code في الدليل الرسمي. ترجمة –وبتصرّف– للمقال How To Install Go 1.7 on Debian 8 لصاحبته Lisa Tagliaferri
  14. من المهم جدًا أن يكون الموقع سريعًا، إذ يتوقع ما نسبته 47% من الزوار أن يُحمَّل الموقع في أقل من ثانيتين، وسيترك ما نسبته 40% من الزوار موقعك إن استغرق أكثر من ثلاث ثواني ليُحمَّل. إحدى الدراسات (صحيحٌ أنَّ الدراسة قديمة، لكن الفكرة النظرية وراءها ما تزال صالحة إلى زماننا هذا) تقول أنَّ المستخدمين سيتساهلون إذا حدث تأخير بسيط، لكن درجة عدم رضاهم إذا كان التأخير متوسطًا هي نفسها إذا كان التأخير كبيرًا. فربما لا تظن أنَّ موقعك «بطيء»، لكن حتى لو كان زمن التأخير متوسطًا فقد يحسّ الزوار أنه بطيء جدًا؛ والحل الوحيد لتفادي خسارة زوار موقعك بسبب بطء الموقع هو جعله سريعًا :-) . إحدى أكبر العقبات التي ستواجهك عندما تحاول جعل موقعك سريعًا هي الصور والملفات الثابتة الأخرى مثل JS و CSS، فالصور تكون عادةً كبيرةً وتأخذ وقتًا طويلًا للتحميل (خصوصًا على الاستضافات المشتركة الرخيصة)، ولتحسين ذلك يمكنك استخدام شبكات توزيع المحتوى (CDN). ما هي شبكات توزيع المحتوى؟ شبكات توزيع المحتوى (بالإنكليزية Content Distribution Networks) هي مجموعة من الخواديم المنتشرة حول العالم والمختصة بتخديم المحتوى الثابت بسرعة. طريقة عمل تلك الشبكات تتلخص بوجود خادوم رئيسي (origin) يخزِّن ملفاتك الثابتة (مثل الصور وملفات JavaScript و CSS) وخواديم توزيع التي توصِّل المحتوى إلى المستخدمين، والخادوم الرئيسي هو الخادوم الذي يحتوي على النسخة الرئيسية من الملفات (وفي حالتنا: هو الخادوم الذي يُشغِّل ووردبريس). وعندما يتم طلب الصورة عبر شبكة توزيع المحتوى فسيُحدَّد ما هو الخادوم الأقرب لمكان المستخدم جغرافيًا وسيتحقق الخادوم إن كان يملك الصورة المطلوبة، فإن لم يكن يملكها فسينزلها من الخادوم الرئيسي، وإذا كانت موجودةً عنده فسيرسلها للمستخدم. فائدة طريقة التوزيع السابقة تتلخص في نقطتين أساسيتين: 1. تلك الخواديم مخصصة ومحسّنة لتخديم المحتوى الثابت (مثل الصور) لذا يمكنها تحميل المحتوى بشكل أسرع. 2. يتواجد أحد تلك الخواديم بالقرب من مكان المستخدم، وهذا يعني أنَّ الملف لن يحتاج إلى الانتقال لمسافات طويلة (فيزيائيًا) حتى يصل إلى المستخدم، وبالتالي سيكون زمن التأخير قليلًا. قد يبدو من الوهلة الأولى أنَّ الأمر معقدٌ جدًا، وهو كذلك، لكن لحسن الحظ لا توجد ضرورة أن تتعامل مع الأمور التقنية الخاصة بشبكات توزيع المحتوى، إذ تستطيع قطف الثمار مباشرةً، فهنالك خدماتٌ كثيرة تتولى الأمور التقنية وتُسهِّل عملية الاستفادة من تحسين الأداء عبر استعمال شبكات توزيع المحتوى في موقعك. لكن دعنا نلقي نظرةً على أفضل حلّ لاستعمال شبكات التوزيع في ووردبريس. استخدام Photon خدمة Photon هي خدمة جيدة لتوزيع المحتوى، وهي مجانية أيضًا، وهنالك أسباب تجعل خدمة Photon (التابعة لإضافة Jetpack) جيدة، ولهذا فصلناها عن بقية إضافات CDN: 1. هذه الخدمة هي جزءٌ من إضافة Jetpack، فإضافة Jetpack فيها الكثير من الميزات المفيدة ومن المرجح أنّك تستعملها في موقعك؛ كل ما عليك فعله هو تثبيت Jetpack (من إضافات – أضف جديد، ثم ابحث عن Jetpack) وفعِّل Photon وستكون خدمة CDN جاهزةً عندك، ولا حاجة إلى إجراء أيّة خطوات إضافية، وضبط هذه الخدمة بسيطٌ جدًا؛ إذ تحتاج الكثير من إضافات CDN الأخرى إلى تعديلات تقنية على ضبط خادومك، لكن هذه الإضافة لا تتطلب ذلك. 2. ستُحسِّن خدمة Photon من حجم صورك تلقائيًا، فأغلبية خدمات CDN ستُخدِّم الصور التي ترسلها لها كما هي، لكن خدمة Photon ستجعل الحجم التخزيني لتلك الصور أصغر، ولفعل ذلك ستستخدم Jetpack صيغة صور باسم webp التي طورتها Google، وتملك صيغة webp أفضل خوارزمية ضغط متوافرة حاليًا، وهي مدعومة من متصفحَي Chrome و Opera، وخدمة Photon تعرف ذلك وتُخدِّم الصور بصيغة webp لزوار موقع Chrome و Opera فقط (التي يستعملها حوالي نصف الزوار). 3. إحدى المزايا المتقدمة لخدمة Photon هي القدرة على تطبيق فلاتر إلى الصور وقصها وإعادة تحجميها، وعملية القص وإعادة التحجيم ستقوم بها خدمة Photon دون تدخل من المستخدم (باستعمال دوال add_image_size()‎ الموجودة في ووردبريس)، ويمكن للمستخدمين المتقدمين أن يضيفوا فلاتر إلى الصورة لتغيير طريقة عرضها. عملية ضبط Photon شبيهة بطريقة ضبط وحدات (modules) Jetpack الأخرى. فبعد تفعيل إضافة Jetpack فاذهب إلى صفحة الضبط الخاصة بها وابحث عن Photon ثم اضغط على «Activate». ألم أقل لك أنَّ الأمر بسيط جدًا. لمزيدٍ من المعلومات حول Photon أحيلك إلى هذه الصفحة، وإلى توثيق API. خيارات أخرى لشبكات توزيع المحتوى لماذا تريد استخدام شبكة توزيع أخرى إذا كانت خدمة Photon ممتازةً؟ هنالك ثلاثة أسباب محتملة: الخصوصية. خدمة Photon مملوكة من شركة Automattic (وهي الشركة التي تملك موقع wordpress.com) وبعض المستخدمين يشكون في أمرهم. لا تنسَ أنَّ Automattic هي شركة تجارية وتوفر خدمة مجانية ولا تتوقع أنها صدقة نابعة من طيبة قلوبهم. لن تنتهي صلاحية التخزين المؤقت. وهذا يعني أنَّك لا تستطيع حذف صورة، فلو أردتَ استبدال صورة بأخرى فعليك رفع الصورة الجديدة باسمٍ مختلف. خدمة Photon لا تدعم إلا الصور. فلو أردتَ تخديم ملفات JavaScript و CSS من شبكة توزيع محتوى، فعليك استخدام خدمة أخرى. لكن لسوء الحظ، لا توجد خدمة توزيع محتوى سهلة الإعداد كما في خدمة Photon. لكن الأسباب السابقة لا تعني بالضرورة أن تتجنب استخدام هذه الخدمة، إذ إنَّ تحميل الصورة من خدمة Photon يملك أثرًا كبيرًا على سرعة موقعك، والفائدة الآتية من تحميل الملفات الثابتة الأخرى من شبكة توزيع محتوى ستكون قليلة نسبيًا، ما لم يكن موقعك مشهورًا فعندئذٍ سيستفيد من استعمال خدمة CDN أخرى. إذا أصررتَ على إعداد شبكة CDN فسأذكر في بقية هذا الدرس أفضل الخيارات التجارية المتاحة أمامك لتختار منها ما يناسبك. أفضل الخيارات: خدمة Cloudflare خدمة Cloudflare هي خيار ممتاز، ويمكنها توفير ميزات أكثر من مجرد شبكة توزيع محتوى، بما في ذلك تحسين حماية موقعك وخلاف ذلك، لذا أنصحك بإلقاء نظرة عليها. ذكرتُ Cloudflare أولًا لأنها توفر خطةً مجانيةً رائعةً كافيةً لأغلبية المستخدمين (وإذا أردتَ المزيد من الميزات، فالخطط الاحترافية تبدأ من 20 دولارًا لكل موقع شهريًا). فإذا كنتَ مهتمًا كثيرًا بالحصول على أفضل أداء وأردتَ دمج خدمات إضافة Jetpack مع خدمة توزيع محتوى خارجية، فأنصحك باستعمال Cloudflare. الجانب السلبي الوحيد لهذه الخدمة هو أنَّ إعدادها ليس بسيطًا كما في إضافة Jetpack؛ إذ ستحتاج إلى تسجيل حساب في الخدمة واتباع التعليمات لتحديث سجلات DNS، وقد تستغرق هذه العملية بين عدِّة ساعات إلى يوم كامل، وبعد فعلك لذلك عليك تسجيل الحساب المجاني وضبطه بنفسك. يمكنك قراءة هذا الدرس لشرح طريقة فعل ذلك. الخيارات التجارية الأخرى توفِّر Incapsula خدمة شبيهة بخدمة Cloudflare، وتعطيك خدمات تحسين الأداء والأمان، والخطة المجانية التي توفرها رائعة وهي سهلة الإعداد نسبيًا (ويوفرون لك إضافة ووردبريس لتسهيل دمج الخدمة مع موقعك، لكن قد مضت فترةٌ طويلةٌ منذ آخر تحديث لهذه الإضافة). لكن من مساوئ خدمة Incapsula أنَّ الخطط المدفوعة أغلى من نظيراتها في Cloudflare، لذا إذا أردتَ الحصول على ميزات متقدمة فعليك دفع مبلغ كبير نسبيًا، إذ تبدأ الخطط المدفوعة من 59 دولارًا لكل موقع شهريًا. أما خدمة KeyCDN فهي حلٌّ رخيصٌ نسبيًا لمواقع ووردبريس، وتوفر هذه الخدمة إضافة ووردبريس مُصانة ومُحدَّثة وتستحق التجربة. يجدر بالذكر أنَّ هذه الخدمة لا توفِّر خطة مجانية لكن هنالك فترة تجريبية مجانية، والخطط المدفوعة تبدأ من 0.04 دولار لكل غيغابايت، أي لن تدفع أكثر من دولار واحد شهريًا إلا إذا كان موقعك مشهورًا جدًا. ربما أشهر الخدمات هي خدمة MaxCDN والتي تستخدم من أشهر مواقع التدوين وتُذكَر كثيرًا عند الحديث مع مطوري ووردبريس الآخرين. يمكنك إضافة دعم لخدمة MaxCDN عبر إضافات مثل W3 Total Cache (انظر التوثيق)، وتبدأ الأسعار من 9 دولارًا شهريًا. Fastly هي خدمة CDN تُستعمَل من أكبر المواقع التي تتخصص بالأخبار مثل موقع صحيفة الغارديان البريطانية، وينصحون باستخدام إضافة purgely لدمج الخدمة في موقعك. وصحيحٌ أنَّ Fastly ليست أرخص خدمة CDN لكن هنالك إمكانية تجربة الخدمة بإعطائك 50 دولارًا في حسابك، وأنصحك بتجربة هذه الخدمة إذا كنت جادًا بخصوص تحسين سرعة موقعك. خيارات أخرى إذا أردتَ المزيد من الخيارات والإعدادات فقد تضع ببالك استخدام Amazon Cloudfront أو Google’s Cloud CDN إذا توفر تلك الخدمات تحكمًا دقيقًا وتسعير أكثر مرونة، لكنها تتطلب أن تكون لديك دراية تقنية أكبر. ربما تفكر في الدفع لأحدهم لكي يضبط تلك الخدمات لك لكي تلائم احتياجاتك. الخلاصة إنَّ أفضل خيار هو استخدام خدمة Photon لتخديم الصور مع استخدام Cloudflare لبقية الملفات، وعملية إعداد تلك الخدمات سهلة ولا تأخذ وقتًا طويلًا وستحسِّن سرعة موقعك كثيرًا، مما يرضي زوار موقعك ومحركات البحث. أما إذا كان موقعك أكبر فقد تفكر في استخدام الخدمات المدفوعة التي توفر لك قدرًا كبيرًا من التحكم، وهذه الخدمات التي ناقشناها في هذا الدرس توفِّر مجالًا واسعًا من الخدمات لمختلف أنواع المواقع ولمختلف الميزانيات. الفكرة الرئيسية من استخدام شبكات توزيع المحتوى هي تخديم محتوى الموقع بشكل أسرع إلى المستخدمين، وهذه الخدمات تضبطها لمرة واحدة ثم تنساها، لذا أنصحك بأخذ وقتك لتفكِّر بالخيار الأفضل لجعل موقعك سريعًا. لا تنسَ أنَّ استخدام شبكات توزيع المحتوى هو جزءٌ بسيطٌ من الأحجية التي تجعل موقعك سريعًا، فاستخدام إضافة للتخزين الموقت واختيار قالب سريع والاستضافة في شركة جيدة هي عوامل ستساعد في تسريع موقعك. لذا أنصحك بالاطلاع على الدورة التدريبية Become a WordPress Master التي تعلِّمك المهارات اللازمة لفعل ذلك في ووردبريس. ترجمة –وبتصرّف– للمقال Using CDNs to Unlock a Big WordPress Speed Boost لصاحبه Alex Denning. حقوق الصورة البارزة محفوظة لـ Freepik
  15. تتوسع قواعد البيانات بسرعة مع مرور الزمن، وتكاد في بعض الأحيان أن تملأ المساحة التخزينية المتاحة في نظام الملفات كلها. وقد تتعرض أيضًا إلى مشاكل في الإدخال والإخراج نتيجةً لمحاولة عدِّة خدمات الكتابة على (أو القراءة من) القسم نفسه معًا. هذا الدرس سيفيدك لو كنتَ تريد إضافة المزيد من المساحة التخزينية، أو استخدام خصائص جهاز التخزين لزيادة الأداء (ربما عبر استخدام RAID)، أو تتطلّع إلى استعمال ميزات أخرى للتخزين. سيعلِّمُك هذا الدرس طريقة تغيير مجلد تخزين بيانات MySQL. المتطلبات المسبقة للمتابعة مع هذا الدرس يجب أن يكون عندك: - خادوم CentOS 7 مع حساب مستخدم ليس جذرًا لكنه يمتلك امتيازات الجذر باستعمال الأمر sudo، وفيه خادوم MariaDB مثبت مسبقًا، يمكنك معرفة المزيد من المعلومات حول ضبط CentOS 7 بقراءة درس الضبط المبدئي لخادوم CentOS 7، وإذا لم تثبت MariaDB من قبل، فسيساعدك درس تثبيت وإعداد نظامي إدارة قواعد البيانات MySQL وPostgreSQL على ذلك. سننقل البيانات من جهاز تخزينٍ موصولٍ (mounted) في نقطة الوصل ‎/mnt/volume-nyc1-01. يمكنك معرفة المزيد من المعلومات عن أجهزة التخزين والأقسام وكيفية استخدامها في درس «كيفية إجراء مهام إدارة أجهزة التخزين البسيطة في لينكس». سيعلّمك هذا الدرس طريقة نقل مجلد تخزين بيانات MySQL إلى مكانٍ جديد بغض النظر عن وسيط التخزين الذي تستخدمه (قرص صلب، أو مصفوفة RAID، أو تخزين شبكي). الخطوة الأولى: نقل مجلد بيانات MariaDB لكي نحضِّر لنقل مجلد بيانات MariaDB فلنحاول معرفة مساره الحالي عبر بدء جلسة تفاعلية بتسجيل الدخول بحساب المستخدم root: mysql -u root -p أدخِل كلمة المرور عند طلبها، ثم نفِّذ التعليمة التالية من سطر أوامر mysql: select @@datadir; الناتج: +-----------------+ | @@datadir | +-----------------+ | /var/lib/mysql/ | +-----------------+ 1 row in set (0.00 sec) الناتج السابق يُظهِر أنَّ قواعد MariaDB مضبوطة لاستخدام مجلد تخزين البيانات المبدئي ‎/var/lib/mysql/‎، وهذا هو مسار المجلد الذي علينا نقله؛ نفِّذ الأمر exit للخروج: exit لكي نضمن سلامة البيانات، علينا أولًا إغلاق خادوم MariaDB قبل تعديل مجلد البيانات: sudo systemctl stop mariadb الأمر systemctl لا يُظهِر نتيجة تنفيذ أوامر إدارة الخدمات، لذا إذا أردتَ التحقق أنَّ الخادوم قد أُغلِق بنجاح، فنفِّذ الأمر الآتي: sudo systemctl status mariadb انظر إلى آخر سطر من ناتج الأمر السابق الذي يجب أن يخبرك أنَّ الخادوم قد توقف عن العمل: . . . Dec 16 18:29:26 mysql systemd[1]: Stopped MariaDB database server. سننسخ مجلد قواعد البيانات الموجود حاليًا إلى المكان الجديد باستخدام rsync وذلك بعد إغلاق الخادوم. سنستخدم الخيار ‎-a للحفاظ على الأذونات وخصائص المجلد الأخرى، وسيزودنا الخيار ‎-v بمخرجات توضِّح سير عملية النسخ. ملاحظة: احرص على عدم وجود خط مائل (/) في نهاية مسار المجلد الذي ستُنسَخ البيانات منه، والذي قد يُضاف تلقائيًا إذا كنتَ تُكمِل المسار باستعمال زر tab، فإذا كان الخط المائل موجودًا فسينسخ الأمر rsync المجلد نفسه وليس محتوياته. sudo rsync -av /var/lib/mysql /mnt/volume-nyc1-01 بعد إكمال تنفيذ أمر rsync السابق، فأعد تسمية المجلد الحالية وأضف إليه اللاحقة ‎.bak (لتعرف أنه نسخة احتياطية وليس المجلد الأصل) وأبقِه موجودًا حتى تتأكد من نجاح عملية النقل؛ أعدنا تسميته لتفادي الخلط بين الملفات الموجودة في المكان القديم والجديد: sudo mv /var/lib/mysql /var/lib/mysql.bak سنشرع الآن بتعديل ضبط قواعد البيانات. الخطوة الثانية: الإشارة إلى مكان تخزين البيانات الجديد هنالك طرائق عدِّة لتجاوز القيم المضبوطة في MySQL، إذ تُضبَط التعليمة datadir مبدئيًا إلى ‎/var/lib/mysql في ملف ‎/etc/my.cnf، لذا لنعدِّل هذا الملف لتغيير المسار إلى المجلد الجديد: sudo vi /etc/my.cnf ابحث عن السطر الذي يبدأ بالكلمة datadir=‎ وغيّر المسار الذي يُشير إليه إلى المسار الجديد. ولوجود ملف المقبس (socket file) في مجلد البيانات القديم، فعلينا تحديثه ليشير إلى المكان الجديد أيضًا: [mysqld] . . . datadir=/mnt/volume-nyc1-01/mysql socket=/mnt/volume-nyc1-01/mysql/mysql.sock . . . بعد تحديث الأسطر السابقة الموجودة في الملف، فلنضف ضبطًا خاصًا بعميل mysql وذلك بإضافة الضبط الآتي إلى نهاية الملف (لكي لا نُقسِّم تعليمات الضبط الخاصة بخادوم MySQL إلى قسمين) لكن قبل السطر الذي يحتوي على الكلمة include: [client] port=3306 socket=/mnt/volume-nyc1-01/mysql/mysql.sock !includedir /etc/my.cnf.d بعد أن تنتهي من تعديل الملف، فاضغط على زر Escape ثم اكتب ‎:wq!‎ لحفظ الملف والخروج من المحرر. الخطوة الثالثة: إعادة تشغيل خادوم MariaDB بعد أن حدثنا الضبط ليشير إلى مسار المجلد الجديد، فيمكننا الآن تشغيل خادوم MariaDB والتأكد من عمله بشكل سليم: sudo systemctl start mariadb sudo systemctl status mariadb للتأكد أننا نستعمل المجلد الموجود في المسار الجديد لتخزين البيانات، فسنتصل عبر عميل mysql: mysql -u root -p وننظر إلى قيمة datadir مجددًا: select @@datadir; الناتج: +----------------------------+ | @@datadir | +----------------------------+ | /mnt/volume-nyc1-01/mysql/ | +----------------------------+ 1 row in set (0.01 sec) نفِّذ exit للخروج من العميل. بعد أن أعدت تشغيل خادوم MariaDB وتأكدت أنَّه يستعمل المكان الجديد، فخذ وقتك للتحقق من سلامة بياناتك وأنَّ قواعد بياناتك تعمل دون مشاكل، وبعدئذٍ تستطيع حذف المجلد الاحتياطي بالأمر sudo rm -rf /var/lib/mysql.bak. الخلاصة تعلمنا في هذا الدرس طريقة نقل مجلد بيانات MariaDB إلى مسارٍ جديد، وهذه الطريقة ستعمل مهما كانت تقنية التخزين التي يعتمدها وسيط التخزين الذي ستستعمله. ولمّا كانت قواعد بيانات MariaDB مشتقةً من MySQL، فيمكنك معرفة المزيد من المعلومات حول إدارة مجلدات البيانات في القسمين الآتيين من توثيق MySQL الرسمي: The MySQL Data Directory و Setting Up Multiple Data Directories. ترجمة –وبتصرّف– للمقال How To Change a MariaDB Data Directory to a New Location on CentOS 7 لصاحبته Melissa Anderson