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

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

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

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

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

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

    63

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

  1. تمهيد سنشرح في هذا الدرس كيفية إعداد بيئة برمجية محليّة للغة بايثون 3 في توزيعة أوبنتو 16.04 أو دبيان 8. بايثون هي لغةٌ سهلة القراءة للغاية ومتنوعة ومتعددة الاستخدامات، واسمها مستوحى من مجموعة كوميدية بريطانية باسم «Monty Python»، وكان أحد الأهداف الأساسية لفريق تطوير بايثون هو جعل اللغة مرحةً وسهلة الاستخدام، وإعدادها بسيطٌ، وطريقة كتابتها مباشرة وتعطيك تقريرًا مباشرًا عند حدوث أخطاء، وهي خيارٌ ممتازٌ للمبتدئين والوافدين الجدد على البرمجة. إصدار بايثون 3 هو الإصدار الحالي من اللغة ويُعتَبَر أنَّه مستقبل بايثون. سيُرشِدُك هذا الدرس خطوةً بخطوة إلى كيفية تثبيت بايثون 3 على نظام لينكس المحلي عندك وذلك عبر سطر الأوامر، وصحيحٌ أنَّ هذا الدرس يشرح عملية التثبيت لتوزيعة أوبنتو 16.04 أو دبيان 8، إلا أنَّ المفاهيم الأساسية فيه تنطبق على أيّة توزيعة أخرى. المتطلبات المسبقة يجب أن يكون لديك حاسوبٌ يعمل بتوزيعة أوبنتو 16.04 أو دبيان 8 (أو أيّ إصدار آخر من دبيان)، وأن تكون لديك امتيازات إدارية على النظام، بالإضافة إلى اتصالٍ بالإنترنت. الخطوة الأولى: إعداد بايثون 3 سنُثبِّت ونضبط بايثون عبر سطر الأوامر، والذي هو طريقةٌ غيرُ رسوميةٍ للتعامل مع الحاسوب، فبدلًا من الضغط على الأزرار فستكتب نصًا وتعطيه للحاسوب لينفذه وسيُظهِر لك ناتجًا نصيًا أيضًا. يمكن أن يساعدك سطر الأوامر على تعديل أو أتمتة مختلف المهام التي تنجزها على الحاسوب يوميًا، وهو أداةٌ أساسيةٌ لمطوري البرمجيات، وهنالك الكثير من الأوامر التي عليك تعلمها لكي تتمكن من الاستفادة منه. هنالك مقالات في أكاديمية حسوب (كدرس مدخل إلى طرفيّة لينكس Linux Terminal) ستعلمك أساسيات سطر الأوامر، وهنالك كتاب «سطر أوامر لينكس» الذي يُعتَبر مرجعًا تفصيلًا لطريقة التعامل مع سطر الأوامر. ستجد تطبيق «Terminal» (البرنامج الذي تستعمله للوصول إلى سطر الأوامر) بالضغط على أيقونة Dash في الزاوية العليا اليسرى من الشاشة ثم كتابة «terminal» في شريط البحث، ثم الضغط على أيقونة التطبيق التي ستظهر بعدئذٍ. يمكنك بشكلٍ بديلٍ أن تضغط على Ctrl+Alt+T في لوحة المفاتيح بنفس الوقت لتشغيل تطبيق Terminal. أما على دبيان 8 فيمكنك فتح القائمة الموجودة أيضًا في الزاوية العليا اليسرى من الشاشة ثم البحث عن «terminal» في شريط البحث، ثم النقر على أيقونة التطبيق. يمكنك أيضًا أن تضغط على Ctrl+Alt+T في لوحة المفاتيح بنفس الوقت لتشغيل تطبيق Terminal. تأتي توزيعات أوبنتو 16.04 ودبيان 8 وإصدارات دبيان الأخرى مثبتةً مسبقًا مع بايثون 3 وبايثون 2. للتأكد أنَّك تملك آخر الإصدارات منها فحدِّث نظامك باستخدام apt-get: sudo apt-get update sudo apt-get -y upgrade الخيار ‎-y يعني أنَّك توافق على تثبيت جميع الحزم القابلة للتحديث، لكن قد تحتاج إلى تأكيد ذلك عند تحديث النظام وذلك اعتمادًا على الحزم التي ستُحدَّث ونسخة نظامك. بعد إكمال العملية، يمكننا التحقق من إصدار بايثون 3 المُثبّت في النظام بكتابة: python3 -V ستحصل على مخرجات في نافذة الطرفية والتي ستريك ما هو إصدار بايثون المثبّت. قد يختلف الرقم بناءً على النسخة المثبتة في توزيعتك، لكن يجب أن يكون شبيهًا بما يلي: Python 3.5.2 لإدارة الحزم البرمجية الخاصة ببايثون، فثبّت pip: sudo apt-get install -y python3-pip الأداة pip هي أداةٌ تعمل مع لغة بايثون تُثَبِّت وتدير الحزم البرمجية التي قد نحتاج إلى استخدامها في تطوير مشاريعنا. يمكنك تثبيت حزم بايثون بكتابة الأمر: pip3 install package_name حيث عليك وضع اسم الحزمة أو المكتبة التابعة لبايثون مكان package_name مثل Django لتطوير الويب أو NumPy لإجراء حسابات علمية. لذا إن شئتَ تنزيل NumPy فيمكنك تنفيذ الأمر pip3 install numpy. بعد أن انتهينا من ضبط بايثون وتثبيت pip، فيمكننا الآن إنشاء «بيئة وهمية» (virtual environment) لمشاريعنا. الخطوة الثانية: إعداد بيئة وهمية تُمكِّنك البيئات الوهمية من إنشاء مساحة معزولة في حاسوبك مخصصة لمشاريع بايثون، مما يعني أنَّ كل مشروع تعمل عليه يملك مجموعة من الاعتماديات (dependencies) والتي لن تؤثِّر على غيره من المشاريع. يوفِّر لنا ضبط بيئةٍ برمجيةٍ تحكمًا أكبر بمشاريع بايثون وإمكانية التعامل مع إصداراتٍ مختلفةٍ من حزم بايثون. وهذا مهمٌ كثيرًا عندما تتعامل مع الحزم الخارجية. يمكنك ضبط أيُّ عددٍ تشاء من البيئات الوهمية، وكل بيئة تُمثِّل مجلدًا في حاسوبك الذي فيه عددٌ من السكربتات. علينا أولًا تثبيت وحدة (module) برمجية باسم venv، وهي جزءٌ من مكتبة بايثون3 القياسية، وذلك لكي نتمكن من استخدام الأمر pyvenv الذي سيُنشِئ البيئات الوهمية لنا. لنثبِّت venv على نظامنا بكتابة: sudo apt-get install -y python3-venv سنتمكن الآن من إنشاء بيئات وهمية بعد إتمام التثبيت، لنختار ما هو المجلد الذي سنضع فيه بيئات بايثون، أو لننشِئ مجلدًا جديدًا باستخدام الأمر mkdir كما يلي: mkdir environments cd environments بعد أن انتقلتَ إلى المجلد الذي تريد احتواء البيئات فيه، فتستطيع الآن إنشاء بيئة جديدة بتنفيذ الأمر الآتي: pyvenv my_env سيُنشِئ الأمر pyvenv مجلدًا جديدًا فيه بعض الملفات التي يمكننا عرضها باستخدام الأمر ls: ls my_env bin include lib lib64 pyvenv.cfg share تعمل هذه الملفات مع بعضها لضمان أنَّ مشاريعك معزولةٌ عن بقية النظام، لكي لا تختلط ملفات النظام مع ملفات المشاريع. وهذا أمرٌ حسنٌ لإدارة الإصدارات ولضمان أنَّ كل مشروع يملك وصولًا إلى حزمٍ معيّنة التي يحتاج لها. تتوافر أيضًا Python Wheels والتي هي صيغة بناء حزمٍ لبايثون والتي يمكن أن تُسرِّع من تطوير البرامج بتقليل عدد المرات التي تحتاج فيها إلى بناءٍ (compile) للمشروع، وهي موجودةٌ في مجلد share في توزيعة أوبنتو 16.04 لكنها ستكون في دبيان 8 في أحد مجلدات lib وليس في share. عليك تفعيل البيئة لاستخدامها، وذلك بكتابة الأمر الآتي الذي سيُنفِّذ سكربت التفعيل: source my_env/bin/activate يجب أن تظهر الآن سابقةٌ (prefix) في المِحث (prompt) والتي هي اسم البيئة المستخدمة، وفي حالتنا هذه يكون اسمها my_env، وقد يكون مظهر المِحَث مختلفًا في توزيعة دبيان، وذلك اعتمادًا على الإصدار المستخدم؛ لكن يجب أن تشاهد اسم البيئة بين قوسين في بداية السطر: (my_env) sammy@sammy:~/environments$ السابقة ستسمح لك بمعرفة أنَّ البيئة my_env مفعلة حاليًا، وهذا يعني أننا سنستخدم إعدادات وحزم هذه البيئة عند إنشائنا لمشاريع جديدة. ملاحظة: يمكنك داخل البيئة الوهمية أن تستخدم الأمر python بدلًا من python3 والأمر pip بدلًا من pip3 إن شئتَ. أما إذا كنتَ ستستخدم بايثون 3 خارج البيئة الوهمية، فيجب عليك حينها استخدام python3 و pip3 حصرًا. يجب أن تكون بيئتك الوهمية جاهزةً للاستخدام بعد اتباعك للخطوات السابقة. الخطوة الثالثة: إنشاء برنامج بسيط بعد أن أكملنا ضبط بيئتنا الوهمية، لننشِئ برنامجًا بسيطًا يعرض العبارة «Hello World!‎»، وبهذا سنتحقق من أنَّ البيئة تعمل عملًا صحيحًا، وستصبح طريقة إنشاء برامج بايثون مألوفةً لديك إن كنتَ وافدًا جديدًا على اللغة. علينا أولًا تشغيل محرر ملفات نصية لإنشاء ملف جديد، وليكن المحرر nano الذي يعمل من سطر الأوامر: (my_env) sammy@sammy:~/environments$ nano hello.py بعد فتح الملف في نافذة الطرفية، فاكتب البرنامج الخاص بنا: print("Hello, World!") أغلق محرر nano بالضغط على Ctrl+x ثم اضغط على y عندما يسألك عن حفظ الملف. بعد أن يُغلَق محرر nano وتعود إلى سطر الأوامر، فحاول تشغيل البرنامج: (my_env) sammy@sammy:~/environments$ python hello.py سيؤدي برنامج hello.py الذي أنشأتَه إلى طباعة الناتج الآتي في الطرفية: Hello, World! للخروج من البيئة، فاكتب الأمر deactivate وستعود إلى مجلدك الأصلي. الخلاصة تهانينا! لقد ضبطتَ الآن بيئة تطوير للغة بايثون 3 في جهازك الذي يعمل بتوزيعة أوبنتو أو دبيان، حان الآن الوقت للتعمق بلغة بايثون وإنشاء برامج رائعة! بالتوفيق. ترجمة -وبتصرّف- للمقال How To Install Python 3 and Set Up a Local Programming Environment on Ubuntu 16.04 لصاحبته Lisa Tagliaferri
  2. إذا كنتَ معتادًا على إدارة موقع ووردبريس مفرد، فستجد أنَّ هنالك بعض الاختلافات بين ذلك وبين إدارة شبكة. وستحتاج أيضًا إلى إدارة أيّة مواقع تملكها شخصيًا على شبكتك أيضًا: الموقع الرئيسي مثلًا. أهلًا بك إلى القسم الأخير (المكون من درسين) من الدورة التدريبية الشاملة في ميزة تعدد المواقع في ووردبريس؛ تعلمتَ في هذه السلسلة إلى الآن كيف تُفعِّل ميزة تعدد المواقع وتضبط شبكة من المواقع التي سيُنشئها المستخدمون، وتعلمتَ كيف تستضيف المواقع، وكيف تُطوِّر مجتمعًا. لكن بعد أن تنتهي من فعل كل ذلك، فستحتاج إلى معرفة كيف تدير وتصون شبكتك وتبقها تعمل على أتم وجه. ستتعلم في هذا الجزء (الدرس الحالي والدرس الأخير) كيف ستدير شبكتك بشكلٍ اعتيادي. حيث ستتعلم: الاختلافات الأساسية بين صفحات إدارة الشبكة متعددة المواقع وصفحات إدارة المواقع المفردة المستقلة. كيف تدير المستخدمين وتتفادى نشر محتوى مزعج (spam) وكيف تتفادى إنشاء مدونات تنشر مواد مزعجة (spammy blogs أو اختصارًا splogs). كيف تُبقي على شبكتك مُحدَّثةً دومًا: سواءً بالنسبة إلى نسخة ووردبريس نفسها، أو القوالب والإضافات. سأريك أفضل الممارسات لفعل ذلك. الطرائق التي يمكنك أن تستخدمها لإبقاء شبكتك منسوخةً نسخًا احتياطيًا وكيفية استعادة الشبكة بأكملها أو موقع منها إن حدثت مشكلة. كيفية تحسين الحماية في شبكتك. وفي النهاية، كيف تتأكد أنَّ شبكتك ستعمل بسلاسة وفعالية. لنبدأ بالنظر حول الاختلافات بين صفحات إدارة الشبكة والمواقع التي اعتدت على استخدامها. إدارة الشبكة وإدارة المواقع: الاختلافات الأساسية كمدير للشبكة، ستتمكن من الوصول إلى بعض الصفحات الإدارية الأخرى بالإضافة إلى تلك الصفحات التي تتوفر لك كمدير للموقع. لقد تعاملتَ مسبقًا مع العديد من تلك الصفحات خلال هذه الدورة. هنالك مجموعة كاملة من الصفحات الإدارية التي يمكنك الوصول إليها بالضغط على رابط «My Sites» (مواقعي) في شريط الإدارة، ثم «Netword Admin» (إدارة الشبكة)، الذي سيأخذك إلى لوحة تحكم مدير الشبكة: تحتوي لوحة تحكم مدير الشبكة على: الصفحة الرئيسية وصفحة التحديثات. قسم «Sites» (المواقع)، الذي يتضمن صفحة «All Sites» (كافة المواقع) التي تسمح لك بإدارة المواقع على شبكتك؛ وصفحة «Add New Site» (أضف موقعًا جديدًا) لكي تُنشِئ منها موقعًا جديدًا. قسم «Users» (الأعضاء)، الذي يتضمن صفحة كافة الأعضاء التي تمكنك من مشاهدة وإدارة المستخدمين الموجودين على شبكتك، وصفحة لإضافة مستخدم جديد إلى شبكتك. قسم «Themes» (القوالب)، الذي يتضمن صفحة تمكنك من تفعيل القوالب المثبتة، وصفحة لإضافة القوالب حيث تستطيع فيها تثبيت قوالب جديدة، وهنالك محرر يسمح لك بتعديل الشيفرة الخاصة بالقوالب المثبتة على شبكتك. لا تستعمل صفحة المحرر على الإطلاق! تعديل القوالب هكذا لا يعطيك طريقة لحفظ تعديلاتك، وإن سببتَ بتعطيل قالب، فقد يؤدي ذلك إلى تعطيل كامل شبكتك. إذا احتجت إلى تعديل قالب، فافعل ذلك باستخدام محرر نصي. قسم «Plugins» (الإضافات)، الذي يتضمن صفحة يمكنك فيها تحديث الإضافات، وتفعيل الإضافات التي ثبتَها على كامل الشبكة. وصفحة لتثبيت الإضافات، وصفحة لتحرير شيفرة الإضافة، وأكرِّر أنَّ عليك تفادي استخدام المحرر. قسم «Settings» (الإعدادات)، الذي يتضمن صفحة «Network Settings» (إعدادات الشبكة) التي يمكنك فيها ضبط الشبكة، وصفحة «Network Setup» (تهيئة الشبكة) التي ستتمكن عبرها من الوصول إلى الشيفرة التي يجب وضعها في ملفَي ‎.htaccess و wp-config.php؛ وسيحتوي هذا القسم أيضًا على أيّة صفحات لضبط الإضافات التي ثبتها على شبكتك. إذا كنتَ عضوًا في WPMU DEV فستملك وصولًا إلى WPMU DEV Dashboard، التي يمكنك استخدامها لتثبيت وإدارة القوالب والإضافات الخاصة بموقع WPMU DEV: إذا تابعتنا عبر الأقسام السابقة من هذه السلسلة، فمن المرجح أنَّك استخدمتَ العديد من الصفحات السابقة: في مقدّمة هذه السلسلة، اطلعتَ على لمحة عن الصفحات السابقة والفرق بينها وبين صفحات لوحة تحكم إدارة الموقع. في قسم «التفعيل والضبط»، استخدمتَ صفحة «Network Setup» (تهيئة الشبكة) للوصول إلى الشيفرة التي عليك إضافتها إلى ملفَيwp-config.php و ‎.htaccess؛ ثم استخدمتَ قسم «Users» (أعضاء) وقسم «Sites» (المواقع) لإضافة مواقع ومستخدمين جدد؛ واستعملتَ قسمَي «Themes» (القوالب) و «Plugins» (الإضافات) لتثبيت وتفعيل القوالب والإضافات. في قسم «تسجيل المستخدمين والمواقع» ، استخدمتَ صفحة «Network Settings» (ضبط الشبكة) لتضبط عملية تسجيل المستخدمين والمواقع، وقسم «Users» (أعضاء) لمشاهدة وتعديل بيانات المستخدمين الجدد. في قسم «مواقع العملاء وربط النطاقات»، استخدمتَ صفحة ضبط Domain Mapping التي وضعتها إضافة Domain Mapping في قسم «Settings» (الإعدادات). في قسم «إنشاء مجتمع»، استخدمتَ الصفحات الجديدة التي وفرتها الإضافات في قسم «Settings» (الإعدادات)، بالإضافة إلى صفحة «Plugings» (الإضافات) ولوحة تحكم WPMU DEV لتثبيت وتفعيل إضافات على كامل الشبكة بغرض إدارة المجتمع. أما في الجزء الحالي من السلسلة، فسنزور بعض الصفحات السابقة، وسنستخدم أخرى جديدة خاصة بالإضافات. إدارة المستخدمين وتفادي المحتوى المزعج طريقة تخزين معلومات المستخدمين في شبكة متعددة المواقع تختلف قليلًا عن المواقع المفردة. كل مستخدم مسجل في أحد المواقع على شبكتك يملك سجلًا وحيدًا في قاعدة البيانات، وسيكون مستخدمًا لكامل شبكتك. لكن ذلك لا يعني أنَّه يملك وصولًا إلى كامل الشبكة: حيث ستُخزِّن ووردبريس بيانات وصفية (metadata) مرتبطة بكل مستخدم التي تُشير إلى ما هي المواقع التي يملك وصولًا لها وبأي درجة من الامتيازات. لذا يمكن لشخصٍ وحيد أن يكون مديرًا لأحد المواقع، وكاتبًا في آخر، ومشتركًا في عدِّة مواقع أخرى. سيملك هذا الشخص سجلًا وحيدًا في جدول wp-users في قاعدة البيانات، ولن يكون له أكثر من سجل منفصل لكل موقع على الشبكة. هذا يعني أنَّ المستخدمين يمكن أن يُضافوا من قِبلك (كمدير للشبكة) أو من قِبل مدراء المواقع. يمكن لمدير الموقع أن يُضيف مستخدمًا جديدًا إلى موقعه وإلى شبكتك (إن سمحتَ بذلك بالطبع)، ويمكنهم أيضًا –أي مدراء المواقع– أن يُضيفوا مستخدمًا موجودًا في الشبكة إلى موقعهم. إن لم تُفعِّل إمكانية إنشاء مستخدمين جدد من قِبل مدراء المواقع، فسيتمكنون فقط من إضافة أعضاء موجودين مسبقًا في الشبكة إلى مواقعهم. يمكنك –كمدير للشبكة– أن تُدير المستخدمين عبر صفحة «Users» (أعضاء) في لوحة تحكم الشبكة: يمكنك هنا أن تُعدِّل بيانات أحد المستخدمين أو تحذفهم، بنفس الطريقة التي اعتدتَ على استعمالها في المواقع المفردة. في الجزء الثالث من هذه الدورة « تسجيل المستخدمين والمواقع»، تعلمتَ كيف تضبط تسجيل المستخدمين والمواقع، سامحًا بتسجيل المستخدمين في شبكتك وإنشائهم لمواقعهم الخاصة؛ لكن ماذا لو بدأ أولاءك المستخدمون بإنشاء مدونات مزعجة (splogs) على شبكتك؟ هنالك طريقتان لمنع ذلك: تغيير الضبط لمنع إنشاء المواقع إلا من المستخدمين الموجودين مسبقًا أو من الأشخاص الذين يملكون عنوان بريد إلكتروني موجود على نطاق معيّن. استخدام إضافة مضادة للمدونات المزعجة. الخيار الأول أبسط، والذي هو الحاجة إلى تغيير ضبط الشبكة. ولفعل ذلك، اذهب إلى «Settings > Network Settings» (الإعدادات > إعدادات الشبكة) ثم انتقل إلى قسم «Registration Settings» (إعدادات التسجيل): تملك بعض الخيارات لتقليل عدد المدونات المزعجة: غيّر خيار «Allow new registrations» (السماح بالتسجيل) إلى «Logged in users may register new sites» (السماح للأعضاء المتصلين بتسجيل مواقع جديدة). استخدم حقل «Banned Names» (الأسماء الممنوعة) لحجب أيّة أسماء يستعملها المستخدمون المزعجون لإنشاء مواقع جديدة. استخدم حقل «Limited Email Registrations» (نطاقات البريد الإلكتروني المسموحة) لتقييد إمكانية إنشاء مواقع جديدة إلى أشخاصٍ يملكون بريدًا إلكترونيًا ينتمي إلى أحد النطاقات التي تُحدِّدها في هذا الحقل. هذا الخيار مفيدٌ إن كانت شبكتك تابعةً لمنظمةٍ التي يملك كلُ شخصٍ فيها عنوان بريد متشابه، لكن هذا الخيار سيكون مُقيِّدًا لشبكتك إن كانت مفتوحةً وعامةً. استخدم حقل «Banned Email Domains» (نطاقات البريد الإلكتروني الممنوعة) لتحديد أسماء نطاقات البريد الإلكتروني التي يستعملها المستخدمون المزعجون لإنشاء مواقع على شبكتك. إذا كنتَ ترغب أن يُسجِّل عندك أكبر قدر ممكن من المستخدمين غير المزعجين، فلن ترغب باستخدام الأشياء السابقة، وفي هذه الحالة، يمكنك استخدام إضافة Anti-Splog للتخلص من المستخدمين المزعجين. حجب المدونات المزعجة باستخدام إضافة Anti-Splog إضافة Anti-Splog ذات مستوى أعلى من الإضافات العادية، حيث تسمح لك بالوصول إلى مستودع كبير من البيانات الذي يحتوي معلومات حول المدونين المزعجين ومن أين يأتون؛ وبناءً على المعلومات المجموعة من المستخدمين الآخرين لهذه الإضافة ومن شبكة Edublogs، ستتمكن من الوصول إلى قاعدة بيانات تحتوي على معلومات المستخدمين المزعجين، وهذا يعني أنَّ الإضافة ستستخدم تلك المعلومات لحجب أولاءك الأشخاص الذين لا تريد أن تسمح لهم بإنشاء موقع على شبكتك. هذه الإضافة شبيهة بإضافة Akismet لكن للشبكات. لنبدأ بإعداد الإضافة على الشبكة, علينا أولًا تثبيتها وتفعيلها على عموم الشبكة من لوحة تحكم WPMU DEV. ستُنشِئ هذه الإضافة قسمًا جديدًا في قائمة لوحة تحكم مدير الشبكة اسمه Anti-Splog. لضبط هذه الإضافة وجعلها تعمل، اذهب إلى «Anti-Splog > Settings»: سترى تحذيرًا يخبرك أنَّك ستحتاج إلى إدخال مفتاح API الخاص بك قبل أن تعمل هذه الإضافة. ولفعل ذلك، انقر على رابط «Get your API key and register your server here» في الصفحة السابقة، والذي سيأخذك إلى صفحة «Anti-Splog API» في حساب WPMU DEV الخاص بك: مرِّر إلى الأسفل لتصل إلى قسم «Register a Site»، ويجب أن يكون نطاق شبكتك موجودًا مسبقًا في حقل «Multisite Domain». تحقق من صحته وغيّره إلى النطاق الصحيح لشبكتك إن لزم الأمر؛ ثم اضغط على زر «Add Site». يجب أن يُضاف الموقع إلى قائمة المواقع المسجلة. انسخ الآن مفتاح API واذهب إلى موقعك مرةً أخرى، وافتح صفحة ضبط إضافة Anit-Splog والصق المفتاح في حقل «API Key». ثم اضغط على زر «Check Key» للتحقق منه. إذا جرى كل شيءٍ على ما يرام، فسيُحفَظ مفتاح API وسيتحول لون الحقل إلى اللون الأخضر. إذا لم يعمل، فارجع إلى صفحة Anti-Splog API وتحقق أنَّك أدخلتَ النطاق بشكلٍ صحيح. ملاحظة: إذا كانت شبكتك مثبتةً في مجلدٍ فرعي من نطاقك الرئيسي، فاستخدم النطاق الرئيسي لتسجيل موقعك، وليس النطاق الكامل. هنالك شيءٌ آخر عليك فعله قبل أن تبدأ باستخدام الإضافة الذي هو نقل ملف blog-suspended.php من الإضافة إلى مجلد wp-content. ولفعل ذلك ستحتاج إلى وصول FTP إلى خادومك. افتح عميل FTP (ربما يكون جزءًا من محررك النصي أو قد يكون عميلًا منفصلًا مثل FileZilla)، واذهب إلى مجلد wp-content/plugins/anti-splog واعثر على ملف blog-suspended.php. إن لم تجده هناك، فافتح مجلد ‎/includes وستجد ملفًا باسم blog-suspended-template.php، فانسخه وأعد تسميته إلى blog-suspended.php. انقل ذاك الملف إلى مجلد wp-content. ارجع إلى موقعك وأعد فتح صفحة ضبط إضافة Anti-Splog، أو حدِّثها إن كنتَ فيها. ستلاحظ اختفاء رسالة التحذير التي تطلب منك أن تنقل الملف: ملاحظة: إذا بقيت رسالة التحذير موجودةً، فتأكَّد أنَّك نقلتَ الملف إلى المكان الصحيح، وأعدتَ تسميته بالاسم المناسب إن أنشأتَ نسخةً من ملف blog-suspended-template.php. عليك الآن ضبط الإضافة. تملك إضافة Anti-Splog الكثير من خيارات الضبط، وعلى الرغم من أنَّك بدأتَ لتوِّك في استخدامها، لكن من الأفضل البدء باستخدام الخيارات الافتراضية ثم تعديلها مع مرور الوقت إن احتجت إلى ذلك. يمكنك معرفة المزيد عن خيارات الضبط في لسان «Usage» في صفحة الإضافة على WPMU DEV: جعل شبكتك محدَّثةً دومًا جزءٌ مهمٌ من عملية إدارة الشبكة هو إبقاء الشيفرات البرمجية محدثةً دومًا، وهذا يضمن لك أنَّك تعمل على آخر وأكثر نسخة أمانًا من الشيفرات البرمجية التي تحتوي على تحسينات في الشيفرة أو حلول لبعض العلل. لكن عليك اختبار أيّة تحديثات على نسخة من شبكتك قبل تحديث موقعك الإنتاجي. إذا سبب تحديثٌ ما مشاكل، فقد يؤثر ذلك على جميع مواقع الشبكة ولن يكون عملاؤك أو مستخدموك سعداء بذلك، لذا عليك أن تتحقق من عدم حدوث أيّة مشاكل عند التحديث. نصائح لإبقاء شبكتك محدَّثةً لإبقاء شبكتك محدثةً دون مواجهة أيّة مشاكل، فالتزم بتطبيق هذه النصائح: أنشِئ نسخةً محليةً من شبكتك على حاسوبك المحلي (ربما باستخدام MAMP). الخطوات مماثلة لإنشاء نسخة من موقع ووردبريس مفرد، ويمكنك أن تتعلم فعل ذلك بالتفصيل في درس كيفية تنصيب ووردبريس محليا باستخدام MAMP، استخدم هذا الموقع لتجربة التحديثات. بشكلٍ بديل، من الأفضل إنشاء نسخة من شبكتك على نفس الخادوم. هذا أفضل لأنَّ البيئة التي تجرِّب عليها مماثلة للشبكة الإنتاجية، لذا ستتمكن من معرفة أيّة مشاكل تتعلق بالخادوم عند تجربتك للتحديث. استشر مزود خدمة الاستضافة ليساعدك في إنشاء هذه النسخة. خذ نسخًا احتياطيةً من شبكتك، فلو واجهتَ أيّة مشاكل مع التحديثات، فيمكنك بسرعة أن تعود إلى النسخة غير المحدثة من شبكتك. سنفصِّل ذلك في الدرس القادم. استخدم إضافة Multisite Enhancements لكي ترى ما القوالب أو الإضافات التي تستعملها المواقع الموجودة في شبكتك. وبهذا ستعلم أيّ المواقع التي عليك اختبارها عندما تُحدِّث قالبًا أو إضافةً ما. تحديث ووردبريس نفسها أو قالب أو إضافة هو أمرٌ لا يستطيع فعله إلا مدير الشبكة. أي أنَّ مدراء المواقع لا يستطيعون فعل ذلك، ولن يستطيعوا أن يروا إشعارات التحديثات في لوحة التحكم الخاصة بهم. لننظر الآن إلى كيفية تحديث إضافة، على سبيل المثال. تحديث إضافة عندما يجب تحديث إضافة مثبتة على شبكتك، فستجد دائرةً حمراء صغيرة بجوار عنصرّي «Updates» (تحديثات) و «Plugins» (إضافات) في قائمة لوحة التحكم. عندما تذهب إلى صفحة «Updates» (تحديثات) فستشاهد كل الإضافات القابلة للتحديث فيها: لتحديث إضافة، فاخترها ثم اضغط على زر «Update Plugins» (تحديث الإضافات). ستُحدِّث ووردبريس الإضافة وستُعلِمُك عندما ينتهي الأمر: ملاحظة: يمكنك تحديث الإضافات من صفحة «Plugins» (الإضافات)، حيث يمكنك تحديث كل إضافة على حدة باستخدام بالنقر على الرابط أسفل اسمها. والأمر سيانٌ للقوالب. بعد أن تفعل ذلك على النسخة الاختبارية من شبكتك وتجرِّب الإضافة المحدثة، فيمكنك أن تفعل المثل لشبكتك الإنتاجية. ترجمة –وبتصرّف– للمقال WordPress Multisite Masterclass: Managing your Network لصاحبته Rachel McCollin.
  3. تمهيد OwnCloud هو خادوم مشاركة ملفات الذي يسمح لك بتخزين المحتوى الخاص بك مثل المستندات والصور في مكانٍ مركزي بشكلٍ يشبه خدمة Dropbox. الاختلاف بينهما هو أنَّ ownCloud هو برمجية حرة ومفتوحة المصدر، مما يسمح لأي شخص باستخدامه وتفحّص شيفرته، وهذا يعني أيضًا تحكمك بأمان وحماية بياناتك المهمة تمامًا مما يجنِّبُك استخدام خدمات استضافة من طرفٍ آخر. سنُثبِّت ونضبط في هذا الدرس نسخة من ownCloud على خادوم أوبنتو 16.04. المتطلبات المسبقة ستحتاج إلى ما يلي لإكمال الخطوات المذكورة في هذا الدرس: الوصول إلى مستخدم بامتيازات الجذر على خادومك: يُمكنك اتباع هذا الدّرس لإنشاء مستخدم يملك وصولًا إلى امتيازات الجذر عبر الأمر sudo. خدمات LAMP: يتطلب ownCloud وجود خادوم ويب وقاعدة بيانات ومُفسِّر PHP لكي يعمل بشكلٍ صحيح؛ إذا أعددتَ خدمات LAMP (أي Linux و Apache و MySQL و PHP) فستُحقِّق هذا الشرط. يشرح لك هذا الدرس كيفية تثبيت وضبط تلك الخدمات. شهادة SSL: طريقة ضبط الشهادة تختلف فيما إذا كنتَ تملك اسم نطاق (domain name) ليشير إلى خادومك أم لا. إذا كان لديك اسم نطاق فأسهل طريقة لتأمين موقعك هي استخدام «Let’s Encrypt» والذي يوفِّر لك شهادات مجانية وموثوقة، راجع درس تنصيب شهادة SSL مجانية عبر خدمة Let’s encrypt على خادوم لينكس لمزيدٍ من المعلومات. إذا لم يكن لديك نطاق، وكنت تتبع هذا الدرس لتجربة ownCloud أو لاستخدامه استخدامًا شخصيًا، فيمكنك إنشاء شهادة موقّعة ذاتيًا؛ والتي ستوفِّر نفس نوع التشفير، لكن دون التحقق من هوية النطاق. اتبع درس كيفية إنشاء شهادات SSL موقعة ذاتيًا لمزيدٍ من المعلومات. الخطوة الأولى: تثبيت ownCloud لا تتوافر حزمة ownCloud في مستودعات أوبنتو الافتراضية، لكن برمجية ownCloud توفِّر مستودعًا خاصًا لتوزيعة أوبنتو. علينا أولًا تنزيل مفتاح الإصدارة (release key) باستخدام الأمر curl ثم استيراد ذاك المفتاح باستخدام الأمر apt-key: curl https://download.owncloud.org/download/repositories/stable/Ubuntu_16.04/Release.key | sudo apt-key add - ... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1358 100 1358 0 0 2057 0 --:--:-- --:--:-- --:--:-- 2057 OK يحتوي الملف Release.key على مفتاح PGP عمومي الذي يمكن للأداة apt استخدامه للتأكّد أنَّ الحزم التي سننزلّها لبرمجية ownCloud هي حزمٌ موثوقة. إضافةً إلى استيراد المفتاح، يجب علينا إنشاء ملف باسم owncloud.list فيه عنوان مستودع ownCloud في مجلد sources.list.d التابع للأداة apt: echo 'deb http://download.owncloud.org/download/repositories/stable/Ubuntu_16.04/ /' | sudo tee /etc/apt/sources.list.d/owncloud.list نفِّذ الأمر apt-get update بعد إضافة المستودع الجديد لكي نُعلِمَ apt بالتغيير الذي أحدثناه: sudo apt-get update أخيرًا، نستطيع تثبيت ownCloud باستخدام الأمر apt-get install: sudo apt-get install owncloud ونتيجةً لتثبيت ownCloud سيُضاف ملفُ ضبطٍ جديدٍ إلى مجلد ضبط أباتشي (Apache)؛ استخدم الأمر systemctl لإعادة تشغيل أباتشي لكي يقرأ ملف الضبط: sudo systemctl restart apache2 بعد تثبيت خادوم ownCloud، حان الوقت لضبط قاعدة البيانات للاستخدام. الخطوة الثانية: ضبط قاعدة بيانات MySQL علينا بادئ الأمر أن نُسجِّل دخولنا إلى MySQL بحسابٍ له امتيازاتٌ إدارية: mysql -u root -p أدخِل كلمة المرور التي ضبطتها للمستخدم root التابع لقاعدة بيانات MySQL عندما ثبّتَها. يجب إنشاء قاعدة بيانات منفصلة لخادوم ownCloud لتخزين البيانات الإدارية، وصحيحٌ أنَّ تستطيع تسمية قاعدة البيانات بأيِّ اسمٍ تشاء، لكنني فضَّلتُ استخدام owncloud لتبسيط الأمور. نفِّذ الأمر الآتي في سطر أوامر MySQL: CREATE DATABASE owncloud; ملاحظة: يجب أن تنتهي جميع أوامر وتعابير MySQL بفاصلة منقوطة ;، تأكّد أنَّك لم تنسها إن واجهت أيّة مشاكل عند تنفيذ الأوامر المذكورة هنا. أنشِئ بعد ذلك مستخدمًا جديدًا في MySQL للتعامل مع قاعدة البيانات الجديدة. إنشاء قواعد بيانات ذات غرضٍ وحيد وإنشاء مستخدمين مخصصين لإدارتها هو أمرٌ حسنٌ من ناحية سهولة الإدارة والأمان. وكما عند تسمية قاعدة البيانات، اختر ما تشاء اسمًا للمستخدم، إلا أنَّنا اخترنا الاسم owncloud في هذا الدرس. نفِّذ الأمر الآتي في سطر أوامر MySQL: GRANT ALL ON owncloud.* to 'owncloud'@'localhost' IDENTIFIED BY 'set_database_password'; تنويه: ضع كلمة مرورك في الأمر السابق بدلًا من set_database_password. بعد السماح للمستخدم الجديد بالوصول إلى قاعدة البيانات، فحدِّث امتيازات الوصول لكي تضمن أنَّ النسخة الحالية التي تعمل من MySQL تعرف عن التعديلات الأخيرة التي أجريتَها: FLUSH PRIVILEGES; لقد انتهى ضبطنا لقاعدة MySQL، وبالتالي يمكننا الخروج من جلسة MySQL بكتابة: exit بعد تثبيت ownCloud وضبط قاعدة بياناته، فنحن الآن جاهزون لضبط خادوم ownCloud نفسه. الخطوة الثالثة: ضبط ownCloud للوصول إلى واجهة الويب التابعة لبرمجية ownCloud فافتح متصفح الويب واذهب إلى الرابط الآتي: https://server_domain_or_IP/owncloud إذا استخدمتَ شهادةً موقعةً ذاتيًا، فسترى تحذيرًا لأنَّ الشهادة غير موقعة من سلطة يثق بها متصفحك. لا تقلق، هذا طبيعيٌ جدًا، إذا كنتَ مهتمًا بالتشفير وليس بالتحقق من صحة الشهادة، فاضغط على الزر أو الرابط الملائم للمتابعة إلى صفحة إدارة ownCloud. ستبدو الصفحة شبيهةً بما يلي: أنشِئ الآن حساب مدير باختيار اسم مستخدم (لا يجدر بك استخدام اسم مثل «admin» لأسبابٍ أمنية) وكلمة مرور. قبل الضغط على زر «Finish setup» فاضغط على رابط «Storage & database»: اترك خيار «Data folder» كما هو واضغط على زر «MySQL/MariaDB» في قسم «Configure the database»، أدخِل معلومات قاعدة البيانات والتي ضبطتها في الخطوة السابقة. ما يلي هو مثالٌ يُطابِق معلومات قاعدة البيانات التي أدخلناها منذ قليل: اضغط على زر «Finish setup» للتسجيل في ownCloud. ستظر نافذة بعنوان «A safe home for all your data»: اضغط على إشارة × في الزاوية العليا اليمنى من النافذة لكي تصل إلى الواجهة الرئيسية: يمكنك من تلك الواجهة إنشاء أو رفع الملفات إلى منصة التخزين السحابي الخاصة بك! الخلاصة يملك ownCloud أغلبية ميزات خدمات التخزين السحابي، حيث يمكن مشاركة المحتوى بين المستخدمين أو عبر روابط URL عامة. ميزة استخدام ownCloud هي تخزين البيانات بأمان في مكانٍ تتحكم فيه أنت. استكشف الواجهة وتثبّت بعض الإضافات عبر متجر ownCloud لمزيدٍ من الميزات. ترجمة -وبتصرّف- للمقال How To Install and Configure ownCloud on Ubuntu 16.04 لصاحبه Michael Lenardson
  4. يمكن أن تكون الغاية من شبكة متعددة المواقع أكثر من مجرد إنشاء مجموعة من المواقع، إذ يمكن أن تُشكِّل مجتمعًا. وستوفِّر لمستخدمي شبكتك طريقةً رائعةً لإنشاء مواقع ومحتوى خاص بهم، ويمكنك أيضًا أن تُقرِّب بين أولائك المستخدمين. الشبكات متعددة المواقع الكبيرة مثل WordPress.com و Edublogs تُساعِد مُستخدميها لكي يعثروا على محتوى رائع ويتواصلوا مع بعضهم بعضًا وذلك بارتباطهم كمجتمع. هنالك عدِّة خيارات متاحةٌ لك للقيام بذلك، والتي تعتمد على طبيعة شبكتك وعلى احتياجات مستخدميك، بعض هذه الخيارات يُمكن أن يُضاف خلال توسّع شبكتك لكنه بعضها الآخر يجب أن يُضبَط منذ البداية. هذا هو الدرس الثامن في سلسلتنا المكونة من عشرة دروس التي تشرح التعامل مع الشبكات متعددة المواقع في ووردبريس، ستتعلم في هذه السلسلة كل ما تحتاج له لكي تُنشِئ شبكتك، وتضيف المواقع إليها أو تسمح للمستخدمين بذلك، بالإضافة إلى إدارة الشبكة. وستتعلم كيف تتأكد أنَّ شبكتك آمنة وأداؤها عالٍ، وكيف يمكنك أن تُنشِئ مجتمعًا ناجحًا من المستخدمين والمواقع. ستتعلم في هذا الدرس عن: إنشاء شبكة اجتماعية في موقعك الرئيسي مع إتاحة خيار للمستخدمين لكي يُنشِئوا مدونات خاصة بهم. السماح للمستخدمين بمشاهدة محتوى المستخدمين الآخرين في لوحة التحكم، وعرض المحتوى المُفضّل عندهم والموجود في الشبكة على موقعهم الخاص. عرض المحتوى الجديد أو المُميّز في الشبكة (بما في ذلك المنشورات والتعليقات) في موقعك الرئيسي، وحثّ الزوار على تصفح بقية المواقع على الشبكة. عرض المحتوى الجديد أو المُميّز في الشبكة على مواقع أخرى فيها. السماح لمستخدميك بالتواصل المباشر بين بعضهم وذلك بجعلهم «أصدقاء» عبر لوحة التحكم. من غير المحتمل أن تفعل كل ما سبق، ولهذا يُفضَّل أن تأخذ بعض الوقت في التخطيط لمجتمعك أولًا وتتعرف على احتياجات مستخدميك وما الذي عليك توفيره لهم. لنبدأ. استخدام شبكة متعددة المواقع كمجتمع: أمثلة حقيقية أكبر شبكتين متعددتي المواقع في العالم يُمثِّلان مجتمعًا للمستخدمين والقراء. يحثّ موقعا WordPress.com و Edublogs المستخدمين على متابعة بعضهم والاستفادة من محتوى الآخرين. إذا كنتَ مستخدمًا لمنصة WordPress.com أو نظام Calypso الجديد للإدارة أو كنت تستعمل نسخة ووردبريس مفردة، فستتمكن من الوصول إلى Reader، الذي يمكِّنك من قراءة المحتوى الجديد في المدونات التي تتابعها: ولدى Edublogs ميزة Reader في لوحة التحكم، التي تسمح لك برؤية آخر المحتوى المنشور في مواقعك المفضَّلة على الشبكة: سأريك في هذا الدرس كيف تستخدم بعض الإضافات المتاحة لمجتمع Edublogs لكي تتمكن من إعداد مجتمع خاص بك. التعرف على احتياجات مجتمعك قبل أن تضبط مجتمعًا وتُقرِّر ما هي الإضافات التي ستحتاج إلى استخدامها، عليك أن تتعرف على احتياجات المجتمع وكيف سيعمل. اسأل نفسك الأسئلة الآتية: هل سيكون تفاعل المستخدم في الموقع الرئيسي، أم في لوحة التحكم الخاصة بمواقعهم؟ هل سيحتاج المستخدمون إلى إنشاء أحداث (events) ومجموعات …إلخ. لدعم نشاط المجتمع؟ هل سيتمكن المستخدمون من الوصول بسهولة إلى محتوى المواقع الأخرى في الشبكة؟ هل سيتمكن المستخدمون من مشاركة المحتوى المنشور من المستخدمين الآخرين؟ هل سيحتاج المستخدمون إلى تفاعلات اجتماعية بما في ذلك المنشورات والتعليقات والنقاشات؟ ما هو المحتوى الذي ستعرضه أو تشاركه في موقعك الرئيسي؟ ما هي نسبة المحتوى المعروض لعامة الزوار، وما هي نسبة المحتوى الخاص بمستخدمي الشبكة؟ الإجابات عن الأسئلة السابقة ستُحدِّد مدى امتداد شبكتك تحت أحد العناوين الآتية: التفاعلات الاجتماعية، واستهلاك المحتوى، ومشاركة المحتوى. ربما يكون أحدها هو الهدف الرئيسي من شبكتك، واحتمال أن يكون الخياران الآخران ثانويين. على سبيل المثال: شبكة يكون غرضها الأساسية هو تمكن عملية إنشاء المدونات (مثل Edublogs أو WordPress.com) ستركِّز على ذلك، وتُضيف إمكانية مشاركة المحتوى المُنشَأ على تلك المدونات وأيّة جوانب اجتماعية كميزات في الواجهة الأمامية (front-end) والسند الخلفي (backend). موقع يهدف إلى إنشاء تواصل اجتماعي بين أعضاء المجتمع سيُركِّز على جعل ذلك يعمل بشكل جيد في الموقع الرئيسي، مع إمكانية السماح للمستخدمين بإنشاء مواقع خاصة بهم. قد يكون BuddyPress هو أهم مكوِّن في مثل هكذا مواقع. إذا أردت أن تسمح للمستخدمين المحتملين بأخذ عينة من المحتوى على شبكتك، فستركِّز على الإضافات التي تسمح لك بمشاركة المحتوى المنشور في الشبكة في الواجهة الأمامية لموقعك، لكي يتمكن الزوار من قراءته. لننظر الآن إلى ما سبق بالتفصيل. الاستفادة من المحتوى المنشور على الشبكة يسمح موقع Edublogs و WordPress.com للمستخدمين برؤية المحتوى الجديد من أرجاء الشبكة في لوحة التحكم الخاصة بهم، وهذا يعني أنَّه في كل مرة يُسجِّل المستخدم دخوله فيها، فسيرى ما الذي نشره المستخدمون الآخرون. وهذا يحثّ ويشجِّع المستخدمين على تصفح الشبكة والاستفادة من المحتوى بالإضافة إلى تشجيع نشرهم لمحتوى جديد على أمل أن يراه الآخرون ويبدؤوا متابعتهم. لننظر إلى كيفية إعداد ذلك في الشبكة باستخدام إضافة Reader. قبل أن تبدأ: تثبيت إضافة Post Indexer قبل تبدأ بتثبيت أيّة إضافات للمشاركة والاستفادة من المحتوى الموجود على الشبكة، فستحتاج إلى تثبيت وتفعيل إضافة Post Indexer على جميع مواقع الشبكة. وهذا ضروريٌ لكي تعمل الإضافات مثل Reader، و Recent Global Posts، و Recent Global Comments (التي سنتحدث في أمرها قريبًا). ثبِّت إضافة Post Indexer من صفحة تحكم WPMU DEV في موقعك، ثم تأكَّد أن الإضافة مُفعَّلة لعموم الشبكة. لن تحتاج إلى ضبط أيّة إعدادات لهذه الإضافة، فستعمل عملها تلقائيًا دون تدخل. تثبيت وضبط إضافة Reader عليك الآن تثبيت إضافة Reader عبر لوحة تحكم WPMU DEV وتفعيلها على عموم الشبكة. لضبط الإعدادات اللازمة لهذه الإضافة، فاذهب في لوحة تحكم الشبكة إلى «Settings > Reader»: يمكنك هنا أن تُحدِّد كيف سيعمل Reader. في أول قسم «Where should the Reader be?‎» (أين يجب أن تظهر إضافة Reader) اختر «The Reader should replace the default WordPress Dashboard Home page» (يجب أن تستبدل إضافة Reader الصفحة الرئيسية للوحة التحكم). ثم اختر ما هي الأمور التي تريد من Reader عرضها في القسم الذي يليه. اضغط على زر «Save Changes» لحفظ الإعدادات. بعد أن تفعل ذلك، انتقل إلى لوحة التحكم لأحد المواقع التي تديرها. هذه صورة للموقع الرئيسي عندي: يجب أن تكون متابعًا لموقعك افتراضيًا. ستُعرَض المنشورات الحديثة من ذاك الموقع في الصفحة الرئيسية للوحة التحكم؛ وإذا لم يُعرَض أيُّ شيءٍ، فأنشِئ بعض المنشورات! :-) متابعة المواقع الأخرى في الشبكة مستخدمو شبكتك –سواءً كانوا مدراء للمواقع أم لم يكونوا كذلك– يستطيعون أن يتابعوا بعضهم بعضًا على الشبكة. وسيظهر محتوى من تلك المواقع في لوحة التحكم. للعثور على مواقع لكي تتابعها، فابحث عن عنوان أحد المنشورات، أو ابحث عبر وسمٍ (tag) ما، أو عبر كاتبٍ معيّن. من صفحة Reader، اكتب عبارة البحث في حقل البحث الموجود في الزاوية العليا اليمنى، واختر ما الذي تريد البحث عنه (عنوان [Title]، أو كاتب [Author]، أو وسم [Tag])، ثم اضغط على زر «Search». وستشاهد جميع المنشورات التي تُطابِق عبارة البحث: يمكنك عرض تلك المنشورات بالضغط فوقها أو يمكنك متابعة المدونات بالنقر فوق زر «Follow» الظاهر أسفل كل منشور في صفحة نتائج البحث. ستظهر منشورات المدونة التي تابعتها الآن في صفحة Reader: يمكن للمستخدمين أن يعثروا على مواقع ليتابعوها إذا شاركتَ المحتوى المُميّز أو آخر المنشورات على موقعك الرئيسي. ثم الضغط على ذاك المحتوى والنقر فوق أيقونة «Follow» على الشريط الإداري عند تصفح الموقع. ستتعلم في القسم التالي عن كيفية مشاركة المحتوى على موقعك الرئيسي. مشاركة المحتوى عبر الشبكة بالإضافة إلى قراءة محتوى مأخوذ من الشبكة في لوحة التحكم، يمكنك أنت ومستخدموك أن تُشاركوا المحتوى عبر الشبكة على الواجهة الأمامية لمواقعكم. هنالك عدِّة طرائق لفعل ذلك: مشاركة المحتوى الذي تتابعه عبر Reader، باستخدام ودجة (widget) توفرها إضافة Reader. استخدام شيفرة مُختصرة (shortcode) لمشاركة المنشورات على صفحة في موقعك الرئيسي باستخدام إضافة Recent Global Posts. استخدام ودجة لمشاركة المنشورات على الشريط الجانبي أو التذييل، وذلك باستخدام إضافة Recent Global Posts Widget. إضافة ودجة للتعليقات على الشريط الجانبي أو على التذييل باستخدام إضافة Recent Comments Widget. استخدام إضافة Live Stream Widget لعرض حيّ لآخر المحتوى في شبكتك في أيّة منطقة مخصصة للودجات. كما ترى، هنالك خياراتٌ كثيرةٌ أمامك. أغلبية تلك الإضافات يمكن إضافتها فقط إلى الموقع الرئيسي، ما عدا ودجة Reader. وبدلًا من شرح كل هذه الإضافات، فسأريك أمرين: كيفية إنشاء صفحة في موقعك الرئيسي التي تعرض المحتوى الحديث. كيفية إضافة المحتوى الحديث إلى منطقة مخصصة للودجات في أيّ موقع على شبكتك. قبل البدء: تثبيت إضافة Post Indexer إن لم تفعل ذلك إلى الآن، فثبّت إضافة Post Indexer وفعِّلها لكامل الشبكة. راجع التعليمات المذكورة في القسم السابق. إنشاء صفحة لعرض المحتوى الحديث في موقعك الرئيسي طريقة رائعة لحثّ الناس على التسجيل في شبكتك وتشجيعهم ليصبحوا جزءًا من المجتمع هو عرض المحتوى الحديث في الشبكة على موقعك الرئيسي. على سبيل المثال، موقع WordPress.com فيه صفحة Discover التي يمكنك أن تقرأ فيها أفضل المقالات المنشورة حديثًا التي أنشأها المستخدمون: لذا، لنضبط صفحة على الموقع الرئيسي في الشبكة، ولفعل ذلك ستحتاج إلى تثبيت وتفعيل إضافة Recent Global Posts. تهيئة الصفحة اذهب الآن إلى لوحة تحكم مدير الموقع لموقعك الرئيسي، وأنشِئ صفحة جديدة باسم «Latest Content» (أو أي اسم يحلو لك!). اكتب فيها بعض المحتوى لجذب انتباه الزوار وأخبرهم ما الغرض من هذه الصفحة. ثم اكتب [globalrecentposts] وهذه شيفرة (shortcode) ستستعملها الإضافة لملأ الصفحة بأحدث المنشورات في عموم شبكتك. هذه هي الصفحة الخاصة بي عند تحريرها: انشر صفحتك وعاينها في الواجهة الأمامية. هذه صفحتي: ملاحظة: الأشخاص ذوو البصر الثاقب سيلاحظون أنني أضفت ودجة لتسجيل الدخول إلى الشريط الجانبي لموقعي الرئيسي. وهذا يسمح للمستخدمين بتسجيل الدخول بسهولة إن نسوا كيف يصلون إلى صفحة تسجيل الدخول الخاصة بهم. استخدمتُ إضافة Login Widget with Shortcode لفعل ذلك. حسنًا، سيظهر محتوى رائع لكي يغري المستخدمين. لحسن الحظ، لشيفرة Shortcode لإضافة Recent Posts بعضُ المعاملات (parameters) التي تستطيع استخدامها لتوفير المزيد من المعلومات. لاستخدام تلك المعاملات، اكتبها داخل الأقواس المربعة مع شيفرة Shortcode: number="5"‎: عدد المنشورات التي تريد عرضها title_characters="250"‎: العدد الأقصى للمحارف في كل عنوان content_characters="200"‎: العدد الأقصى للمحارف في كل مُدخَلة (entry) title_content_divider="-"‎: ما الذي تريد استخدامه لفصل العنوان عن المحتوى. إن لم تُحدَّد قيمة هذا المعامل، فسيُعرَض المحتوى تحت العنوان title_link="no"‎: افتراضيًا، يوضع رابط للمنشور، يمكنك استخدام هذا المعامل لتغيير ذلك show_avatars="yes"‎: عرض صورة Avatar لكاتب المقالة إن كانت صور avatar مفعَّلة على موقعك avatar_size="32"‎: قياس صورة avatar posttype="post-type"‎: استخدم هذه المعامل لتحديد نوع المنشور الذي يجب عرضه. النوع الافتراضي هو post، لاحظ أنَّك تستطيع تحديد نوع واحد فقط من المنشورات القيم المذكورة في الأمثلة السابقة هي قيم توضيحية فقط، يمكنك أن تضع القيم الملائمة لحالتك. أريد أن أضيف صور avatar وعرض مقتطف من المنشور. ولفعل ذلك سأضع [globalrecentposts content_characters="250" show_avatars="yes" avatar_size="40" ‎] بدلًا من [globalrecentposts]. احفظ الصفحة، واعرضها في المتصفح وستشاهد شيئًا شبيهًا بما يلي: حسنًا، هذا أفضل بكثير! لنضف الآن رابطًا لحث الزوار على التسجيل. اضف بعض النص تحت شيفرة shortcode التي تعرض آخر المنشورات، وضع رابطًا لصفحة التسجيل الموجودة في wp-signup.php، والتي أنشأتَها في درسٍ سابقٍ في هذه السلسلة. لفعل ذلك، اكتب النص في صفحة التحرير، ثم اضغط على أيقونة الرابط والصق رابط URL لصفحة التسجيل: وأضف أيضًا رابطًا إلى صفحة Latest Content في شريط التنقل الرئيسي. هذه هي النسخة النهائية من الصفحة: إذا أردتَ أن تثير إعجاب زوار الموقع بكفاءة، فأنصحك باستخدام بعض التنسيق في قالبك لكي تجعل رابط التسجيل بارزًا أكثر ولكي تجعل المنشورات تظهر بشكلٍ أفضل وتستطيع تمييزها عن بعضها بسهولة، بالإضافة إلى حذف النقاط التي تظهر قبل عنوان المنشور. لكن ذلك خارجٌ عن نطاق هذه السلسلة، لذا سأترك الأمر لك! مشاركة المحتوى على المواقع باستخدام ودجة Reader إذا ثبّتتَ إضافة Reader، فيمكن لمدراء المواقع إضافة ودجة خاصة بهذه الإضافة إلى موقعهم لكي يعرضوا المحتوى الذي يتابعونه في الشبكة على زوار موقعهم. يمكنك فعل ذلك في صفحة الودجات أو التخصيص في لوحة التحكم. وسنستعمل هنا صفحة التخصيص. اذهب إلى «Appearance > Customize» (مظهر > تخصيص) ثم اختر «Widgets» (ودجات)، ثم اختر منطقة الودجات التي تريد أن تتعامل معها (اخترتُ أنا الشريط الجانبي): اضغط على زر «Add a Widget» (أضف ودجت) ثم اختر «Reader: Recent Posts» واملأ حقل «Title» (العنوان)، واختر عدد المنشورات التي تريد عرضها، واضبط الخيارات الأخرى مثل تاريخ النشر، والمقتطف، والكاتب. يمكنك أن تختار ما الذي تريد عرضه: المنشورات المميزة، أو المنشورات من المواقع التي تتابعها، أو منشوراتك، أو المنشورات من كل المواقع في الشبكة، أو المنشورات المشهورة في الشبكة، أو آخر المنشورات في الشبكة. اخترتُ المنشورات التي أتابعها: بعد أن تفعل ذلك، اضغط على زر «Save & Publish» (حفظ ونشر) ثم تحقّق من ظهور الودجة في الواجهة الأمامية لموقعك: يمكنك أيضًا أن تستعمل الودجة لإظهار محتوى من عموم الشبكة، أو إظهار منشوراتك الخاصة؛ لذا قد ترغب باستعمالها أكثر من مرة أو في أكثر من منطقة مخصصة للودجات. إنشاء شبكة اجتماعية إنشاء مجتمع في شبكتك هو عنصرٌ مساهمٌ في التواصل الاجتماعي. إذا أردتَ أن يعمل موقعك الرئيسي كشبكة اجتماعية متكاملة، فثبّت إضافة BuddyPress، لكن إن لم تكن تحتاج إلى كل وظائف BuddyPress، فيمكنك استخدام إضافة Friends للسماح للأعضاء بإنشاء ارتباطات، وإضافة Messaging للسماح لهم بإرسال رسائل لبعضهم بعضًا. قد ترغب أيضًا بالسماح لمستخدميك أن يرفعوا صورة avatar خاصة دون استخدام Gravatar، وعليك حينها استخدام إضافة WP User Avatar. السماح للمستخدمين برفع صورة Avatar لا يملك أغلبية الأشخاص حسابًا على Gravatar وربما لا يريد مستخدموك أن يُهيئوا واحدًا. يمكنك حينها تثبيت إضافة WP User Avatar للسماح لمستخدميك بإضافة صورة شخصية من صفحة حساباتهم. ثبِّت الإضافة وفعِّلها على كامل الشبكة كالمعتاد. لرفع صورة، سيذهب المستخدم إلى «Users > Your Profile» (أعضاء > حسابك)، ثم مرِّر إلى الأسفل لتصل إلى حقل «Image» (الذي يقع تحت حقل «Profile Picture» [صورة الحساب] بمسافة كبيرة!): اضغط على زر «Choose Image» ثم ارفع صورتك الجديدة: في النهاية، اضغط على «Update Profile» (تحديث الحساب) وستتغير صورة حسابك، كما ترى في الصورة التالية للواجهة الأمامية للموقع: السماح للمستخدمين بالتواصل مع بعضهم بعضًا للسماح للمستخدمين بالتواصل مع بعضهم بعضًا، فثبِّت إضافة Friends من لوحة WPMU DEV وفعِّلها على كامل الشبكة. يمكنك أن تسمح لهم بإرسال الرسائل لبعضهم أيضًا، وذلك بتثبيت إضافة Massaging وتفعيلها على كامل الشبكة. عليك الآن ضبط الإضافة بالذهاب إلى صفحة «Friends Settings» في قائمة لوحة التحكم، ومن هنا يمكنك تعديل قوالب البريد الإلكتروني التي تستعملها الإضافة لإخطار المستخدمين بوجود أعضاء آخرين يريدون التواصل معهم: أجرِ أيّة تعديلات تريدها، ثم اضغط على زر «Save Changes». وستحتاج إلى الضغط على زر «Save Changes» لكل قالب تريد تعديله، وليس مرةً واحدةً فقط. لإرسال طلب صداقة، فسيذهب مستخدموك إلى صفحة «Friends > Find Friends» في قائمة لوحة التحكم. ومن ثم يكتبون اسم المستخدم، أو الاسم المرئي، أو عنوان البريد الإلكتروني للشخص الذي يريدون إنشاء صداقة معه ثم الضغط على Search: ومن ثم الضغط على رابط «Add» الظاهر بجوار الصورة. الشخص الذي أرسلتَ له طلب الصداقة سيحصل على إشعار على البريد الإلكتروني. وعندما يسجلون الدخول إلى موقعهم، سيذهبون إلى «Friends > Friend Requests» لرؤية الطلبات الجديدة: يمكنك أن ترى موقعهم أولًا بالضغط على رابط «View Blog»، وتستطيع قبول طلب الصداقة أو رفضه؛ وسيحصل الشخص الذي أرسل طلب الصداقة على رسالة بريدية تخبره بردِّك. عندما يذهب أحدكما إلى صفحة Friends، فسيرى الشخص الآخر مذكورًا فيها: يمكن للمستخدمين أن يرسلوا لبعضهم رسائل بالضغط على رابط «Send Message»: اكتب الرسالة التي تريدها، ثم اضغط «Send» وسيحصل المستخدم الآخر على بريد إلكتروني لينبهه إلى رسالتك. يمكنك أن تستخدم بعض خيارات التنسيق المتاحة لك كما لو كنتَ تُنسِّق مقالةً. لرؤية الرسائل الواردة، اذهب إلى صفحة «Inbox» في قائمة المدير: يمكنك إرسال الرسائل من هذه الصفحة، ومن صفحة الأصدقاء أيضًا. إنشاء مجتمع سيُحسِّن من شبكتك إضافة ميزات المجتمع إلى شبكة متعددة المواقع سيمنح المستخدمين شيئًا أكبر من مكان لإنشاء مواقع. سيتمكنون أيضًا من الاستفادة من محتواهم المفضل بمشاركته مع الآخرين والتواصل معهم مباشرةً. يمكنك أيضًا استخدام ميزات المجتمع لإظهار ما تحتويه شبكتك في موقعك الرئيسية وتظهِر أنَّ شبكتك رائعة. إنشاء مجتمع يجعل شبكتك ذات قيمة أكبر للمستخدمين وسيساعدك على اكتشاف طاقاتهم. ترجمة –وبتصرّف– للمقال WordPress Multisite Masterclass: Creating a Community لصاحبته Rachel McCollin
  5. يملك لينُكس أنظمةً صلبةً وأدواتٍ عمليةً لإدارة الأجهزة والعتاد، بما في ذلك أجهزة التخزين. سنشرح في درسنا هذا كيفية تمثيل تلك الأجهزة في لينكس وكيف يمكن تحويل المساحات الخام إلى مساحاتٍ تخزينيةٍ قابلةٍ للاستخدام على الخواديم. ما هو التخزين الكتلي؟ التخزين الكتلي (Block storage) هو اسمٌ آخر لما تدعوه نواة لينُكس بالجهاز الكتلي (block device). والجهاز الكتلي هو قطعةٌ من العتاد التي يمكن استعمالها لتخزين البيانات، مثل أقراص التخزين الصلبة الاعتيادية (HDD) أو أقراص التخزين ذات الحالة الثابتة (solid state drive أي SSD) أو وحدات الذاكرة الفلاشية (flash memory stick) …إلخ. تلك تسمى «أجهزةً كتليةً» لأنَّ النواة تتعامل مع العتاد على أنَّه كتلٌ ثابتةُ الحجم، أو قطعٌ من المساحة. بشكلٍ أساسي، التخزين الكتلي هو ما نعتبر أنَّه التخزين الاعتيادي المتواجد في الحواسيب، والذي –بعد ضبطه وإعداده– سيعمل على أنَّه جزءٌ من شجرة نظام الملفات الحالية، وستتمكن من قراءة أو كتابة المعلومات منه وإليه بسلاسة. ما هي الأقسام في الأقراص؟ الأقسام (partitions) هي طريقةٌ لتقسيم جهاز التخزين إلى وحدات قابلة للاستخدام أصغر حجمًا، إذ أنَّ القسم هو جزءٌ من جهاز التخزين الذي يمكن معاملته بطريقةٍ مشابهةٍ لطريقة التعامل مع القرص نفسه. يسمح لك التقسيم بتجزئة المساحة المتوافرة لديك واستخدام كل قسمٍ لغرضٍ مختلف. وهذا يعطي المستخدمين الكثير من المرونة سامحًا لهم بتجزئة النظام لديهم لتحديثه بسهولة أو لتثبيت أكثر من نظام تشغيل أو لإنشاء مساحة تبديل (swap) أو لاستخدام أنظمة ملفات خاصة على تلك الأجزاء. وصحيحٌ أنَّ الأقراص يمكن أن تُهيّئ (format) وتُستعمَل دون تقسيم، إلا أنَّ بعض أنظمة التشغيل تتوقع وجود «جدول أقسام» (partition table) حتى ولو كان هنالك قسمٌ وحيدٌ في القرص؛ لذا يُستحسَن ويُنصَح عمومًا إنشاء أقسام في الأجهزة الجديدة لضمان مرونة استخدامها مهما كانت الظروف. MBR أم GPT؟ من المهم عند تقسيم القرص معرفة ما هي «صيغة» التقسيم التي ستستعملها، وسينتهي بك المطاف بالاختيار بين MBR (اختصار للعبارة Master Boot Record) و GPT (اختصار للعبارة GUID Partition Table). MBR هو نظام التقسيم التقليدي الذي بقي مُستخدَمًا طيلة 30 عامًا الماضية؛ ونتيجةً لعمره الطويل، فهو يعاني من بعض المحدوديات التي لها وقعٌ كبير. فمثلًا لا يمكننا استخدامه للأقراص التي حجمها التخزيني أكبر من 2 تيرابايت، ولا يمكن إنشاء أكثر من أربعة أقسام رئيسية (primary partitions)؛ ونتيجةً لذلك نضبط عادةً القسم الرابع على أنَّه «قسمٌ ممتد» (extended partition) الذي سيُنشَأ داخله «أقسامٌ منطقيةٌ» (logical partitions). وهذا يسمح لك بتجزئة آخر قسم لإنشاء أي عدد إضافي من الأقسام. GPT على الجانب الآخر هو تخطيط حديث للتقسيم الذي يحاول حلّ بعضًا من المشكلات الموروثة من MBR، الأنظمة التي تستعمل GPT يمكن فيها إنشاء أي عددٍ نريده من الأقسام، لكن هذا محدودٌ عادةً بالقيود المفروضة من نظام التشغيل نفسه. إضافةً إلى ما سبق، لا تعاني أقراص GPT من محدوديات في حجم القرص، ومعلوماتُ جدولِ الأقسامِ متوافرةٌ في مواضعَ عدَّة مما يحميها من التلف. يمكن أيضًا كتابة سجل «protective MBR» الذي يخبر الأدوات التي تتعامل مع أقراص MBR فقط أنَّ القرص قيد الاستخدام حاليًا. من الأفضل في أغلبية الحالات اختيار GPT ما لم يمنعك نظام تشغيلك أو الأدوات التي ستستعملها من ذلك. التهيئة وأنظمة الملفات صحيحٌ أنَّ نواة لينكس يمكنها التعرف على الأقراص الخام (raw disks) إلا أنَّ القرص لا يمكن أن يُستعمل كما هو؛ وإنما يجب تهيئته (format) قبل استعماله. التهيئة هي عملية كتابة نظام ملفات إلى القرص وتجهيزه لإجراء عمليات لها علاقة بالملفات. أما نظام الملفات (filesystem) فهو النظام الذي يُنظِّم البيانات ويتحكم بكيفية كتابة المعلومات إلى القرص والحصول على المعلومات من القرص؛ فبدون نظام الملفات لن تتمكن من استخدام جهاز التخزين لأيّة عمليات لها علاقة بالملفات. هنالك الكثير من صيغ أنظمة الملفات المختلفة، والتي تتباين فيما بينها بامتلاكها لميزاتٍ مختلفة، بما في ذلك دعمُ أنظمة التشغيل. لكن بشكلٍ أساسي، تمنح جميع أنظمة الملفات للمستخدم تمثيلًا مألوفًا للقرص، لكن الميزات التي يدعمها كل نظام ملفات وآلية سماحه للمستخدم بالتعامل وإجراء عمليات على القسم مختلفةٌ تمامًا. بعضٌ من أشهر أنظمة الملفات المتاحة للينكس: Ext4: أشهر نظام ملفاتٍ افتراضيٍ في لينكس هو Ext4 (اختصار للعبارة the fourth version of the extended filesystem) وهو نظام ملفات ذو سجل (journaled)، ومتوافق مع الأنظمة القديمة، ومستقر للغاية، ومدعومٌ دعمًا واسعًا وتتوافر له أدواتٌ كثيرة؛ وهو خيارٌ جيدٌ إن لم تكن لديك احتياجاتٌ خاصة. XFS: نظام ملفات XFS متخصصٌ بموضوع الأداء وبالملفات كبيرة الحجم، وستتم تهيئته بسرعة وأداؤه جيد عند التعامل مع الملفات الكبيرة ومع الأقراص الضخمة. ولديه ميزة أخذ snapshot من نظام الملفات. يعتمدXFS على تسجيل البيانات الوصفية (metadata journaling) فقط والذي يختلف عن تسجيل البيانات الوصفية والبيانات نفسها؛ وهذا يؤدي إلى سرعةٍ في الأداء، لكن قد يؤدي في الوقت نفسه إلى حدوث تلفٍ في البيانات في حال حدوث فقدان غير متوقع للطاقة الكهربائية. Btrfs: نظام ملفات Btrfs هو نظامٌ حديثٌ له ميزاتٌ كثيرة وهو من نمط copy-on-write بدل كونه journaled، هذه المعمارية تسمح لبعض وظائف إدارة الحجوم (volume management) بأن تُدمَج مع طبقة نظام الملفات، بما في ذلك snapshots، والنسخ (cloning)، والحجوم (volumes) …إلخ. لكن نظام ملفات Btrfs ما يزال يواجه مشاكل عند التعامل مع الأقراص الممتلئة. هنالك بعض الجدال الدائر حول جاهزية نظام الملفات هذا لاستعماله في بيئات العمل الإنتاجية، وينتظر الكثير من مدراء الأنظمة أن يصل Btrfs إلى درجةً أكبر من الدعم والانتشار. ZFS: هو نظام ملفاتٍ من نمط copy-on-write وفيه مدير حجوم (volume manager) بمجموعة متينةٍ ومستقرةٍ من الميزات. يحتوي أيضًا على ميزاتٍ ممتازةٍ لضمان سلامة البيانات المُخزَّنة عليه، ويمكنه التعامل مع أقسام ذات مساحات تخزينية كبيرة، وفيه ميزات إدارة الحجوم التقليدية مثل snapshotting و cloning، ويمكن فيه تنظيم الحجوم (volumes) إلى مصفوفة RAID أو مصفوفات شبيهة بمصفوفات RAID لغرض إنشاء نظام تخزيني مستقر وذي أداءٍ عالٍ. أما عن وضع دعم ZFS في لينكس، فيجدر بالذكر أنَّ له تاريخٌ جدليٌ نتيجةً لمخاوف من رخصة استعماله. أصبحت توزيعة أوبنتو توفِّر وحدة ثنائية (binary module) من وحدات النواة للتعامل معه، وتضع توزيعة دبيان الشيفرة المصدرية له في مستودعاتها، لكن لم يُحدَّد دعمه في بقية التوزيعات بعد. كيف يُدير لينُكس أقراص التخزين ملفات التخزين الموجودة في ‎/dev من المعروف أنَّ كل شيء في لينُكس (تقريبًا) يُمثَّل بملف؛ بما في ذلك الأجهزة العتادية مثل أجهزة التخزين والتي تُمثَّل في النظام كملفات في مجلد ‎/dev، وعمومًا تبدأ أسماء الملفات التي تُمثِّل أجهزة التخزين بالحرفين sd أو hd متبوعَين بحرفٍ آخر؛ فمثلًا: أوّل قرص تخزين على الخادوم يكون اسمه شبيهًا بالاسم ‎/dev/sda. تملك الأقسام على تلك الأجهزة ملفاتٍ هي الأخرى ضمن مجلد ‎/dev، ممثلةً بإضافة رقم القسم إلى نهاية اسم الجهاز، فعلى سبيل المثال، أوّل قسمٍ في القرص المذكور في المثال السابق سيكون على الشكل ‎/dev/sda1. وعلى الرغم من أنَّ ملفات الأجهزة ‎/dev/sd*‎ و ‎/dev/hd*‎ هي الطريقة التقليدية للإشارة إلى الأجهزة والأقسام، إلا أنَّ هنالك جانبٌ سلبيٌ لاستخدام تلك المسارات، إذ أنَّ نواة لينكس تُقرِّر ما هو الجهاز الذي سيحصل على الاسم الفلاني عند كل إقلاعٍ للنظام، لذا قد يودي ذلك إلى تضاربات حيث تتغير أسماء عقد الأجهزة. حلٌ التفافيٌ على هذه المشكلة هو احتواء المجلد ‎/dev/disk على مجلدات فرعية تَنظُمُ الأقراص والأقسام بطرائق ثابتةٍ لا تتغير؛ وتلك المجلدات تحتوي على وصلاتٍ رمزيةٍ (symbolic links) التي تُنشَأ عند الإقلاع لتشير إلى ملفات ‎/dev/[sh]da*‎ الصحيحة. تُسمى تلك الوصلات وفقًا لنوع طريقة التنظيم والموضَّحة باسم المجلد (على سبيل المثال، ستسمى الوصلات حسب «لُصيقة» [label] القسم في مجلد ‎/dev/disk/by-partlabel). ستُشير تلك الوصلات دومًا إلى الأجهزة الصحيحة، لذا يمكننا استخدامها كمُعرِّفات ثابتة لأجهزة التخزين. بعض (أو جميع) المجلدات الآتية موجودةٌ ضمن مجلد ‎/dev/disk: by-label: أغلبية أنظمة الملفات لها آلية لإعطاء لُصيقة سامحةً بإسناد أسماء يُحدِّدها المستخدم إلى القرص أو القسم؛ يحتوي هذا المجلد على وصلاتٍ مسماةٍ تِبعًا للُصيقات التي كتبها المستخدم. by-uuid: المُعرِّفات العالمية الفريدة (اختصارًا UUIDs) هي سلسلةٌ طويلةٌ فريدةٌ من الحروف والأرقام التي يمكن أن تُستعمَل كمُعرِّف لوسيط التخزين. تلك المُعرِّفات ليست سهلة القراءة من البشر، لكنها فريدة، وستبقى ثابتةً حتى لو بدَّلنا الخادوم أو النظام؛ لذا من الأفضل استخدام مُعرِّفات UUID للإشارة إلى أجهزة التخزين التي قد تُنقَل بين الأنظمة بين الحين والآخر، لأنَّ من غير المحتمل أن يحدث تضاربٌ في الأسماء. by-partlabel و by-partuuid: توفِّر جداول GPT لافتاتٍ ومعرِّفات UUID خاصة بها، والتي يمكن أن تُستعمَل أيضًا بغرض تمييز الأقسام، وتعمَل بنفس طريقة عَمَل المجلدين السابقين، إلا أنَّها تستعمل مُعرِّفات خاصة بجداول GPT. by-id: يحتوي هذا المجلد على وصلات مُولَّدةٌ أسماؤها من الرقم التسلسلي لجهاز التخزين وللجهاز الموصول إليه، وتلك الأسماء غير ثابتة تمامًا، لأنَّ طريقة وصل الجهاز إلى النظام قد تُغيّر من اسم وصلات المجلد by-id. by-path: وكما في مجلد by-id، تعتمد الوصلات الموجودة في هذا المجلد على أجهزة التخزين الموصول إلى النظام نفسه، وتُبنى تلك الوصلات اعتمادًا على طريقة تمثيل العتاد الذي يُستعمَل للوصول إلى وسيط التخزين في نظام التشغيل. وللوصلات الموجودة في هذا المجلد نفس الإشكاليات التي تواجهها تلك الموجودة في by-id لأنَّ وصل جهاز التخزين إلى منفذٍ آخر قد يؤدي إلى تغيير هذه القيمة. يُفضَّل عادةً استخدام by-label أو by-uuid إذ أنَّ تمثيلها للأقراص ثابتٌ. وصل أجهزة التخزين الكتلية تُستعمَل ملفات الأجهزة الموجودة في ‎/dev للتواصل مع التعريف القادر على التعامل مع الجهاز المُعيّن في النواة؛ لكن يجب إنشاء طبقة تُمكّننا من معاملة الجهاز كوسيط تخزين يحتوي على مساحةٍ تخزينيةٍ قابلةٍ للاستعمال. في لينكس وغيره من الأنظمة الشبيهة بيونكس (Unix-like)، يُمثَّل نظام التشغيل كشجرة ملفات موحّدة بغض النظر عن عدد الأجهزة الفيزيائية التي تُستعمَل فيه؛ ولكي يُستعمَل نظامُ ملفاتٍ أو قرصٌ في النظام، فيجب ربطه بمكانٍ ما في تلك الشجرة. عملية «الوصل» (mounting) تعني ربط قسم مُهيئ أو قرص إلى مجلدٍ موجودٍ ضمن نظام ملفات لينُكس؛ ومن ثم سنتمكّن من الوصول إلى محتويات القرص أو القسم من ذاك المجلد. توصل الأقراص أو الأقسام دومًا في مجلدات فارغة مخصصة لهذا الغرض (الوصل في مجلد غير فارغ يعني أنَّنا لن نتمكن من الوصول إلى محتويات المجلد حتى نفصل [unmount] القرص أو القسم). هنالك الكثير من خيارات الوصل التي يمكن ضبطها لتعديل سلوك الأجهزة الموصولة، على سبيل المثال، يمكن أن يوصل القرص بوضع «القراءة فقط» لضمان عدم تغيير محتوياته. ينصح معيار هيكلة نظام الملفات باستخدام ‎/mnt أو مجلدٍ فرعيٍ داخله لوصل أنظمة الملفات مؤقتًا. إذا كان وصلك للأقراص مؤقتًا فهذا أفضل مكانٍ لوصلها؛ لكن المعيار لم يُقدِّم أيّة اقتراحات لمكان وصل وسائط التخزين الدائمة، لذا يمكنك وصلها أينما تشاء؛ لكن في أغلبية الحالات توصل وسائط التخزين الدائمة في مجلد ‎/mnt أو في مجلدٍ فرعيٍ داخله. جعل الوصل دائمًا باستخدام ‎/etc/fstab تنظر أنظمة لينكس إلى ملفٍ يدعى ‎/etc/fstab (أي filesystem table) الذي يُحدِّد ما هي أنظمة الملفات التي يجب وصلها أثناء الإقلاع. توصل أنظمة الملفات غير الموجودة في ذاك الملف تلقائيًا (باستثناء تلك المُعرَّفة بملفات systemd‏ ‎.mount، التي ليست شائعةً حاليًا). ملف ‎/etc/fstab بسيطٌ جدًا، فكلُ سطرٍ فيه يُمثِّل نظام ملفاتٍ مختلفٍ الذي يجب أن يوصل؛ يُحدِّد هذا السطر ما هو الجهاز الكتلي، وما هي نقطة الوصل (mount point) التي سيُربَط إليها، وما هي صيغة القسم، وما هي خيارات الوصل، بالإضافة إلى معلوماتٍ أخرى. إدارة متقدمة لأجهزة التخزين صحيحٌ أنَّ أغلبية الاستخدامات البسيطة لا تحتاج إلى بُنى إدارية إضافية، إلا أنَّنا سنحصل على أداءٍ عالٍ ومرونة وقدرة على تعويض تلف الأقراص عند استخدامنا لطرائق الإدارة المتقدمة. ما هي مصفوفات RAID؟ مصفوفات RAID ترمز إلى «redundant array of independent disks»، وهي تقنية إدارة تخزين تسمح لك بتجميع الأجهزة مع بعضها لإدارتها كجهاز تخزين وحيد له ميزاتٌ إضافيةٌ. خصائص مصفوفة RAID تعتمد على مستوى RAID المستعمل، والذي يُعرِّف ما هو عدد الأقراص في المصفوفة وكيف تتعلق ببعضها. للمستوى المختار تأثيرٌ على الأداء والقدرة على تعويض تلف الأقراص، بعض المستويات الشائعة هي: RAID 0: يعتمد هذا المستوى على «توزيع البيانات» (drive striping) والذي يعني أنَّه عندما تُكتَب البيانات إلى المصفوفة، فستُقسَّم وتوزَّع على الأقراص الموجودة في المصفوفة، وهذا يعني زيادةً في الأداء لأنَّ بالإمكان الكتابة على أو القراءة من أكثر من قرص في آنٍ واحد. الجانب السلبي لهذا المستوى هو عندما يحدث عطبٌ في أحد الأقراص فسنفقد جميع المعلومات في كامل المصفوفة، لعدم وجود قرص يحتوي على معلوماتٍ كافيةٍ لإعادة بناء المصفوفة. RAID 1: مستوى RAID 1 يعتمد على إنشاء نسخة مماثلة للبيانات (drive mirroring). فأي شيء يُكتَب إلى مصفوفة RAID 1 سيُكتَب على عدِّة أقراص؛ الميزة الأساسية لهذا المستوى هو القدرة على تعويض الأقراص، مما يعني أنَّ البيانات ستبقى موجودةً في المصفوفة حتى لو حدث عطبٌ في أحد الأقراص؛ وذلك لأنَّ عدِّة أقراص تحتوي على نفس البيانات، لكن في المقابل سيؤدي ذلك تقليل المساحة التخزينية للمصفوفة إلى النصف. RAID 5: مستوى RAID 5 يوزِّع البيانات على عدِّة أقراص بشكلٍ شبيهٍ بمستوى RAID 0؛ لكن هذا المستوى يتضمن تكرار توزيع جزء من البيانات على قرصٍ آخر، وهذا يعني أنَّه لو حدثت مشكلة في أحد الأقراص، فستتمكن بقية الأقراص من إعادة بناء المصفوفة باستخدام البيانات المُكرَّرة التي يمكن تجميعها معًا. تلك البيانات المكررة كافية لإعادة بناء قرصٍ وحيد، وهذا يعني أنَّ المصفوفة ستتمكن من إعادة بناء نفسها إن حدث عطبٌ في قرصٍ وحيدٍ فقط. يؤدي تكرار توزيع البيانات إلى تقليل المساحة التخزينية لكامل المصفوفة إلى ما يعادل المساحة التخزينية لقرصٍ وحيد. RAID 6: يملك المستوى RAID 6 نفس خصائص RAID 5، إلا أنَّه يُكرِّر جزءًا من البيانات على قرصين، وهذا يعني أنَّ مصفوفات RAID 6 ستتمكن من إعادة بناء نفسها إن فقدت قرصين؛ وستتأثر المساحة التخزينية لكامل المصفوفة بتكرار البيانات، وهذا يعني أنَّ المساحة التخزينية القابلة للاستخدام لكامل المصفوفة مساويةٌ للمساحة التخزينية لقرصين. RAID 10: هذا المستوى هو دمجٌ بين المستويين 1 و 0، فبدايةً ستُنشَأ مجموعتين متماثلتين (mirrored) من المصفوفات؛ ثم ستُوزَّع البيانات عليها، وهذا يُنشِئ مصفوفةً لها نفس القدرة التعويضية لكن أداءها عالٍ. لكن هذا المستوى يتطلب عددًا كبيرًا نسبيًا من الأقراص، والمساحة التخزينية القابلة للاستخدام هي نصف مساحة جميع الأقراص. ما هو LVM؟ LVM، أو مدير الحجوم المنطقية (Logical Volume Manager) هو نظامٌ يُشكِّل «طبقةً» تعلو البنية الفيزيائية لوسائط التخزين وخصائصها لتوفير مرونة عالية وقدرات كبيرة. يسمح لك LVM بإنشاء مجموعة من الأجهزة الفيزيائية وإدارتها كما لو أنَّها قرصٌ وحيد، ويمكنك تقسيم المساحة عند الحاجة إلى «حجوم منطقية» (logical volumes) والتي تعمل عمل الأقسام. يعمل LVM بناءً على الأقسام العادية، ويحّل الكثير من المحدوديات الموجودة في الأقسام التقليدية، فعلى سبيل المثال، يمكنك بكل سهولة عند استخدام حجوم LVM أن توسِّع الأقسام وتُنشِئ أقسامًا تمتد على أكثر من قرص، وتأخذ نسخ snapshot من الأقسام، وتنقل الحجوم إلى أقراص فيزيائية مختلفة. يجدر بالذكر أنَّ بالإمكان استخدام LVM مع مصفوفات RAID ذات الأداء والوفرة العالية لتوفير نظام إدارة مرن. ما هي الخطوة القادمة؟ إذا كان لديك جهاز تخزين جديد تريد استخدامه مع نظام لينكس، فألقِ نظرةً على هذه المقالة التي ستُرشِدُكَ إلى طريقة تقسيم وتهيئة ووصل نظام الملفات الجديد الذي ستُنشِئه. يجب أن تكفيك المقالة السابقة لأغلبية حالات الاستخدام حيث سيكون همّك الرئيسي هو زيادة القدرات التخزينية. لتعلم المزيد عن مهام إدارة أجهزة التخزين الأساسية، فانظر إلى هذه المقالة ترجمة -وبتصرّف- للمقال An Introduction to Storage Terminology and Concepts in Linux لصاحبه Justin Ellingwood
  6. رأيتُ في الآونة الأخيرة الكثير من الأشخاص يشقون طريقهم بصعوبة في CSS، انطلاقًا من المبتدئين إلى المبرمجين المحترفين؛ بعضهم لا يحب طريقة عمل CSS، ويرون أنَّ استبدال لغة أخرى بلغة CSS هو أمرٌ حسن، وكانت هذه هي نقطة انطلاق مفسرات CSS (مثل Sass و Less)؛ وبعضهم الآخر يستخدم إطارات العمل على أمل أنَّ ذلك سيجعلهم يكتبون شيفرات أقل (ورأينا في درس «ربما لا تحتاج إلى إطار عمل للغة CSS » أنَّ ذلك ليس صحيحًا)؛ بينما تخلى بعض المطورين عن استخدام CSS تمامًا وبدؤوا باستعمال JavaScript بدلًا عنها. لكنك لا تحتاج دومًا إلى استخدام مُفسِّر CSS في مشاريعك، ولستَ بحاجةٍ إلى استعمال إطار عمل كبير كنقطة بداية لمشروعك، ومن المؤكد أنَّ فكرة استعمال JavaScript لغير غرضها الأصلي هي فكرةٌ سيئة. سنطالع في هذا الدرس بعض التلميحات والنصائح لكيفية أفضل لكتابة شيفرات CSS سهلة الصيانة، لذا ستصبح ملفات الأنماط أقصر، وفيها قواعد أقل، وستشعر أنَّ CSS أصبحت أداةً مفيدةً واستخدامها مريح بدلًا من أن تفكر في عواقب استعمالها! إنشاء محددات غير مخصصة تعتمد لغة CSS على التصريح عن «محددات» (selectors) التي تضع فيها القواعد التنسيقية التي تريد تطبيقها على العناصر الموجودة في شجرة DOM. وهنالك بعض القواعد التي لها أولوية على القواعد الأخرى، كتلك التي عُرِّفَت داخل الخاصية style في العنصر نفسه. على سبيل المثال، إذا كانت لدينا شيفرة HTML و CSS الآتية: <button class="button-warning"> .button-warning { background: red; } button, input[type=submit] { background: gray; } بغض النظر عن أنَّ القاعدة ‎.button-warning قد عرِّفَت قبل قاعدة button, input[type=submit]، لكن لخاصية background فيها أولوية على خاصية background المُعرَّفة في قاعدة button, input[type=submit]. لكن لماذا؟ ما هو المعيار الذي تتبعه لغة CSS لتقرر ما هي القواعد التي لها أولوية على غيرها؟ الجواب هو «التحديد»، فبعض المحددات تُعتبَر أنَّها مخصصة أكثر من غيرها: فمثلًا المُحدِّد ‎#id له أولوية على محدد ‎.class. ماذا يحدث لو استخدمنا مُحدِّد أكثر تخصيصًا مما يلزم؟ ماذا لو أردنا لاحقًا تجاوز تلك القواعد، سنحتاج حينها إلى مُحدِّد أكثر تخصيصًا. ماذا لو أردنا بعد ذلك أن نتجاوز تلك القيم… نعم سنحتاج إلى مُحدِّد أكثر تخصيصًا، وهكذا حتى تصبح المحددات أطول وأعقد وسينتهي بها المطاف لتمسي صعبة الصيانة والتطوير. لذا عليك عند كتابة المُحدِّدات أن تسأل نفسك: هل هذا هو أقل مُحدِّد تخصيصًا الذي يعمل عملًا صحيحًا هنا؟ جميع قواعد التحديد مُعرَّفة بشكلٍ رسمي في مواصفة «W3C CSS Selectors»، وستجد في تلك الصفحة جميع التفاصيل المتعلقة بمُحدِّدات CSS. إذا أردتَ مقالةً سهلة الفهم فاطلع على هذه المقالة. لا تعالج المشاكل بإضافة قواعد جديدة لنتخيل هذا الموقف الذي يتكرر كثيرًا: هنالك علّة في شيفرة CSS وعرفتَ أنَّ أحد عناصر DOM مُنسَّقٌ تنسيقًا خاطئًا، وأدركتَ أنَّ السبب هو وراثته (inherit) لخاصيةٍ لا يجب أن يرثها. رجاءً لا تضف شيفرة CSS جديدة لحل المشكلة، فبفعلك لذلك ستصبح الشيفرات عندك كثيرة، وسيصبح تحديد العلل المستقبلية أصعب. فبدلًا من ذلك، توقف، واستخدام أدوات المطوِّر في متصفحك لتفحص العنصر ومعرفة ما الذي يرثه من خاصيات، ومعرفة ما هي القاعدة التي تُطبَّق على العنصر والتي لا تريدها، ثم تعديل تلك القاعدة لكي لا تؤدي إلى تلك النتيجة. يمكنك إظهار الأنماط التي يرثها أحد العناصر في متصفح Firefox بالضغط بالزر الأيمن على العنصر ثم اختيار «Inspect element». انظر إلى الخاصيات الموروثة، ولاحظ كيف سترى جميع القواعد المُطبَّقة على العنصر، وبالترتيب الذي طُبِّقَت فيه. أي أنَّ القواعد الموجودة في الأعلى هي القواعد الأكثر تحديدًا ولها أولولية على القواعد التي تليها. يمكنك أن ترى وجود خط يمر ببعض الخاصيات، وهذا يعني أنَّ هنالك قاعدة أكثر تخصيصًا أدت إلى تجاوز هذه القاعدة. يمكنك –إضافةً إلى رؤية القواعد المُطبَّقة على العنصر– أن تُفعِّل أو تلغي تفعيل بعض الخاصيات أو أن تجري تعديلات حية على قيمها ثم تلاحظ النتائج، وهذا مفيدٌ جدًا عند محاولة إصلاح العلل. قد يتضمن الحل اللازم تطبيقه لإصلاح العلة تعديلًا في إحدى القواعد، أو تغييرًا لقاعدةٍ ما في مكانٍ آخر في صفحة الأنماط؛ وقد يتطلب إصلاح العلة إضافةَ قاعدةٍ جديدةٍ… لكن المهم أن تعلم ما هو الإجراء الصحيح الذي عليك اتخاذه لإصلاح المشكلة. أقترح عليك أيضًا أن تنظر في إعادة هيكلة الشيفرات (code refactoring)، فصحيحٌ أنَّ CSS ليست لغةً برمجيةً، إلا أنَّها «شيفرات» وعليك أن تأخذ بعين الاعتبار نفس الأمور التي تفعلها مع شيفرات JavaScript أو بايثون: يجب أن تكون الشيفرات مرتبةً وسهلة القراءة ويمكن إعادة هيكلتها عند الحاجة. لا تستخدم ‎‎!important هذه النصيحة مضمّنة في القسم السابق، إلا أنني فضَّلتُ ذكرها بمفردها لأهميتها: لا تستخدم ‎!important في شيفرة CSS! الكلمة المحجوزة ‎!important هي ميزة في CSS تسمح لك بتجاوز الترتيب الافتراضي للأولويات، وهي تستعمل عادةً إن استعجلت إصلاح علّة لكنك لا تملك وقتًا أو ليست عندك رغبة في إصلاحها بمعرفة مسببها الأصلي… من الشائع أيضًا استعمال الكلمة المحجوزة ‎!important عندما تَستخدم إطار عمل CSS ذو قواعد مخصصة جدًا، ومن الصعب تجاوز تلك القيم. عندما تُضيف ‎!important إلى خاصيةٍ ما، فسيتجاهل المتصفح جميع القواعد التي لها أولوية عليها (أي أنَّ القاعدة «أكثر تخصيصًا»)، وستجد نفسك في ورطة عندما تستعمل ‎!important لتجاوز قاعدة أخرى قد اُستخدمَت فيها ‎!important أيضًا. الاستعمال المشروع الوحيد للكلمة ‎!important هو عند استخدامك لأدوات التطوير لمحاولة حل مشكلة ما، فعليك في بعض الأحيان أن تعرف ما هي القيم اللازم ضبطها لإصلاح العلة، واستخدام ‎!important في أدوات التطوير وتعديل قواعد CSS تعديلًا حيًا سيسمح لك بمعرفة تلك القيم مع تجاهل القيم الموروثة. بعد أن تعرف ما هي القيم الصحيحة، فعد إلى الشيفرة وانظر ما هي القواعد التي تتضمن تلك الخاصيات، وعدِّلها كما ينبغي. لا تجعل px و % هي كل ما تستخدمه من الواحدات التعامل مع px (البسكلات) و % (النسب المئوية) أصبح بدهيًا، لذا سنشرح بعض الواحدات الأقل شهرةً. em و rem من أشهر الواحدات النسبية هي em، حيث يكافئ 1em قياس الخط التابع لذلك العنصر. لتكن لدينا شيفرة HTML الآتية: <article> <h1>Title</h1> <p>One Ring to bring them all and in the darkness bind the.</p> </article> وسنستخدم قاعدة CSS وحيدة: article { font-size: 1.25em; } تُطبِّق أغلبية المتصفحات قياسًا بمقدار 16 بكسل إلى العنصر الجذر (root element) افتراضيًا (بالمناسبة، يمكن تعديل هذه القيمة من المستخدم، وهذه ميزةٌ رائعةٌ تُسهِّل من قابلية الوصول). أي ستُعرَض نصوص العنصر article بخاصية font-size ذات القيمة 20 بكسل (أي 16 * 1.25). لكن ماذا عن العنصر h1؟ لفهم ما الذي يحدث تمامًا فسنضيف قاعدة CSS أخرى إلى صفحة الأنماط: h1 { font-size: 1.25em; } صحيحٌ أنَّ قيمة الخاصية font-size هي 1.25em أيضًا، أي نفس قياس العنصر article، لكن علينا أن نأخذ بعين الاعتبار أنَّ الخاصية em هي خاصية تجميعية، أي لو كان العنصر h1 ابنًا (child) مباشرًا للعنصر body على سبيل المثال، فستكون قيمة الخاصية font-size هي 20 بكسل (أي 16 * 1.25)؛ لكن عنصر h1 في مثالنا موجودٌ داخل عنصرٍ (العنصر article هنا) له قيمةٌ للخاصية font-size تختلف عن العنصر الجذر، ففي هذه الحالة قياس الخط هو 1.25 مضروبًا بقيمة الخاصية font-size التي يرثها العنصر h1، أي سيكون قياس الخط النهائي للعنصر h1 الموجود داخل العنصر article هو 25 بكسل (أي 16 * 1.25 * 1.25). الواحدة em متعددة الاستخدامات وتجعل من السهل تغيير جميع القياسات في الصفحة (حتى لو غيرناها ديناميكيًا)، ولا تُستعمَل فقط على قيمة الخاصية font-size وإنما يمكن توظيفها في الخاصيات الأخرى مثل line-height أو width. إذا أعجبتكَ فكرة استخدام واحدة قياس نسبةً إلى الحجم الأساسي، لكن لم تحب موضوع تجميع القيم، فيمكنك حينها استخدام rem، واحدة rem شبيهةٌ جدًا بواحدة em إلا أنَّها تتجاهل تجميع القيم، وتأخذ قياس العنصر الجذر فقط. إذا أخذنا شيفرة CSS للمثال السابق وبدلنا واحدة em إلى rem للعنصر h1: article { font-size: 1.25em; } h1 { font-size: 1.25rem; } ستملك جميع عناصر h1 الخاصية font-size بقيمة 20 بكسل (بافتراض أنَّ قياس العنصر الجذر هو 16px)، بعض النظر إن كان العنصر h1 داخل عنصر article أم لا. vw و vh واحدات vm و vh تُمثِّل نسبة من أبعاد «إطار العرض» (viewport)، حيث 1vw هي 1% من عرض «إطار العرض»، بينما 1vh هي 1% من ارتفاع «إطار العرض». هذه الواحدات مفيدة للغاية، وخصوصًا عندما تريد إنشاء عنصر يأخذ كامل الشاشة (مثل الخلفيات الغامقة للأقسام). واحدات أخرى هنالك واحدات أخرى غير شائعة أو مستعملة بكثرة، لكن قد تصادفك في مسيرتك البرمجية، يمكنك تعلم المزيد من المعلومات عنها في هذا الدرس. استخدم flexbox تحدثنا عن هذا من قبل في درسٍ سابقٍ عن إطارات عمل CSS «ربما لا تحتاج إلى إطار عمل للغة أضفCSS» ، لكن لا ضير من التذكير أنَّ flexbox سيُبسِّط عملية إنشاء تخطيطات الصفحات أو لمحاذاة العناصر. إذا كان flexbox جديدًا عليك فانظر إلى هذا الدرس التمهيدي. أجيب بنعم على السؤال البدهي الذي سيخطر ببالك: «هل يمكن استخدام flexbox في الوقت الراهن؟». دعم flexbox في المتصفحات تجاوز نسبة 94%، لذا يمكنك استخدامه حالًا إلا إن كنتَ تريد دعم المتصفحات القديمة. لذا يمكنك التوقف عن كتابة عناصر div الكثيرة ذات الخاصية float والتي يصعب اكتشاف الأخطاء فيها وصيانتها. راقب أيضًا التطويرات في مجال تنسيق تخطيط الصفحة وخصوصًا Grid ، الذي سيُسهِّل كثيرًا من إنشاء تخطيط الصفحة. عند استخدام مُفسِّر CSS… مفسِّرات CSS مثل Sass أو Less مشهورة جدًا في عالم تطوير الواجهات الأمامية لصفحات الويب، وهي أدواتٌ مفيدةٌ جدًا وتسمح لنا (عند استخدامها استخدامًا صحيحًا) أن نعمل بكفاءة كبيرة مع CSS. لا تسرف في تشعّب المُحدِّدات إحدى الميزات الشائعة في مُفسِّرات CSS هي تشعّب المحددات (selector nesting)، فمثلًا هذه شيفرة Less: a { text-decoration: none; color: blue; &.important { font-weight: bold; } } ستُحوَّل إلى قواعد CSS الآتية: a { text-decoration: none; color: blue; } a.important { font-weight: bold; } تسمح هذه الميزة لنا بكتابة شيفرات أقل، وتجميع القواعد التي تؤثر على العناصر التي تأتي مع بعضها (عمومًا) في شجرة DOM، وهذه الميزة تساعدك في اكتشاف العلل وإصلاحها. لكن من الشائع أيضًا الإفراط في استخدام هذه الميزة مما يجعلك تعيد كتابة شجرة DOM بكاملها في محددات CSS، لذا إذا كانت لدينا شيفرة HTML الآتية: <article class="post"> <header> <!-- … --> <p>Tags: <a href="..." class="tag">irrelevant</a></p> </header> <!-- … --> </article> فقد تجد ما يلي في شيفرة CSS: article.post { // ... ستُذكَر القواعد الأخرى هنا header { // ... p { // ... a.tag { background: #ff0; } } } } الجانب السلبي الرئيسي لهذا هو أنَّ مُحدِّدات CSS الناتجة هي مُحدِّدات مخصصة جدًا، وشرحنا من قبل أنَّ علينا تفادي استخدامها. هنالك سلبيات أخرى للاستخدام المفرط للتشعّب، والتي ذُكِرَت في هذا الدرس. باختصار: لا تجعل تشعّب مُحدِّدات CSS في مفسرات CSS يولِّد قواعد لن تفكر في كتابتها يدويًا دون مُفسِّر. استخدام include أو استخدام extend؟ ميزة أخرى مفيدة لمُفسِّرات CSS تدعى «mixins»، وهي مجموعة من قواعد CSS القابلة لإعادة الاستخدام، فمثلًا لنقل أننا نريد تنسيق الأزرار (buttons)، وأغلبية الأزرار لها نفس خاصيات CSS الأساسية؛ لذا يمكننا إنشاء mixin كما يلي في Less: .button-base() { padding: 1em; border: 0; } ثم إنشاء قاعدة كالآتية: .button-primary { .button-base(); background: blue; } والتي ستولِّد شيفرة CSS: .button-primary { padding: 1em; border: 0; background: blue; } كما ترى، من المفيد جدًا إعادة هيكلة (واستخدام) الشيفرات المكررة. وإلى جانب «تضمين» (including) بُنية mixin، هنالك خيارٌ آخر هو «توسعة» (extending) أو «وراثة» تلك البنية (يختلف المصطلح المستعمل اعتمادًا على الأداة المستخدمة). والتي ستَدمِج عدة مُحدِّدات في نفس القاعدة. لنشاهد مثالًا عمليًا عن توسعة بنية mixin السابقة (أي ‎.button-base): .button-primary { &:extend(.button-base) background: blue; } .button-danger { &:extend(.button-base) background: red; } والتي ستحوّل إلى شيفرة CSS الآتية: .button-primary, .button-danger { padding: 1em; border: 0; } .button-primary { background: blue; } .button-danger { background: red; } بعض المقالات والدروس الموجودة على الويب تخبرنا أن نستخدم طريقة «include» فقط، والأخرى تطلب منا استخدام طريقة «extend» فقط؛ لكن الواقع هو أنَّ كلا الطريقتين ستنتجان شيفرات CSS مختلفة، وليس من الخطأ استخدام أي واحدة منهما، لكن قد يُفضَّل استخدام إحداهما على الأخرى في بعض الحالات. كيف تختار بينهما؟ أكرِّر أنَّ قاعدة «هل ستكتب هذه الشيفرة يدويًا» تنطبق هنا. الخلاصة أرجو أن يؤثر هذا الدرس عليك ويجعل طريقة كتابتك لشيفرات CSS أفضل؛ تذكَّر ما قلتُ لك سابقًا: CSS هي شيفرات، ويجب أن تعاملها بنفس طريقة معاملتك لبقية الشيفرات. فإن أعطيتها الاهتمام اللازم فسترد لك الجميل :-) . ترجمة -وبتصرّف- للمقال CSS coding techniques لصاحبه Belén Albeza
  7. تمهيد هنالك الكثير من الأدوات المتوفرة لإدارة التخزين في لينكس، لكن هنالك عددٌ قليلٌ منها نستعمله يوميًا لإدارة وصيانة أجهزة التخزين. سأريك في هذا الدرس بعضًا من أشهر الأدوات التي تستعمل لإدارة نقاط الوصل وأجهزة التخزين وأنظمة الملفات. لن نشرح في هذا الدرس كيفية تهيئة أجهزة التخزين لأوّل استعمال لها في لينكس، إذ شرحنا ذلك في درسٍ بعنوان «كيفية تقسيم وتهيئة أجهزة التخزين في لينكس» الذي يبيّن لك كيفية إعداد جهاز تخزين جديد إن لم يكن مضبوطًا من قبل. للمزيد من المعلومات حول الاصطلاحات والمفاهيم المستخدمة في هذا الدرس، فراجع درس «تقديم إلى اصطلاحات ومفاهيم التخزين في لينكس». معرفة القدرة التخزينية والمساحة المستخدمة عبر df غالبًا ما تكون أهم معلومة تريد معرفتها عن وسائط التخزين في جهازك هي القدرة التخزينية والمساحة المستخدمة في أجهزة التخزين الموصولة إلى النظام. لمعرفة ما المساحة التخزينية المتوافرة إجمالًا وكم نسبة استخدامها، فسنستعين بالأمر df، الذي يعرض ناتجه مقدرًا بالكيلوبايت، لكنك لن تستفيد عادةً من ذلك لذا أضف الخيار ‎-h إلى الناتج لعرضه بصيغةٍ سهلة القراءة: df -h Filesystem Size Used Avail Use% Mounted on udev 238M 0 238M 0% /dev tmpfs 49M 624K 49M 2% /run /dev/vda1 20G 1.1G 18G 6% / tmpfs 245M 0 245M 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 245M 0 245M 0% /sys/fs/cgroup tmpfs 49M 0 49M 0% /run/user/1000 /dev/sda1 99G 60M 94G 1% /mnt/data وكما تلاحظ، القسم ‎/dev/vda1 الموصول في / ممتلئٌ بنسبة 6% وفيه 18 غيغابايت من المساحة التخزينية الفارغة، بينما القسم ‎/dev/sda1 موصولٌ في ‎/mnt/data وهو فارغٌ وفيه 94 غيغابايت من المساحة التخزينية. الأسطر الأخرى تستخدم أنظمة الملفات tmpfs و devtmpfs والتي هي الذاكرة المؤقتة (volatile memory) ممثلةً كما لو أنَّها وسيطُ تخزينٍ دائمٍ. يمكننا استثناء تلك القيم من الناتج بكتابة الأمر: df -h -x tmpfs -x devtmpfs Filesystem Size Used Avail Use% Mounted on /dev/vda1 20G 1.1G 18G 6% / /dev/sda1 99G 60M 94G 1% /mnt/data الناتج الحالي يُركِّز على عرض استخدام الأقراص بإزالة بعض الأجهزة الخاصة التي لن ننظر إليها عادةً. معرفة معلومات عن الأجهزة الكتلية باستخدام lsblk الجهاز الكتلي هو قطعةٌ من العتاد التي يمكن استعمالها لتخزين البيانات، مثل أقراص التخزين الصلبة الاعتيادية (HDD) أو أقراص التخزين ذات الحالة الثابتة (solid state drive أي SSD) أو وحدات الذاكرة الفلاشية (flash memory stick) …إلخ. والأجهزة الكتلية هي أقراصٌ فيزيائيةٌ التي تُكتَب عليها أنظمة الملفات، وتُحدِّد أنظمة الملفات بدورها كيفية تخزين الملفات والبيانات على القرص. يمكن استعمال الأداة lsblk لعرض معلومات عن الأجهزة الكتلية الموجودة في النظام. تَتبَع الميزات المتاحة لهذه الأداة للنسخة المُثبَّتة، لكن يمكن عمومًا استخدام الأداة lsblk لعرض معلومات عن القرص نفسه، بالإضافة إلى عرض معلومات عن طريقة التقسيم وأنظمة الملفات التابعة لتلك الأقسام. إذا نفّذنا الأمر lsblk دون وسائط فسيُظهِر أسماء الأجهزة، والأرقام الرئيسية (major) والثانوية (minor) والتي تستخدم من نواة لينكس لتتبع الأقراص والأجهزة، وفيما إذا كان القرص قابلًا للإزالة، ومساحته التخزينية، وفيما إذا كان موصولًا بنمط «القراءة فقط»، ونوعه (أي قرص أم قسم)، ونقطة الوصل. تتطلب بعض الأنظمة استخدام امتيازات الجذر (أي استخدام الأمر sudo) لعرض الناتج عرضًا صحيحًا، وهذا ما سنفعل في المثال الآتي: sudo lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 100G 0 disk vda 253:0 0 20G 0 disk └─vda1 253:1 0 20G 0 part / أهم الأجزاء المعروضة في الناتج السابق هي الاسم الذي يُشير إلى اسم الجهاز في مجلد ‎/dev، ومساحته التخزينية، ونقطة الوصل. يمكنك أن ترى في الناتج السابق أنَّنا نملك قرصًا (‎/dev/vda) فيه قسمٌ وحيد (‎/dev/vda1) الموصول في / وقرصًا آخر (‎/dev/sda) الذي لم يُقسَّم بعد. للحصول على معلوماتٍ متعلقة بإدارة القرص والقسم، فمرِّر الخيار ‎--fs الذي يعمل في بعض الإصدارات: sudo lsblk --fs NAME FSTYPE LABEL UUID MOUNTPOINT sda vda └─vda1 ext4 DOROOT c154916c-06ea-4268-819d-c0e36750c1cd / إذا لم يكن الخيار ‎--fs متوافرًا في نسختك، فيمكنك أن تطلب إظهار نفس الناتج السابق باستخدام الخيار ‎-o NAME,FSTYPE,LABEL,UUID,MOUNTPOINT‎. للحصول على معلومات حول بنية القرص، فنفِّذ الأمر: sudo lsblk -t NAME ALIGNMENT MIN-IO OPT-IO PHY-SEC LOG-SEC ROTA SCHED RQ-SIZE RA WSAME sda 0 512 0 512 512 1 deadline 128 128 2G vda 0 512 0 512 512 1 128 128 0B └─vda1 0 512 0 512 512 1 128 128 0B هنالك المزيد من الاختصارات المتوافرة لعرض مختلف المعلومات عن أقراصك وأقسامك. يمكنك عرض جميع المعلومات باستخدام الخيار ‎-0 أو يمكنك تحديد ما هي الحقول التي تريدها بتحديد اسمها باستخدام الخيار ‎-o. خيار المساعدة ‎-h سيعرض جميع الحقول المتاحة: lsblk -h . . . Available columns (for --output): NAME device name KNAME internal kernel device name . . . SUBSYSTEMS de-duplicated chain of subsystems REV device revision VENDOR device vendor For more details see lsblk(8). فصل ووصل أنظمة الملفات عليك قبل استخدامٍ قرصٍ جديدٍ أن تُقسِّمه، وأن تُهيئه بنظام ملفاتٍ معيّن، ثم تصله. عملية التقسيم والتهيئة تُجرى عادةً لمرة واحدة، لذا لن نناقشها هنا، وكما ذكرتُ في بداية هذا الدرس، تستطيع العثور على معلوماتٍ تفصيلية حول تقسيم قرص وتهيئة قسمٍ فيه في هذه المقالة. أما الوصل (mounting) فهو أمرٌ تفعله كل حين، فوصل نظام ملفاتٍ يعني أنَّه أصبح متاحًا للاستخدام داخل النظام في نقطة الوصل المُحدَّدة. ونقطة الوصل هي مجلدٌ الذي يمكننا الوصول عبره إلى نظام الملفات. يوجد أمرَين يُكمِّلان بعضها بعضًا ويستخدمان لإدارة عملية الوصل هما mount و umount. يُستعمَل الأمر mount لوصل نظام ملفات إلى شجرة الملفات الحالية، ففي نظام لينكس هنالك شجرة ملفات وحيدة لكامل النظام بغض النظر عن عدد الأجهزة الفيزيائية التي تتألف منها. أما الأمر umount (انتبه أنَّ اسم الأمر هو umount وليس unmount) فيُستعمَل لفصل نظام ملفات. إضافةً إلى الأمرين السابقين، يوجد أمرٌ باسم findmnt الذي يفيد بجمع معلومات عن حالة أنظمة الملفات الموصولة. استخدام الأمر mount أبسط طريقة لاستخدام mount هي تمرير مسار القسم ثم نقطة الوصل التي تريد وصله إليها: sudo mount /dev/sda1 /mnt نقطة الوصل –التي هي آخر وسيط والذي يُحدِّد أين يجب وصل نظام الملفات الجديد– يجب أن تُشير دائمًا إلى مجلدٍ فارغ. يمكنك تحديد بعض الخيارات عند الوصل، وصحيحٌ أنَّ الأمر mount سيحاول معرفة نوع نظام الملفات، لكن من الأفضل تمرير نوع نظام الملفات عبر الخيار ‎-t. فلنظام ملفات Ext4 نكتب: sudo mount -t ext4 /dev/sda1 /mnt هنالك الكثير من الخيارات الأخرى التي تُغيّر طريقة وصل نظام الملفات؛ حيث تتواجد خيارات الوصل العامة في قسم «FILESYSTEM INDEPENDENT MOUNT OPTIONS» في صفحة الدليل man mount، ويوجد أيضًا أقسام لمختلف أنظمة الملفات تحت عنوان «FILESYSTEM SPECIFIC MOUNT OPTIONS» في نفس صفحة الدليل السابقة لشرح الخيارات الخاصة بأنظمة ملفات معيّنة. يمكنك تمرير الخيارات الأخرى باستخدام ‎-o، فمثلًا يمكنك وصل القسم باستخدام الخيارات الافتراضية (والتي هي rw,suid,dev,exec,auto,nouser,async) بكتابة ‎-o defaults، أما إذا أردتَ مثلًا أن تتجاوز إذن السماح بالقراءة والكتابة وتريد وصل القسم للقراءة فقط، فيكنك إضافة الخيار ro والذي سيتجاوز الخيار rw من defaults: sudo mount -t ext4 -o defaults,ro /dev/sda1 /mnt لوصل جميع أنظمة الملفات الموجودة في ملف ‎/etc/fstab فمرِّر الخيار ‎-a: sudo mount -a عرض خيارات وصل أنظمة الملفات يمكن عرض خيارات الوصل المستعملة مع قسمٍ معيّن بتمرير مسار نقطة الوصل إلى الأمر findmnt، فمثلًا لو مررنا نقطة الوصل التي استعملناها في المثال السابق لوصل نظام الملفات للقراءة فقط إلى الأمر findmnt فسيبدو الناتج شبيهًا بما يلي: findmnt /mnt TARGET SOURCE FSTYPE OPTIONS /mnt /dev/sda1 ext4 ro,relatime,data=ordered يمكن أن تستفيد من هذا خير استفادة إن كنت تجرِّب عدِّة خيارات ووجدت ضالتك في إحداها، فتستطيع حينها أن تستعمل findmnt لمعرفة ما هي خيارات الوصل لإضافتها إلى ملف ‎/etc/fstab أو إذا أردتَ وصل القسم يدويًا في المستقبل. فصل نظام الملفات يستعمل الأمر umount لفصل نظام ملفات معيّن، أكرِّر أنَّ الأمر هو umount وليس unmount. الشكل العام للأمر بسيطٌ جدًا وهو تمرير نقطة الوصل أو الجهاز الموصول إلى الأمر umount. تأكّد أنَّك لا تستخدم أيّة ملفات في نقطة الوصل ولا توجد أيّة برامج (بما في ذلك الصَدَفَة [shell] التي تستعملها) تعمل داخل نقطة الوصل: cd ~ sudo umount /mnt لن تحتاج غالبًا إلى أيّة خيارات خاصة عند فصل أنظمة الملفات. الخلاصة صحيحٌ أنَّ الأدوات التي شرحناها في مقالتنا هذه ليس كثيرةً، لكنها تكفي احتياجاتك اليومية بخصوص إدارة الأقسام وأجهزة التخزين. ترجمة -وبتصرّف- للمقال How To Perform Basic Administration Tasks for Storage Devices in Linux لصاحبه Justin Ellingwood
  8. أهلًا بك في هذه السلسلة التي تتحدث عن تأثيرات التمرير (Scrolling Effects)، سنستعرض في هذه السلسلة عددٌ من تأثيرات التمرير وسنشرح آلية عملها وسنجرِّبها عمليًا. يمكننا الاستفادة من الحدث scroll في JavaScript لإجراء تأثيرات عند تمرير صفحة الويب؛ لكن إن فعلنا ذلك دون إتقان فالنتيجة كارثية، أما إذا أحسنا صنعنا فيمكن لتأثيرات التمرير أن تبهر الزوار وتشعرهم أنَّ موقعك مميز. تحدثنا في المقالتين السابقتين عن التأثيرات الآتية: إخفاء صورة خلفية تدريجيًا عند التمرير توضيح الصورة عند التمرير تدوير العناصر عند التمرير تأثير اختلاف المظهر parallax إظهار صورة الخلفية عند التمرير باستخدام CSS فقط تمرير سلس للصفحة تطبيق تأثير عدم الوضوح على المحتوى خلف شريط الانتقال وسنشرح في هذه المقالة (الثالثة) طريقة إنشاء: عنصر قابل للتمرير مع إمكانية وصول مخصصة من لوحة المفاتيح تأثير غروب الشمس باستخدام SVG إظهار فيديو في الخلفية صور متحركة بتأثير parallax باستخدام CSS 3D و JavaScript سأقدِّم لك في بداية كل قسم رابطًا لتجربة المثال تجربةً حيةً على المتصفح. سيسهل عليك كثيرًا أن تفهم الشرح والشيفرات بعد تجربتك للتأثير. عنصرٌ قابلٌ للتمرير مع إمكانية وصول مخصصة من لوحة المفاتيح (تجربة حية) كقاعدة عامة، إخفاء المعلومات المهمة داخل عنصر قابل للتمرير هي فكرةٌ سيئة، لكنه تُستعمَل عادةً من المصممين لأنها تبدو «ذات مظهرٍ جيد» بدلًا من التفكير حول قابلية استخدامها؛ لكن هنالك حالات يمكن فيها من الضروري فعل ذلك، وعندئذٍ يجب أن تكون الروابط داخل تلك العناصر قابلةً للوصول عبر لوحة المفاتيح. شيفرات HTML و CSS الأساسية تقريبًا جميع العناصر يمكن أن تُضبَط لها الخاصية overflow: scroll، لذا لن يصعب علينا إنشاء شيفرة HTML. سأذكر في هذا المثال بعض الأماكن في أفريقيا: <ol id="scrolling-list"> <li><a href=#><img src="tunisia.jpg" alt>Tunisia</a> <li><a href=#><img src="botswana.jpg" alt>Botswana</a> <li><a href=#><img src="south-africa.jpg" alt>South Africa</a> <li><a href=#><img src="kenya.jpg" alt>Kenya</a> <li><a href=#><img src="nigeria.jpg" alt>Nigeria</a> <li><a href=#><img src="tanzania.jpg" alt>Tanzania</a> </ol> ستعرض شيفرة CSS التي سنكتبها القائمةَ بارتفاعٍ معيّن، الخاصية height نفسها لن تؤثر على طريقة العرض، فالقاعدة العامة هي أنَّ المحتوى سيُعرَض دومًا حتى لو تجاوز حدود العنصر الحاوي له. إذا أردنا أن نعكس هذا السلوك، فعلينا القيام بخطواتٍ معيّنة، وفي هذه الحالة، سنضبط الخاصية overflow-y: scroll لنتيح إمكانية التمرير داخل القائمة. لاحظ استخدامنا للكلمة المحجوزة currentcolor وغيرها من الاختصارات التي تجعل عملية التطوير أسهل. ol#scrolling-list { font-size: 0; background: #333; list-style-type: none; padding-left: 0; height: 230px; overflow-y: scroll; font-weight: 100; color: #999; } ol#scrolling-list li { border-bottom: 1px dashed; } ol#scrolling-list li a { font-size: 1.2rem; text-decoration: none; line-height: 2; color: currentcolor; display: block; transition: .4s background; } ol#scrolling-list li a img { width: 20%; vertical-align: top; margin-right: .5rem; } عملية تخصيص شريط التمرير أصبحت محدودة: ففي وقتٍ سابقٍ كان متصفحا Internet Explorer و Firefox يستعملان مُحدِّدات CSS ‏(CSS selectors) لفعل ذلك، لكنهما أهملا دعمها لاحقًا. ما يزال بإمكاننا تخصيص شريط التمرير في المتصفحات التي تعتمد على المحرك Webkit، بسلسلة من المُحدِّدات الخاصية بهذا النوع من المتصفحات (والتي تُشبه تلك التي نستعملها لتخصيص حقل range للإدخال): ol#scrolling-list::-webkit-scrollbar { background: #000; } ol#scrolling-list::-webkit-scrollbar-thumb { background-color: hsl(33,100%,50%); } في النهاية، سنُخصِّص حالة ‎:hover للروابط وسنُخصِّص حالة ‎:focus أيضًا بتجميعهما معًا وذلك لتوضيح ما هو الرابط الذي نُحدِّده عبر لوحة المفاتيح: ol#scrolling-list li a:hover, ol#scrolling-list li a:focus { background: #111; } تحسين قابلية الوصول باستخدام JavaScript بافتراض أنَّ لديك إمكانية كاملة للتنقل باستخدام لوحة المفاتيح في متصفحك (أسهل متصفح لتجربة ذلك هو Chrome، إذ تتطلب بقية المتصفحات أن تضبط بعض الخيارات أولًا) وستجد أنَّك إذا ضغطتَ على زر TAB فستنتقل بين الروابط في السلسلة، فبعد أن تصبح داخل السلسلة ستتمكن من الانتقال إلى الأمام (أي إلى الروابط التالية) باستخدام TAB أو إلى الخلف (أي إلى الروابط السابقة) باستخدام SHIFT+TAB، وتتحكم أزرار الأسهم بتمرير العنصر. لا يوجد شيءٌ خاطئٌ في ما سبق، لكن في بعض الحالات سترغب بالسماح للمستخدم باستعمال أزرار الأسهم لاختيار العناصر في القائمة بدلًا من التمرير. سنحتاج في البداية إلى تحديد بعض الكائنات باستخدام JavaScript: var locales = document.getElementById('scrolling-list'), listItems = locales.children, allLnks = new Array(); for (var i = 0;i<listItems.length;i++) { allLnks[i] = listItems[i].firstElementChild; } المتغير listItems يمثِّل العناصر المُشكِّلة للقائمة، بينما allLnks فهو مصفوفة للروابط الموجودة داخل عناصر القائمة. ولأننا وضعنا تلك العناصر داخل بعضها بعضًا فهذا سيجعل بقية السكربت معقدة قليلًا: locales.addEventListener('keydown', function(e) { var focusedElement = document.activeElement, index = allLnks.indexOf(focusedElement); if (index >= 0) { if (e.keyCode == 40 || e.keyCode == 39) { if (focusedElement.parentNode.nextElementSibling) { var nextNode = focusedElement.parentNode.nextElementSibling.firstElementChild; nextNode.focus(); } else { listItems[0].firstElementChild.focus(); } } if (e.keyCode == 38 || e.keyCode == 37) { if (focusedElement.parentNode.previousElementSibling) { var previousNode = focusedElement.parentNode.previousElementSibling.firstElementChild; previousNode.focus(); } else { locales.lastElementChild.firstElementChild.focus(); } } } }); أنشأنا دالةً لمعالجة الحدث keydown (الذي يُطلَق عندما يُضغَط على أحد الأزرار في لوحة المفاتيح) عندما يَحدُثُ داخل الكائن locales، لكننا نريد أن نُغيّر سلوك مفاتيح الأسهم إذا كان أحد عناصر القائمة مُركَّزًا عليه (focused)، وإلا فسنتحكّم بسلوك مفاتيح الأسهم من بداية تحمل الصفحة، وهذا ما سيمنع المستخدمين من التمرير في الصفحة باستخدامها. لفعل ذلك سنتحقق من العنصر المُركَّز عليه حاليًا (عبر document.activeElement) وسنرى إن كان يُطابِق أحد عناصر مصفوفة الروابط التي أنشأناها، فإن طابق أحدها فسنتحقق إن كان الزر المضغوط مساوٍ لرمز السهم السفلي أو الأيمن، فإن كان كذلك فسيتم التحقق من وجود عنصرٍ يلي العنصرَ الحالي، فإن وجد فسيتم نقل التركيز إلى العنصر التالي، وإلا فسيتم التركيز على أوّل عنصر في القائمة. الشيفرة الخاصة بتغيير سلوك السهم العلوي أو الأيسر مشابهة لما سبق، حيث سيُنقَل التركيز إلى العنصر الذي يسبق العنصر الحالي، وسيُنقَل التركيز إلى آخر رابط إن وصلنا إلى أعلى القائمة. الخلاصة إذا فكّرتَ قليلًا بالسكربت وخططت له، فيمكنك إنشاء شريط تنقل جميل وقابل للوصول، وذلك بتطبيق ما تعلمته هنا لكن مع بعض التحسينات. تأثير غروب الشمس باستخدام SVG (تجربة حية) الرسوميات التي تصوِّر الطبيعة مناسبةٌ جدًا لتأثيرات parallax، وعادةً تتحرك عناصر تلك الرسوميات شاقوليًا، وتستخدم عددًا هائلًا من صور PNG (التي لها شفافية) كطبقات. وخطر ببالي أنَّه يمكن توظيف رسومات SVG كبديل ممتاز لما سبق: حيث أنَّ حجم الصورة صغيرٌ جدًا، ويمكن إعادة تلوين عناصرها أو تحريكهم كلًا على حدة كما هو ظاهر في هذا المثال. بناء الهضبات مستوية السطح تتألف الصورة من سلسلة من الهضبات مستوية السطح التي هي مسارات مغلقة (closed paths)، باستثناء الشمس التي هي دائرة مُنشَأة بعنصر <circle>: <svg id="arizona" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 279"> <circle id="sun" fill="#FFF7EB" cx="655" cy="128" r="41.5"/> <path fill="hsl(32, 89%, 75%)" d="M750 ... "/> <path fill="hsl(31, 74%, 71%)" d="M745 ..." /> أنشأنا المسارات البعيدة أولًا، أي أنَّ أبعد هضبة ستُعرَّف في البداية، ثم تليها الأقرب فالأقرب. السماء والتدرجات بدلًا من إنشاء عنصر <rect> للسماء، فسيتم ملء خلفية عنصر <svg> باستخدام CSS: #arizona { background: hsl(47, 100%, 86%); } استخدام ألوان HSL (سواءً داخل شيفرات SVG أو عبر أنماط CSS) هو المفتاح الرئيسي لهذا التأثير، وذلك بتغير درجة السطوع (luminosity) لكل عنصر وذلك عند التمرير، وبذلك سنعطي انطباعًا بشروق أو غروب الشمس. الجزء الصعب هو استخراج قيمة HSL لكل عنصر، ولفعل ذلك سأستخدم التعابير النمطية (regular expressions) في JavaScript، هذه الشيفرة تُعرِّف التعبير النمطي الذي سنستخدمه مع جمع بعض المعلومات عن عنصر SVG: var regex = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/, arizona = document.getElementById("arizona"), mesaLayers = arizona.querySelectorAll("path"), SVGoffsettop = arizona.getBoundingClientRect().top, vertHeight = arizona.getBoundingClientRect().height, sun = document.getElementById("sun"); المتغير mesaLayers يضم جميع العناصر المُشكِّلة للهضبات معًا، وسيتم التعامل مع التمرير داخل دالة: function scrollHandler() { if (window.scrollY < vertHeight) { Array.prototype.forEach.call(mesaLayers, function(layer) { var layerFill = layer.getAttribute("fill"), vertRoll = Math.abs(window.scrollY - vertHeight) / vertHeight; hslComponents = layerFill.match(regex).slice(1), newLum = parseFloat(hslComponents[2]) * vertRoll; layer.style.fill = "hsl(" + hslComponents[0] +", " + hslComponents[1] + "%, " + newLum + "%)"; arizona.style.background = "hsl(48, " + 100 * vertRoll + "%, " + 88 * vertRoll + "%)"; sun.style.transform = "translate3d(0," + window.scrollY / 10 + "px, 0)"; }) } هذه الدالة تفعل ما يلي بالترتيب: الحصول على الخاصية fill لكل عنصر path تحديد مدى تمرير النافذة استخلاص قيمة HSL من كل عنصر path تعديل سطوع العنصر اعتمادًا على مقدار التمرير إعادة تجميع لون HSL لكل عنصر path الذي يضم السطوع الجديد، وتطبيقه على كل عنصر تعديل خاصية background لعنصر SVG، وأيضًا اعتمادًا على مقدار التمرير تمرير عنصر sun إلى الأسفل باستخدام translate3d لإنشاء تأثير الغروب ملاحظة: لا تعمل ميزة CSS transforms على عناصر SVG في متصفح Internet Explorer أو Edge بعد، على الرغم من أنَّ مفترض أن تدعم الإصدارات القادمة تلك الميزة. تُستدعى الدالة باستخدام requestAnimationFrame لتحسين الأداء: window.onscroll = function() { window.requestAnimationFrame(scrollHandler); } تبطيء التأثير قد تواجه إشكاليات عند ربط العناصر بالتمرير، فقد تتحول العناصر بسرعة كبيرة مما يجعلك تفقد شعورك بالتأثير… لذا فإنَّ أسهل طريقة لتبطيء التأثير هي استخدام مقياس للتمرير. غيّر الشيفرة السابقة لتصبح كما يلي: if (window.scrollY < SVGoffsettop * 4) { Array.prototype.forEach.call(mesaLayers, function(layer) { var layerFill = layer.getAttribute("fill"), vertRoll = Math.abs((window.scrollY / 4 ) - SVGoffsettop) / SVGoffsettop; … الخلاصة وأمور يمكن تحسينها عادةً يُستعمَل هذا التأثير بعد ضبط الخاصية position: fixed على عنصر SVG لإبقائه ظاهرًا أثناء تمرير الصفحة، إلا أنني لم أفعل ذلك هنا لأغراضٍ توضيحية. يمكن أيضًا دمج تأثير parallax معه عند التمرير، لكنني قررتُ أن أركِّز على تأثير غروب الشمس فقط. هنالك جانبان يمكن تطويرهما في السكربت: تكرار استخراج قيم ألوان HSL وتركيبها، فمن الأفضل جعل تلك القيم كخاصيات لكل عنصر لكي يتم الوصول إليها بسهولة عبر السكربت، بدلًا من إعادة حسابها كل مرة. ألوان خلفية السماء مكتوبة ضمن السكربت؛ ومن الأفضل إسناد الألوان باستخدام CSS، مما يجعل السكربت قادرًا على التعامل مع التغييرات في العرض دون الحاجة إلى تكرار التغييرات. إظهار فيديو في الخلفية (تجربة حية) نُشِرَت مقالة عن كيفية إنشاء فيديو في كامل خلفية الصفحة باستخدام HTML5 ، لكن أتت أسئلة على ذاك المقال للسؤال عن كيفية إنشاء فيديو يظهر خلف المحتوى، لكن يمكن تمريره كباقي محتويات الصفحة. فاجأني ذلك قليلًا، لأنَّ بالإمكان فعل ذلك باستخدام CSS مع نفس التقنيات التي نستعملها مع الصور… لكن أتتني الفرصة هنا لإعطاء مثال عن أنماط الاندماج (blend modes). الشيفرات تبدو شيفرة إضافة مقطع الفيديو تقليديةً، حيث سنضعها داخل وسم <main> (بدلًا من وضعها مباشرةً بعد العنصر <body> كما في المقالة الأصلية)، وسأفترض في هذا المثال أنَّ وسم video موجودٌ داخل العنصر <header> ضمن وسم <main>: <main> <header> <video autoplay loop> <source src="forest-fire.webm"> <source src="forest-fire.mp4"> </video> </header> ملاحظة: يجب أن يتبع الفيديو نفس القواعد العامة لمقاطع الفيديو التي تعمل في الخلفية الموجودة في المقالة الأصلية. يجب تنسيق الفيديو بأنماط CSS مماثلة لتلك التي كنتَ ستستعملها لعرض الصور المتجاوبة بكامل العرض: main { width: 80%; max-width: 750px; margin: 0 auto; } main > header video { width: 100%; height: auto; } ملاحظة: إذا أردتَ أن يظهر الفيديو بكامل عرض الشاشة، فبدِّل قيمة الخاصيتين width و max-width للعنصر main لتوسعته. يجب إضافة «طبقة» أمام مقطع الفيديو فيها ترويسة ورابط للانتقال إلى محتوى الصفحة. العناصر التالية يجب أن توضع بعد الوسم <video>: <h1>A world Aflame</h1> <a href="#maincontent">▼</a> </header> سيؤدي الضغط على الرابط إلى الانتقال إلى العنصر ذي المعرِّف maincontent. يجب أن نُعدِّل CSS الآن للسماح بإظهار العناصر الجديدة كطبقة تعلو مقطع الفيديو: main > header { position: relative; } أنماط CSS للترويسة <h1> وللرابط: main > header h1 { position: absolute; bottom: 40%; left: 1rem; font-size: 4rem; text-transform: uppercase; mix-blend-mode: overlay; } main > header a { display: block; text-decoration: none; font-size: 2rem; color: #fff; opacity: .5; position: absolute; bottom: 1.5rem; width: 100%; text-align: center; transition: .3s; animation: downwardprompt 2s 1s; } main > header a:hover { opacity: 1; } سيتم تطبيق تأثير حركي على السهم بعد عدِّة ثواني من تحميل الصفحة، مما يلفت انتباه المستخدم إليه: @keyframes downwardprompt { to { transform: translateY(2rem); opacity: 0; } } هذا كل ما في الأمر، بالطبع يمكنك القيام بالكثير باستخدام هذه التقنية، إلا أنَّ شيفرات CSS الأساسية ستبقى نفسها تقريبًا. صور متحركة بتأثير parallax باستخدام CSS 3D و JavaScript (تجربة حية) صحيحٌ أنَّ هنالك الكثير من الطرائق والتقنيات الموجودة على الويب لإنشاء تأثير parallax، لكنني أرى أنَّها تُزِّيف تأثير العمق في الصور، لكنني وجدتُ أنَّ تقنيةCSS 3D تسمح بتغيير مكان الصور على المحور z، مما يجعل تأثير تغيير المنظور حقيقيًا أثناء تحريك الصور إلى الأعلى وإلى الأسفل. وصحيحٌ أنَّ شيفرة هذا المثال ما تزال بدائيةً وبسيطةً، إلا أنَّني أرى أنها تستحق المشاركة. الشيفرات الأساسية هنالك شيفرة HTML بسيطة جدًا في هذا المثال، وهي عبارة عن عنصر <div> بسيط: <div id="parallax-container"> </div> سيُملأ هذا العنصر بالصور المُحمَّلة عبر شيفرة JavaScript، لكن علينا أولًا أن نضبط الأنماط اللازمة لعنصر <div> وللصور التي ستظهر داخله: #parallax-container { background: #16161d; margin: 0; overflow: hidden; perspective: 1200px; height: 100vh; width: 100vw; transform-style: preserve-3d; } #parallax-container img { transform-origin: center; box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.4); position: relative; } ملاحظة: إن لم تكن تألف التعامل مع واحدات vw و vh أو CSS 3D، فاقرأ المزيد عنها في هذه السلاسل. الصور المتحركة الخطوة التالية هي إضافة الصور، وتنسيقها باستخدام CSS، ثم جعل JavaScript تخفيها ثم تُجري عمليات عليها لتحقيق التأثير المطلوب. ولأنَّ أسماء ملفات الصور لها نفس النمط في هذا المثال (أي wave1.jpg و wave2.jpg …إلخ.) فيمكنني استخدام JavaScript لتوليد أسماء الملفات مع إنشاء بعض المتغيرات التي ستلزمنا لاحقًا في السكربت: var container = document.getElementById("parallax-container"), waveSrc = [], waves = [], imgLoc = "", j = 0; for (var i = 0; i < 10; i++) { waveSrc[i] = imgLoc+"wave"+(i+1)+".jpg"; } سنحتاج أيضًا إلى بعض الأرقام العشوائية، لذا سأولدها باستخدام هذه الدالة: function getRandomInRange(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } سنحتاج أيضًا إلى مرجع (reference) إلى الصور التي جرى تحميلها، بالإضافة إلى عرض وارتفاع الشاشة الحالي (بافتراض أنَّ نافذة المتصفح مُكبَّرَة). var screenWidth = window.screen.width, screenHeight = window.screen.height; وعند اكتمال تحميل الصور وإضافتها إلى عنصر <div>، فسنوفِّر لها خاصيات –وهي ‎.xPlane و ‎.yPlane و ‎.zPlane– بقيمٍ عشوائية، والتي ستُحدِّد موضع الصورة في فضاءٍ ثلاثي الأبعاد. سأترك قيم الخاصية alt في هذا المثال فارغةً وذلك للاختصار: function preloadImage(filename){ var img=new Image(); img.onload = function(){ img.xPlane = getRandomInRange(-500, screenWidth - 500); img.yPlane = getRandomInRange(500, 1000); img.zPlane = getRandomInRange(300,2000); img.style = "transform: translate3d(" + img.xPlane +"px, " + img.yPlane + "px, -" + img.zPlane +"px)"; container.appendChild(img); }; imgLoc = ""; img.src= imgLoc + filename; img.alt = ""; waves[j] = img; j++; } function loadImages(){ for (var i = 0; i < waveSrc.length; ++i) { var filename = waveSrc[i]; preloadImage(filename); } } أخيرًا، ستُحرَّك الصور باستخدام دالة: function moveImages(){ waves.forEach(function(image) { image.yPlane = image.yPlane - 2; image.style.cssText = "transform: translate3d(" + image.xPlane+"px, " + image.yPlane+"px, -" + image.zPlane + "px); z-index: " + image.zIndex; }); window.requestAnimationFrame(moveImages); } وسيتم تشغيل المثال باستدعاء الدوال المناسبة في نهاية السكربت: loadImages(); window.addEventListener("load", function() { window.requestAnimationFrame(moveImages); }); تحسينات إضافية على المثال ما يزال هذا المثال مبدئيًا، وهنالك عدِّة أشياء يمكن إجراؤها لتطويره: 1. سيستمر تشغيل السكربت حتى بعد أن تختفي الصور من أعلى العنصر الحاوي لها، وستستمر بالحركة إلى اللانهاية؛ لذا من الأفضل أنَّ نُزيل الصور من بداية المصفوفة بعد اختفائها ثم إضافتها مرةً أخرى لتظهر مجددًا. 2. ربما من الأفضل أنَّ نُقلِّل من العشوائية في مواضع الصور، فالآن يمكن أن تظهر إحدى الصور خلف صورةٍ أخرى مباشرةً، أو قريبة منها كثيرًا في البُعد z (وبالتالي ستتحرك الصورتان بسرعةٍ قريبةٍ من بعضهما). ولفعل ذلك علينا أن نقارن أماكن الصور الجديدة بتلك التي أنشأناها من قبل في المصفوفة، وتوليد قيمة جديدة إن كانت القيمتان متقاربتين. 3. سيتم تحريك الصور تلقائيًا، إذا أردتَ أن تربط حركة الصور بتغيير شريط التمرير في الصفحة، فعليك أن تُغيّر موضع الصور بالنسبة إلى window.scrollY. ترجمة وبتصرّف للمقالات A Custom Scrolling Element With Keyboard Accessibility و Scrolling Background Video with Layered Content و A Scrolling SVG Sunset و Parallax Image Scrolling Animation with CSS 3D and JavaScript لصاحبها Dudley Storey
  9. أهلًا بك في هذه السلسلة التي تتحدث عن تأثيرات التمرير (Scrolling Effects)، سنستعرض في هذه السلسلة عددٌ من تأثيرات التمرير وسنشرح آلية عملها وسنجرِّبها عمليًا. يمكننا الاستفادة من الحدث scroll في JavaScript لإجراء تأثيرات عند تمرير صفحة الويب؛ لكن إن فعلنا ذلك دون إتقان فالنتيجة كارثية، أما إذا أحسنا صنعنا فيمكن لتأثيرات التمرير أن تبهر الزوار وتشعرهم أنَّ موقعك مميز. تحدثنا في المقالة السابقة عن التأثيرات الآتية: إخفاء صورة خلفية تدريجيًا عند التمرير توضيح الصورة عند التمرير تدوير العناصر عند التمرير تأثير اختلاف المظهر parallax أما المقالة الحالية (الثانية) فهي تتضمن التأثيرات الآتية: إظهار صورة الخلفية عند التمرير باستخدام CSS فقط تمرير سلس للصفحة تطبيق تأثير عدم الوضوح على المحتوى خلف شريط الانتقال وسنشرح في آخر مقالة طريقة إنشاء: عنصر قابل للتمرير مع إمكانية وصول مخصصة من لوحة المفاتيح تأثير غروب الشمس باستخدام SVG إظهار فيديو في الخلفية صور متحركة بتأثير parallax باستخدام CSS 3D و JavaScript سأقدِّم لك في بداية كل قسم رابطًا لتجربة المثال تجربةً حيةً على المتصفح. سيسهل عليك كثيرًا أن تفهم الشرح والشيفرات بعد تجربتك للتأثير. إظهار صورة الخلفية عند التمرير باستخدام CSS فقط (تجربة حية) طريقة عرض جميلة وشائعة هي «إظهار صورة الخلفية عند التمرير»: فكلما مَرَّرنا إلى الأسفل، فستصبح صورة الخلفية المخفية ظاهرةً للمستخدم. صحيحٌ أنَّ طريقة العرض هذه أصبحت شائعة في الآونة الأخيرة، إلا أنَّها جيدة حيث تجعل المحتوى مركَّزًا ومختصرًا إلى بضع صور وفقرات قصيرة من النص. يُحقَّق هذا التأثير عادةً باستخدام إطار عمل من إطارات JavaScript مع إحدى الإضافات؛ وهذا غير ضروري أبدًا في المتصفحات الحديثة، وسأريك طريقة فعل ذلك. «النوافذ والجدران» الفكرة الأساسية لهذا التأثير هي إنشاء سلسلة من «النوافذ» المفتوحة و«الجدران» المغلقة فوق بعضها بعضًا، وكلٌ منها له نفس الطول والعرض الخاص بإطار العرض (viewport). لنبدأ بإنشاء شيفرة HTML بسيطة. يمكن إنشاء «النوافذ» و«الجدران» من أيّ عنصر HTML قادر على احتواء العناصر الأخرى؛ وسنستخدم في هذا المثال وسوم <section>: <section> <h1>Come To Iceland</h1> </section> <section> <h1>The last settled part of Europe, much of Iceland remains pristine and untouched.</h1> </section> … لجعل قياس جميع العناصر صحيحًا، فسأحذف أيّة هوامش (margin) من العنصر <body>، تأكد أنَّ العناصر <section> مُقاسة عبر border-box، وتأكد أنَّ لكل عنصرٍ منها له نفس ارتفاع إطار العرض باستخدام واحدات vm. يجب تنسيق النص ليستخدم نفس الواحدات السابقة: body { margin: 0; } section { box-sizing: border-box; height: 100vh; text-align: center; padding: 2vw; font-size: 6vw; } عناصر <section> تأخذ كامل عرض نافذة المتصفح، ولتوسيط محتواها فسنستعمل flexbox، ويجب إجراء المثل على عناصر <section> التي ستعرض صور الخلفية، لذا سأُضمِّن أنماطها أيضًا: section { display: flex; align-items: center; justify-content: center; text-align: center; flex-direction: column; background-size: cover; background-repeat: no-repeat; background-attachment: fixed; } تُستخدم الخاصية flex-direction لإغلاق أيّة «نوافذ» التي تحتوي عدِّة أسطر نصية. ويجب علينا إضافة نمط خاص بأوّل عنصر <section> لأنَّ النص فيه أكبر، ولونه أبيض، ومكتوبٌ بأحرفٍ كبيرة، مع استخدام الخاصية text-shadow لإضافة ظل لتميزه عن الخلفية: section:first-of-type { text-transform: uppercase; color: #fff; font-size: 8vw; text-shadow: 0 0 5px rgba(0,0,0,0.4); } عناصر <section> الزوجية لها خلفية بيضاء: section:nth-of-type(even) { background: #fff; } أما عناصر <section> الفردية فلها صور خلفية: section:nth-of-type(1) { background-image: url(iceland-fjords.jpg); } section:nth-of-type(3) { background-image: url(iceland-pool-faces.jpg); } section:nth-of-type(5) { background-image: url(iceland-ice.jpg); } وهذا كل ما في الأمر! صحيحٌ أنَّ المثال السابق يعمل على المتصفحات الحديثة فقط والتي تدعم vh و vm و flexbox؛ وإذا كنتَ تنوي دعم المتصفحات القديمة فعليك استخدام بدائل مثل نمط العرض table-row لكل عنصر <section> … تمرير سلس للصفحة (تجربة حية) تتواجد في HTML ميزة الانتقال إلى أماكن معيّن في الصفحة، وذلك بتوفير خاصية id للعنصر الذي تريد الانتقال إليه، ومن ثم ربط ذلك عبر عناصر <a>. لكن الحركة غير سلسة وستنتقل فوريًا إلى العنصر الهدف؛ ولكن بغرض تحسين طريقة عرض واستخدام الموقع، فيتطلّب أحيانًا تصميم الموقع أن يتم التمرير بشكلٍ سلسٍ أو بطيء إلى نقطةٍ معيّنةٍ في الصفحة. قديمًا كانت تُستعمَل jQuery لذلك، لكن من غير المعقول تحميل إطار عمل كامل لاستخدام هذه الميزة فقط؛ وتوفِّر JavaScript طريقةً أفضل وأسرع (من ناحية الأداء) وهي الدالة window.scrollTo. سنستخدم عنصر <a> كأساس لهذه التقنية، وبهذه الطريقة سيتم الانتقال إلى الهدف حتى لو لم تعمل شيفرة التمرير السلس لسببٍ من الأسباب. <a href="#destination">Click me: I’m <em>smoooooth</em>.</a> … <p id="destination">This is the target, further down the page. وكما هو واضح، يجب أن تكون الصفحة طويلةً بعض الشيء وتمتد إلى ما بعد أسفل إطار العرض لكي تعمل هذه التقنية، لأنَّه إذا عُرِضَت كامل محتويات الصفحة في نافذة المتصفح، فلا حاجة إلى التمرير من الأساس؛ ولهذا السبب عليك أن تضع الكثير من المحتوى في الصفحة للتجربة. طريقتان للتمرير بسلاسة قد يبدو الأمر مربكًا بعض الشيء، إلا أنَّ البنية البرمجية للتمرير السلس موجودة في CSS وفي JavaScript، وأنَّ بعض المتصفحات تدعم تلك البنية البرمجية والأخرى لا تدعمها (انظر فقرة «دعم المتصفحات» في الأسفل). ففي CSS إذا أردنا أنَّ يكون التمرير سلسًا لأحد العناصر (وعادةً ما نستخدم العنصر body لكن ذلك ليس ضروريًا) فعلينا أن نضبط الخاصية scroll-behavior ونسند القيمة smooth إليها: body { scroll-behavior: smooth; } لاحظ أنَّ كلمة «behavior» (في scroll-behavior) لا تحتوي على حرف «u». طريقة JavaScript سنضيف شيفرة JavaScript إلى نهاية الصفحة لكي تُنفَّذ بعد انتهاء تحميل الصفحة: var anchorLink = document.querySelector("a[href='#destination']"), target = document.getElementById("destination"); anchorLink.addEventListener("click", function(e) { if (window.scrollTo) { e.preventDefault(); window.scrollTo({"behavior": "smooth", "top": target.offsetTop}); } }) الدالة querySelector تستعمل نفس طريقة كتابة محدِّدات CSS للعثور على أوّل رابط الذي يشير إلى ‎#destination؛ والضغط على هذا الرابط سيؤدي إلى تنفيذ عبارة شرطية للتأكد من دعم المتصفح للدالة scrollTo، فإن دعمها المتصفح فستوقف الدالة e.preventDefault المتصفحَ من الانتقال مباشرةً إلى الفقرة الهدف، وسنستخدم الدالة scrollTo بدلًا من ذلك بعد ضبطها ليكون التمرير سلسًا. تأخذ الدالة scrollTo وسيطين هما behavior و top، مع وسيطٍ اختياريٍ هوleft، ويقبل آخر وسطين إحداثيات المكان الذي نريد الانتقال إليه. يمكن استخدام الدالةwindow.scrollفي المثال السابق، لأنَّ وظيفتها مماثلة لوظيفة الدالةwindow.scrollTo`. مقارنةً مع استخدام إطار عمل، فإنَّ هذه الطريقة أبسط بكثير؛ لكن الجانب السلبي لها هو أنَّها لا تسمح للمصمم بتغيير دالة التوقيت أو حركات التمرير، لتجنّب استعمال المصممين استعمالًا سلبيًا لها. إنشاء سكربت عام السكربت السابق يعمل عمله بشكلٍ صحيح، لكنه يتطلب أن تعرف ما هو اسم العنصر الهدف، ولا يمكن تطبيقه إلا على رابطٍ وحيد. ماذا إذا أردت إنشاء سلسلة من الروابط التي تُشير إلى عناصر مختلفة؟ سنحتاج في هذه الحالة إلى جعل السكربت عامًا. سنبدأ السكربت بإنشاء دالة التي تسمح لنا بمعالجة كل رابط بحلقة forEach: var forEach = function (array, callback, scope) { for (var i = 0; i < array.length; i++) { callback.call(scope, i, array[i]); } }; ثم سأُحدِّد جميع الروابط، وأرى ما هو العنصر التي تشير إليه، ومن ثم سأطبِّق scrollTo عند النقر عليها: var anchorLinks = document.querySelectorAll("a[href^='#']"); if (window.scrollTo) { forEach(anchorLinks, function(index, element) { var target = document.getElementById(element.getAttribute("href").substring(1)); element.addEventListener("click", function(el) { el.preventDefault(); window.scrollTo(0, target.offsetTop); }) }); } لاحظ أنَّ هذا قد يتطلب وضع الخاصية scroll-behavior لعنصر body كما سبق ذكره. دعم المتصفحات هنالك إشكالية وحيدة عند استخدام هذه الطريقة في الوقت الراهن ألا وهي دعم المتصفحات؛ حيث تعمل الدالة window.scrollTo في متصفحات الويب الحديثة. ولأننا كتبنا السكربت بطريقة تجعله يتحقق أولًا من دعم المتصفح للدالة scrollTo، فستعمل الصفحة بشكل سليم على المتصفحات القديمة إلا أنَّ التمرير سيكون فوريًا وليس سلسًا؛ ويمكنك أن تستعمل إحدى الإضافات أو الطرائق الأخرى لدعم المتصفحات القديمة. تطبيق تأثير عدم الوضوح على المحتوى خلف شريط الانتقال (تجربة حية) أحد أنماط تصميم الواجهات الشائعة خصوصًا بعد إصدار نسخة iOS 7 هو شريط الانتقال الذي تظهر محتويات الصفحة التي خلفه مشوشةً؛ ربما تظن أنَّ تطبيق المُرشِّح blur في CSS هو الطريقة السهلة والواضحة لتطبيق هذا التأثير في صفحة ويب، وهذا صحيحٌ إلا أنَّ هنالك إشكالية: تأثيرات CSS ستُطبَّق على المحتوى داخل العنصر وليس خلفه. أي لا يوجد تأثير من تأثيرات CSS الذي يمكن أن يؤدي إلى تشويش العناصر خلفه، باستثناء خاصية اختبارية متوافرة في متصفح Safari 9 فقط باسم ‎-webkit-backdrop-filter-؛ لكن بالطبع سنجد حلًا! إنشاء شريط الانتقال الشريط نفسه هو عنصرٌ فارغٌ يملك القيمة fixed للخاصية position، وعناصر التنقل تأتي «فوق» ذاك العنصر باستعمال نفس الأبعاد. سأكتبُ ذلك باستخدامSass لأنَّها أقصر: #blurrycontent { padding: 1rem; top: 0; left: 0; width: 100%; height: 5rem; overflow: hidden; position: fixed; filter: blur(4px); } nav { @extend #blurrycontent; filter: none; text-align: right; } يجب أن تتواجد بقية الصفحة داخل العنصر <main>، وليس داخل العنصر <body>، وذلك لأسبابٍ سنوضِّحها بعد لحظات: <main id="content"> <h1>London</h1> <p>With roots at least 7,000 years old, London is an accretion of artifacts old and new, from the remnants of wooden Neolithic settlements buried in the mud of the Thames to gleaming 21st century spires of glass and steel… </main> ولأنَّ العنصرين ‎#blurrycontent و <nav> متموضعَين فوق بعضهما في مكانٍ ثابتٍ في أعلى الشاشة، فيجب تنسيق العنصر <main> لكي يأخذ مكان بقية المحتوى: main { margin: 0; background: url(london_background.jpg); background-size: cover; padding: 2rem; } حسنًا، تبدو الصفحة جيدةً، لكننا لم نرَ أيّة تأثيرات في منطقة شريط التنقل عندما يتم التمرير؛ وهذا ما سنفعله في الخطوة الآتية. إنشاء تأثير «الزجاج»! كما ذكرتُ في البداية، لا تُطبّق تأثيرات CSS إلا على المحتوى الموجود داخل العنصر، وليس تحته؛ لذا سنأخذ نسخةً من العنصر <main> ونضعها داخل العنصر ‎#blurrycontent باستخدام الدالة cloneNode عبر سكربت موجود في أسفل الصفحة: var pageContent = document.getElementById("content"), pagecopy = pageContent.cloneNode(true), blurryContent = document.getElementById("blurrycontent"); blurryContent.appendChild(pagecopy); قد لا تستطيع ملاحظة التأثير في هذه المرحلة، لأنَّ المحتوى الموجود داخل العنصر ‎#blurrycontent لن يُمرَّر مع بقية المستند، وعلينا مزامنة حركتهما بإضافة السطر الآتي إلى السكربت: window.onscroll = function() { blurryContent.scrollTop = window.pageYOffset; } بعد أن ربطناهما مع بعضهما بعضًا، فيمكننا أن نُمرِّر الصفحة وسنحصل على نفس المحتوى الموجود تحت شريط التنقل في عنصر ‎#blurrycontent لكنه مشوش. ولأنَّ العنصر <nav> غير موجود داخل العنصر ‎#blurrycontent فلن يخضع لتأثير عدم الوضوح. محدوديات هذه الطريقة كما هو واضح، إنشاء نسخة من محتوى الصفحة وتطبيق تأثير عدم الوضوح عليها سيؤدي إلى عبءٍ إضافيٍ على المتصفح وعلى المعالج الرسومي، لذا كن حذرًا في ذلك وقدِّر كمية المحتوى الموجود ضمن العنصر <main> قبل نسخه. الدالة cloneNode تنسخ العنصر نسخًا حيًا، أي أنَّ أيّة تعديلات على العنصر الأصلي ستُطبَّق أيضًا على العنصر المنسوخ، لكن ربما تلاحظ تأثيرًا بسيطًا حتى تتم مزامنة كلا النسختين. هذه أربع نقاط أخيرة يجب ملاحظتها: لأنَّ بعض إصدارات متصفح Internet Explorer لا تدعم تأثيرات CSS (وأوقف المتصفح دعم النسخة الخاصة به من هذا التأثير، والتي كانت متاحةً في الإصدارات القديمة منه)، فلن تلاحظ أيّة تغييرات في شريط التنقل في متصفح IE. يجب أن تتجنب استخدام العناصر ذات الموضع الثابت (fixed) في صفحات الويب على الهواتف الذكية والأجهزة اللوحية، فمنذ فترةٍ قريبةٍ كانت طريقة تعامل متصفحات الهواتف مع position: fixed سيئةً، وسيتم حجز مساحة من الشاشة الصغيرة. وصحيحٌ أنَّ هذا التأثير مستوحى من أحد أنظمة الهواتف، ألا أنَّه من الأفضل إيقافه في الشاشات الصغيرة باستخدام مجموعة من media queries (أو يمكنك أن تصمم الموقع للهواتف أولًا [mobile-first] ولا تُشغِّل التأثير حتى تصبح الشاشة بمقاسٍ معيّن). يجب أخذ قابلية الوصول (Accessibility) بعين الاعتبار عند إنشاء مثل هذا التأثير، فستُفسِّر قارئات الشاشة شجرة DOM، وليس ما تراه على الشاشة، وهذا يعني أنَّ قارئات الشاشة ستحصل على نسختين من محتوى الصفحة افتراضيًا، ولتنجب ذلك فسأضع aria-hidden="true"‎ في العنصر ‎#blurrycontent: <div id="blurrycontent" aria-hidden="true"></div> وبهذا سترى قارئات الشاشة النسخةَ الأصلية من الصفحة فقط دونًا عن النسخة الموجودة في العنصر ‎#blurrycontent. يجب أن تكون حذرًا عند نسخ العناصر التي لها الخاصية id، فقد يؤدي تكرار قيم الخاصية id إلى تضاربات ومشاكل في CSS و JavaScript. ترجمة وبتصرّف للمقالات Background Reveal Scroll In Pure CSSو Smooth Page Scroll in 5 Lines of JavaScript و Scroll-Behind Blurred Site Navigation Barلصاحبها Dudley Storey
  10. أداة mysqladmin هي أداةٌ سطريةٌ (أي تعمل من سطر الأوامر) تأتي مع خادوم MySQL ويستعملها مدراء قواعد البيانات لإجراء مهام أساسية لإدارة قواعد MySQL مثل ضبط كلمة مرور المستخدم root أو تغييرها، ومراقبة عمليات mysql وإعادة تحديث امتيازات المستخدمين والتحقق من حالة الخدمة …إلخ. سنضع في هذا الدرس بعض أوامر mysqladmin المفيدة والمُستعمَلة من مدراء النظام أو مدراء قواعد البيانات يوميًا. يجب أن يكون خادوم MySQL مثبتًا على نظامك لإجراء هذه المهام. إذا لم يكن خادوم MySQL مثبتًا على نظامك، أو كنتَ تستعمل إصدارًا قديمًا منه، فأنصحك بتثبيت أو تحديث نسختك كما ذكرنا في هذه المقالة. 1. كيفية ضبط كلمة مرور المستخدم root في MySQL؟ إذا كانت لديك نسخةٌ حديثةُ التثبيت من خادوم MySQL، فلن تحتاج إلى استخدام كلمة مرور للاتصال بها عبر المستخدم root، لكن ذلك ليس آمنًا، وأنصحك بضبط كلمة مرور له، وذلك بتنفيذ الأمر الآتي: # mysqladmin -u root password YOURNEWPASSWORD 2. كيفية تغيير كلمة مرور المستخدم root؟ إذا أردتَ تحديث أو تغيير كلمة مرور المستخدم root في قواعد بيانات MySQL، فيمكنك الاستعانة بالأمر الآتي. لنفترض مثلًا أنَّ كلمة مرورك القديمة هي 123456 وأردتَ الآن تغييرها إلى كلمةٍ أخرى ولتكن xyz123: # mysqladmin -u root -p123456 password 'xyz123' 3. كيفية التحقق إذا كان خادوم MySQL يعمل؟ استعمل الأمر الآتي لتعرف إن كان خادوم MySQL يعمل أم لا: # mysqladmin -u root -p ping Enter password: mysqld is alive 4. كيف أعرف إصدار MySQL الذي أعمل عليه؟ الأمر الآتي سيُظهِر إصدار MySQL المُثبَّت على خادومك، إضافةً إلى حالته: # mysqladmin -u root -p version Enter password: mysqladmin Ver 8.42 Distrib 5.5.28, for Linux on i686 Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Server version 5.5.28 Protocol version 10 Connection Localhost via UNIX socket UNIX socket /var/lib/mysql/mysql.sock Uptime: 7 days 14 min 45 sec Threads: 2 Questions: 36002 Slow queries: 0 Opens: 15 Flush tables: 1 Open tables: 8 Queries per second avg: 0.059 5. كيف أعرف ما هي حالة خادوم MySQL الآن؟ يمكن أن يُظهِر الأمر mysqladmin حالة uptime بالإضافة إلى عدد الخيوط (threads) وإحصائيات عن الاستعلامات: # mysqladmin -u root -ptmppassword status Enter password: Uptime: 606704 Threads: 2 Questions: 36003 Slow queries: 0 Opens: 15 Flush tables: 1 Open tables: 8 Queries per second avg: 0.059 6. كيفية التحقق من حالة جميع متغيرات خادوم MySQL وقيمها؟ استخدم الخيار extended-status لأمر mysqladmin لرؤية حالة جميع متغيرات خادوم MySQL والقيم المرتبطة بها. يجب أن تكون المخرجات شبيهةً بما يلي: # mysqladmin -u root -p extended-status Enter password: +------------------------------------------+-------------+ | Variable_name | Value | +------------------------------------------+-------------+ | Aborted_clients | 3 | | Aborted_connects | 3 | | Binlog_cache_disk_use | 0 | | Binlog_cache_use | 0 | | Binlog_stmt_cache_disk_use | 0 | | Binlog_stmt_cache_use | 0 | | Bytes_received | 6400357 | | Bytes_sent | 2610105 | | Com_admin_commands | 3 | | Com_assign_to_keycache | 0 | | Com_alter_db | 0 | | Com_alter_db_upgrade | 0 | | Com_alter_event | 0 | | Com_alter_function | 0 | | Com_alter_procedure | 0 | | Com_alter_server | 0 | | Com_alter_table | 0 | | Com_alter_tablespace | 0 | +------------------------------------------+-------------+ 7. كيفية معرفة قيم جميع المتغيرات المُفعّلة لخادوم MySQL؟ لرؤية جميع القيم التي تعمل حاليًا في خادوم MySQL، أدخِل الأمر الآتي: # mysqladmin -u root -p variables Enter password: +---------------------------------------------------+----------------------------------------------+ | Variable_name | Value | +---------------------------------------------------+----------------------------------------------+ | auto_increment_increment | 1 | | auto_increment_offset | 1 | | autocommit | ON | | automatic_sp_privileges | ON | | back_log | 50 | | basedir | /usr | | big_tables | OFF | | binlog_cache_size | 32768 | | binlog_direct_non_transactional_updates | OFF | | binlog_format | STATEMENT | | binlog_stmt_cache_size | 32768 | | bulk_insert_buffer_size | 8388608 | | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | | collation_connection | latin1_swedish_ci | +---------------------------------------------------+----------------------------------------------+ 8. كيفية التحقق من جميع العمليات التي يستخدمها خادوم MySQL؟ الأمر الآتي سيعرض جميع العمليات التي تستعملها استعلامات قواعد بيانات MySQL: # mysqladmin -u root -p processlist Enter password: +-------+---------+-----------------+---------+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +-------+---------+-----------------+---------+---------+------+-------+------------------+ | 18001 | rsyslog | localhost:38307 | rsyslog | Sleep | 5590 | | | | 18020 | root | localhost | | Query | 0 | | show processlist | +-------+---------+-----------------+---------+---------+------+-------+------------------+ 9. كيفية إنشاء قاعدة بيانات على خادوم MySQL؟ استخدم الأمر الآتي لإنشاء قاعدة بيانات جديدة في MySQL: # mysqladmin -u root -p create databasename Enter password: للتحقق من إنشائها: # mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 18027 Server version: 5.5.28 MySQL Community Server (GPL) by Remi Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | databasename | | mysql | | test | +--------------------+ 8 rows in set (0.01 sec) mysql> 10. كيفية حذف قاعدة بيانات في خادوم MySQL؟ لحذف قاعدة بيانات في خادوم MySQL، فأدخِل الأمر الآتي. سيُطلَب منك الموافقة على ذلك بكتابة الحرف y: # mysqladmin -u root -p drop databasename Enter password: Dropping the database is potentially a very bad thing to do. Any data stored in the database will be destroyed. Do you really want to drop the 'databasename' database [y/N] y Database "databasename" dropped 11. كيفية إعادة تحميل أو إعادة تحديث الامتيازات في MySQL؟ الأمر reload سيطلب من الخادوم إعادة تحميل جداول الامتيازات، بينما الأمر refresh سيؤدي إلى إعادة قراءة جميع الجداول وإعادة فتح ملفات التسجيل (log files): # mysqladmin -u root -p reload; # mysqladmin -u root -p refresh 12. كيفية إيقاف خادوم MySQL بأمان؟ لإيقاف خادوم MySQL إيقافًا آمنًا، فاكتب الأمر الآتي: mysqladmin -u root -p shutdown Enter password: أو يمكنك استخدام الأمرين الآتيين لتشغيل أو إيقاف خادوم MySQL: # /etc/init.d/mysqld stop # /etc/init.d/mysqld start 13. بعض أوامر «التنظيف» هذه بعض أوامر التنظيف (flush) مع شرحٍ لها: flush-hosts: حذف جميع معلومات المُضيف من التخزين المؤقت. flush-tables: «تنظيف» جميع الجداول. flush-threads: تنظيف التخزين المؤقت للخيوط (threads). flush-logs: تنظيف السجلات. flush-privileges: إعادة تحميل جداول الامتيازات (مثل reload). flush-status: مسح متغيرات الحالة (status variables). # mysqladmin -u root -p flush-hosts # mysqladmin -u root -p flush-tables # mysqladmin -u root -p flush-threads # mysqladmin -u root -p flush-logs # mysqladmin -u root -p flush-privileges # mysqladmin -u root -p flush-status 14. كيفية «قتل» عمليات عملاء MySQL المتوقفة؟ يمكنك استخدام الأمر الآتي للتعرف على عمليات عملاء MySQL المتوقفة (sleeping): # mysqladmin -u root -p processlist Enter password: +----+------+-----------+----+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+----+---------+------+-------+------------------+ | 5 | root | localhost | | Sleep | 14 | | | | 8 | root | localhost | | Query | 0 | | show processlist | +----+------+-----------+----+---------+------+-------+------------------+ يمكنك الآن تشغيل الأمر الآتي مع استخدام الخيار kill متبوعًا برقم العملية كما يلي: # mysqladmin -u root -p kill 5 Enter password: +----+------+-----------+----+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+----+---------+------+-------+------------------+ | 12 | root | localhost | | Query | 0 | | show processlist | +----+------+-----------+----+---------+------+-------+------------------+ أما إذا أردت «قتل» (اصطلاح «قتل» [kill] في يونكس يعني إيقاف العملية قسريًا) أكثر من عملية معًا، فافصل بين أرقام العمليات بفاصلة كما في المثال الآتي: # mysqladmin -u root -p kill 5,10 15. كيفية تشغيل أكثر من أمر لأداة mysqladmin معًا؟ إذا أردت تشغيل أكثر من أمر mysqladmin معًا فيمكنك فعل ذلك بذكرها بعضها تلو بعض كالآتي: # mysqladmin -u root -p processlist status version Enter password: +----+------+-----------+----+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+----+---------+------+-------+------------------+ | 8 | root | localhost | | Query | 0 | | show processlist | +----+------+-----------+----+---------+------+-------+------------------+ Uptime: 3801 Threads: 1 Questions: 15 Slow queries: 0 Opens: 15 Flush tables: 1 Open tables: 8 Queries per second avg: 0.003 mysqladmin Ver 8.42 Distrib 5.5.28, for Linux on i686 Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Server version 5.5.28 Protocol version 10 Connection Localhost via UNIX socket UNIX socket /var/lib/mysql/mysql.sock Uptime: 1 hour 3 min 21 sec Threads: 1 Questions: 15 Slow queries: 0 Opens: 15 Flush tables: 1 Open tables: 8 Queries per second avg: 0.003 16. كيفية الاتصال بخادوم MySQL بعيد للاتصال بخادوم MySQL بعيد فاستخدام الخيار ‎-h (أي host، ويعني المضيف) وبعده عنوان IP للخادوم البعيد: # mysqladmin -h 172.16.25.126 -u root -p 17. كيفية تنفيذ أمر على خادوم MySQL بعيد لنقل أنك تريد معرفة حالة (status) خادوم MySQL بعيد، فسيكون الأمر حينئذٍ كالآتي: # mysqladmin -h 172.16.25.126 -u root -p status 18. تشغيل وإيقاف استنساخ MySQL على خادوم ثانوي استخدم الأمرين الآتيين لتشغيل أو إيقاف استنساخ MySQL (أي MySQL replication): # mysqladmin -u root -p start-slave # mysqladmin -u root -p stop-slave 19. كيفية تخزين معلومات التنقيح في MySQL إلى السجلات معلومات التنقيح هي المعلومات التي تخبرنا ما هو استخدام الذاكرة ومعلومات متفرقة عن الاستعلامات، ويمكننا كتابتها إلى ملف سجل MySQL باستخدام الأمر الآتي: # mysqladmin -u root -p debug Enter password: 20. كيفية رؤية الخيارات المتاحة للاستخدام في mysqladmin لمعرفة المزيد من خيارات الأمر mysqladmin وطريقة استخدامه، فاطلع على المساعدة التي تظهر بكتابة الأمر الآتي، والذي سيعرض قائمة بالخيارات المتوافرة: # mysqladmin --help حاولتُ قدر المستطاع أن أُضمِّن أغلبية أوامر mysqladmin مع أمثلةٍ عنها في هذا الدرس، لكن لا مانع من محاولة استكشاف غيرها، وربما تشاركنا بها في التعليقات. ترجمة -وبتصرّف- للمقال ‎20 MySQL (Mysqladmin) Commands for Database Administration in Linux لصاحبه Ravi Saive
  11. تمهيد يمكن أن يكون تحضير قرصٍ جديدٍ للاستخدام في نظام لينكس سهلًا وسريعًا، حيث هنالك الكثير من الأدوات، وصيغ أنظمة الملفات، ومخططات التقسيم التي يمكن أن تُعقِّد العملية إذا كانت لديك احتياجيات خاصة، لكن إن أردتَ أن تُشغِّل جهاز التخزين بسرعة، فالأمر سهلٌ جدًا. سنشرح في هذا الدرس العمليات الآتية: التعرف على قرصٍ جديدٍ في النظام. إنشاء قسمٍ وحيدٍ الذي يمتد على كامل القرص (تتوقع أغلبية أنظمة التشغيل وجود جدول أقسام، حتى لو كان هنالك نظام ملفاتٍ وحيدٍ في القرص). تهيئة القسم بنظام ملفات Ext4 (نظام الملفات الافتراضي في أغلبية توزيعات لينكس). وصل وضبط الوصل التلقائي لنظام الملفات عند الإقلاع. تثبيت الأدوات علينا استخدام الأداة parted لتقسيم القرص، وقد تكون مثبتةً على الخادوم في أغلبية الحالات. إذا كنتَ على خادوم أوبنتو أو دبيان ولم تكن الأداة parted مثبتةً بعد، فيمكنك تثبيتها بكتابة ما يلي في سطر الأوامر: sudo apt-get update sudo apt-get install parted أما إذا كنتَ على خادوم CentOS أو فيدورا، فيمكنك تثبيتها بكتابة: sudo yum install parted التعرف على القرص الجديد في النظام قبل أن نضبط القرص، فيجب أن نتمكن من التعرف عليه بشكلٍ صحيحٍ في الخادوم. إذا كان القرص جديدًا كليًّا، فأسهل طريقة للتعرف عليه في الخادوم هي معرفة إن كان جدول التقسيمات موجودًا. فإذا طلبنا من parted أن يعرض مخطط الأقسام لجميع أقراصنا، فسيعطينا رسالة خطأ لأيّة أقراص لا تملك مخطط أقسام صحيح. يمكننا أن نستعمل هذه المعلومة لمساعدتنا على التعرف على القرص الجديد: sudo parted -l | grep Error يجب أن ترى رسالة الخطأ unrecognized disk label للأقراص الجديدة غير المُقسَّمة: Error: /dev/sda: unrecognised disk label يمكنك أيضًا استخدام الأمر lsblk والبحث عن القرص الذي له المساحة التخزينية الصحيحة وليس له أيّة أقسام تابعة له: lsblk الناتج: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 100G 0 disk vda 253:0 0 20G 0 disk └─vda1 253:1 0 20G 0 part / تحذير: تذكر أنَّ عليك التحقق من ناتج lsblk في كل مرة قبل إجراء التغييرات. فمُعرِّفات الأقراص ‎/dev/sd*‎ و ‎/dev/hd*‎ قد لا تشير إلى نفس القرص بعد إعادة الإقلاع، وهذا يعني أنَّك قد تخاطر بتقسيم أو تهيئة القرص الخاطئ إن لم تتحقق من مُعرِّف القرص قبل ذلك. حاول استخدام مُعرِّفات الأقراص الثابتة مثل ‎/dev/disk/by-uuid أو ‎/dev/disk/by-label أو ‎/dev/disk/by-id. راجع مقالة «مدخل إلى مُصطلحات ومفاهيم التخزين في لينكس» لمزيد من التفاصيل. بعد أن تعلم ما هو الاسم الذي أسندته النواة إلى قرصك، فيمكنك البدء بتقسيمه. تقسيم القرص الجديد كما ذكرنا في التمهيد، سننشِئ قسمًا وحيدًا يمتد على كامل القرص. اختيار أحد معايير التقسيم علينا أولًا تحديد ما هو معيار التقسيم الذي نود استخدامه، إذ أنَّ GPT هو معيار تقسيم حديث، بينما MBR له دعمٌ واسعٌ في أنظمة التشغيل. إن لم تكن عندك متطلباتٌ خاصة، فمن الأفضل أن تختار GPT. نفِّذ الأمر الآتي على القرص الذي تريد تقسيمه لاختيار GPT: sudo parted /dev/sda mklabel gpt أما إذا أردتَ استخدام MBR، فنفِّذ الأمر الآتي بدلًا من الأمر السابق: sudo parted /dev/sda mklabel msdos إنشاء قسم جديد بعد اختيار صيغة جدول الأقسام، فحان الآن الوقت لإنشاء قسم يمتد على كامل القرص بكتابة الأمر الآتي: sudo parted -a opt /dev/sda mkpart primary ext4 0% 100% إذا نفَّذنا الأمر lsblk الآن، فسنشاهد القسم الجديد مذكورًا في القائمة: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 100G 0 disk └─sda1 8:1 0 100G 0 part vda 253:0 0 20G 0 disk └─vda1 253:1 0 20G 0 part / إنشاء نظام ملفات على القسم الجديد أصبح لدينا الآن قسمٌ جديدٌ متاحٌ للاستخدام، لذا علينا الآن تهيئته بنظام ملفات Ext4؛ وذلك بتمرير مسار القسم إلى الأداة mkfs.ext4. يمكننا إضافة لافتة (label) للقسم باستخدام الخيار ‎-L. سيساعدك اختيار اسمٍ واضحٍ على التعرف على القسم بسهولة وسرعة. ملاحظة: من المهم أنَّ تمرِّر اسم القسم وليس كامل القرص. تذكّر أنَّ أسماء الأقراص في لينُكس تشبه sda و sdb و hda …إلخ. أما الأقسام على تلك الأقراص فلها رقمٌ ملحقٌ بآخر اسمها، أي أنَّ عليك استخدام اسمٍ يشبه sda1 وليس sda. sudo mkfs.ext4 -L datapartition /dev/sda1 إذا أردتَ أن تُغيّر لافتة القسم بعد إنشائه، فاستعمل حينها الأمر e2label كما يلي: sudo e2label /dev/sda1 newlabel يمكننا إظهار جميع الطرائق التي يمكنك التعرف فيها على القسم باستخدام lsblk؛ حيث نريد أن نعرض الاسم ,واللُصيقة ومُعرِّف UUID التابعين للقسم. بعض إصدارات lsblk تُظهِر جميع تلك المعلومات إذا كتبنا: sudo lsblk --fs إذا لم تُظهِر النسخة الموجودة عندك كل الحقول اللازمة، فيمكنك طلب إظهارها يدويًا: sudo lsblk -o NAME,FSTYPE,LABEL,UUID,MOUNTPOINT يجب أن يظهر لك ناتجٌ شبيهٌ بالناتج الآتي، وكلُّ سطرٍ فيه يضمُّ الطرائق المختلفة التي يمكنك استعمالها للإشارة إلى نظام الملفات الجديد: NAME FSTYPE LABEL UUID MOUNTPOINT sda └─sda1 ext4 datapartition 4b313333-a7b5-48c1-a957-d77d637e4fda vda └─vda1 ext4 DOROOT 050e1e34-39e6-4072-a03e-ae0bf90ba13a / وصل نظام الملفات الجديد يمكنك الآن وصل نظام الملفات لكي تستعمله. ينصح معيار هيكلة نظام الملفات باستخدام ‎/mnt أو مجلدٍ فرعيٍ داخله لوصل أنظمة الملفات مؤقتًا. إذا كان وصلك للأقراص مؤقتًا فهذا أفضل مكانٍ لوصلها؛ لكن المعيار لم يُقدِّم أيّة اقتراحات لمكان وصل وسائط التخزين الدائمة، لذا يمكنك وصلها أينما تشاء؛ سنصل القسم في هذا الدرس داخل المجلد ‎/mnt/data. أنشِئ المجلد باستخدام الأمر: sudo mkdir -p /mnt/data وصل نظام الملفات مؤقتًا إذا أردتَ وصل نظام الملفات مؤقتًا، فنفِّذ الأمر الآتي: sudo mount -o defaults /dev/sda1 /mnt/data وصل نظام الملفات تلقائيًا عند الإقلاع إذا أردتَ أن تصل نظام الملفات تلقائيًا في كل مرة يُقلِع فيها الخادوم، فعدِّل ملف ‎/etc/fstab بمحرِّرك النصي المفضَّل: sudo nano /etc/fstab نفَّذنا سابقًا الأمر sudo lsblk --fs لعرض ثلاثة مُعرِّفات لنظام الملفات الذي أنشأناه؛ يمكننا استخدام أي منها في ملف fstab؛ وسنستعمل في مثالنا هذا طريقة «اللُصيقة» (label)، لكنك تستطيع أن ترى كيف تبدو الأسطر التي تستعمل الطرائق الأخرى مذكورةً في التعليقات: . . . ## Use one of the identifiers you found to reference the correct partition # /dev/sda1 /mnt/data ext4 defaults 0 2 # UUID=4b313333-a7b5-48c1-a957-d77d637e4fda /mnt/data ext4 defaults 0 2 LABEL=datapartition /mnt/data ext4 defaults 0 2 ملاحظة: يمكنك تعلم المزيد عن مختلف الحقول في ملف ‎/etc/fstab في صفحة الدليل man fstab، لمعلوماتٍ إضافيةٍ عن خيارات الوصل المتوفرة لنظام ملفات معيّن فراجع صفحة الدليل man [filesystem] (أي مثلًا man ext4). لكن الأسطر الموجودة في المثال السابق تكفيك مبدئيًا. يُضاف الخيار discard في بعض الأحيان لأقراص SSD لتفعيل «TRIM» بشكلٍ مستمر، وهنالك جدالٌ قائمٌ عن تأثير ذلك على الأداء؛ وأغلبية التوزيعات تتضمن طريقةً لإجراء TRIM كل فترة كبديلٍ عن تشغيله بشكلٍ مستمر. احفظ الملف الآن بعد أن تنتهي من تعديله. إذا لم تصل نظام الملفات من قبل، فيمكنك وصله الآن بكتابة: sudo mount -a اختبار نظام الملفات الموصول بعد أن وصلنا القسم، فعلينا أن نتأكد من أنَّنا قادرون على الوصول إلى نظام الملفات. يمكننا التحقق إن كان القرص متاحًا بالنظر إلى ناتج الأمر df: df -h -x tmpfs -x devtmpfs Filesystem Size Used Avail Use% Mounted on /dev/vda1 20G 1.3G 18G 7% / /dev/sda1 99G 60M 94G 1% /mnt/data يجب أن تشاهد المجلد lost+found داخل المجلد ‎/mnt/data، والذي يُشير عادةً إلى جذر أنظمة ملفات Ext*‎: ls -l /mnt/data total 16 drwx------ 2 root root 16384 Jun 6 11:10 lost+found يمكننا أيضًا التحقق من أنَّ نظام الملفات موصولٌ مع القدرة على القراءة والكتابة إليه بالكتابة إلى ملفٍ اختباري: echo "success" | sudo tee /mnt/data/test_file اقرأ الملف من القرص للتأكّد من القدرة على قراءة الملفات: cat /mnt/data/test_file success يمكنك حذف الملف بعد التحقق من أنَّ نظام الملفات الجديد يعمل عملًا سليمًا: sudo rm /mnt/data/test_file الخلاصة يجب أن يكون قرصك الآن مُقسَّمًا ومُهيّئًا وموصولًا وجاهزًا للاستخدام؛ وما شرحناه في هذا الدرس يُمثِّل الخطوط الأساسية لكيفية تحويل قرص خام إلى نظام ملفات يمكن للينكس أن يستعمله للتخزين. هنالك طرائق أخرى أكثر تعقيدًا للتقسيم والتهيئة والوصول والتي قد تستفيد منها في بعض الحالة، لكن ما سبق كافٍ كنقطة انطلاق لكيفية إعداد قرص للاستخدام الاعتيادي. ترجمة -وبتصرّف- للمقال How To Partition and Format Storage Devices in Linux لصاحبه Justin Ellingwoo
  12. قاعدة البيانات هي بُنيةٌ هيكليةٌ تحتوي على مجموعة من البيانات المُخزَّنة إلكترونيًا؛ وكان مفهوم قواعد البيانات معروفًا لدى أسلافنا قبل وجود الحواسيب، لكن إنشاء وصيانة تلك القواعد كان أمرًا شاقًا ومملًا. فلنقل أنَّ لدينا قاعدة بيانات فيها 100 صفحة، وأردتَ أن تبحث عن جميع الموظفين الذين يتقاضون أقل من 50 ألف دولار سنويًا، فتخيّل مدى صعوبة الأمر ومقدار الوقت الذي سيستغرقه في ذاك الحين. أما حاليًا، فأنت تصادف قواعد البيانات في كل مكان، إذ تعمل ملايين قواعد البيانات في أنحاء العالم لتخزين والحصول على أي نوع من أنواع البيانات كالبيانات العسكرية وسجلات الموظفين أو حتى مواقع الويب وتقنياتها. تُصنّف قواعد البيانات عمومًا على أنها جزءٌ من «السند الخلفي» (back-end)، وذلك لعدم ظهورها للمستخدم النهائي ولعدم تعامل المستخدم معها مباشرةً. إذ تعمل قواعد البيانات مع لغةٍ برمجيةٍ مثل PHP أو VB أو ASP.NET وتطلب تلك اللغات من قواعد البيانات إجراء عملية ما. تتوافر عدِّة خواديم قواعد بيانات وعملاءٍ لها مثل Oracle و MySQL و MySQLi و MariaDB و MongoDB …إلخ. تتشابه طريقة التعامل مع هذه البيانات، والبنية اللغوية لأوامرها شبه متماثلة، واحتراف التعامل مع إحداها يعني أنَّك ستستطيع التحكم بأريحية مع البقية، وعملية تعلم كتابة الاستعلامات (queries) هي عملية سهلة وممتعة. لنبدأ ببعض الاستعلامات البسيطة على قواعد البيانات؛ وسنستخدم قواعد MySQL التي تأتي مع أغلبية توزيعات لينُكس افتراضيًا، وتستطيع بسهولة تثبيتها من مستودعات توزيعتك إن لم تكن مثبتةً لديك. لكن ربما ينتابك فضولٌ حول معنى «استعلام» (Query)، فبأبسط الكلمات: هي شيفرةٌ بسيطةٌ (أو أمر) تُرسَل إلى قواعد البيانات للحصول على النتيجة المطلوبة. تثبيت قواعد بيانات MySQL يمكنك استخدام مديرَي الحزم yum أو apt لتثبيت قواعد بيانات MySQL: # yum install mysql mysql-client mysql-server (on Yum based Systems) # apt-get install mysql mysql-client mysql-server (on Apt based Systems) تشغيل خادوم MySQL تستطيع تشغيل خدمة MySQL كالآتي: # service mysqld start أو: # service mysql start أذكِّرك أنَّ رمز # في بداية السطر يعني أنَّ عليك تنفيذ الأمر بامتيازات الجذر. سيُطلَب منك أثناء تثبيت قاعدة بيانات MySQL إعداد كلمة مرور لحساب المدير فيها… بعدئذٍ ستتمكن من الوصول إلى مِحَث (prompt، أي المكان الذي تكتب فيه الأوامر) MySQL بتنفيذك للأمر الآتي: # mysql -u root -p ضع اسم المستخدم الذي ضبطته بدلًا من root، وأدخِل كلمة مرورك عند طلبها، فإذا كانت معلومات الدخول صحيحةً، فيمكنك أن تشاهد مِحَث MySQL مباشرةً: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 195 Server version: 5.5.31-0+wheezy1 (Debian) Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. Mysql> تستطيع الآن البدء بتنفيذ الاستعلامات وتعلم إنشاء الاستعلامات. إنشاء قاعدة بيانات سنُنشِئ الآن قاعدة بيانات باسم tecmint كالتّالي: mysql> create database tecmint ; Query OK, 1 row affected (0.02 sec) mysql> ظهر عندنا أنَّ الاستعلام السابق قد نُفِّذَ تنفيذًا سليمًا، وهذا يعني أنَّ قاعدة البيانات قد أُنشِئَت. يمكنك التحقق من وجود قاعدة البيانات الجديدة بتنفيذ الاستعلام الآتي: mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | tecmint | | test | +--------------------+ 9 rows in set (0.00 sec) mysql> لاحظ وجود قاعدة البيانات في مخرجات الاستعلام أعلاه. اختيار قاعدة البيانات علينا قبل إجراء الاستعلامات على إحدى قواعد البيانات أن نختارها، وذلك باستخدام التعليمة use كما يلي: mysql> use tecmint; Database changed mysql> إنشاء الجداول في MySQL لنقل أننا نريد إنشاء جدول باسم minttec في قاعدة البيانات وفيه ثلاثة حقول: mysql> CREATE TABLE minttec ( -> id Int(3), -> first_name Varchar (15), -> email Varchar(20) -> ); Query OK, 0 rows affected (0.08 sec) mysql> لاحظ أنَّ الاستعلام السابق قد أعاد OK مما يعني أنَّ الجدول قد أُنشِئ دون أخطاء. نفِّذ الاستعلام الآتي للتحقق من إنشاء الجدول: mysql> show tables; +-------------------+ | Tables_in_tecmint | +-------------------+ | minttec | +-------------------+ 1 row in set (0.00 sec) mysql> جيد، كل شيء يسير كما ينبغي. يمكننا أن نُطالِع الأعمدة التي أنشأتها في جدول minttec كما يلي: mysql> show columns from minttec; +------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+-------+ | id | int(3) | YES | | NULL | | | first_name | varchar(15) | YES | | NULL | | | email | varchar(20) | YES | | NULL | | +------------+-------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> سأخبرك الآن عن أنواع البيانات الموجودة في الجدول السابق ومعانيها: - int: عدد صحيح. - varchar: سلسلة من المحارف التي لا يتجاوز طولها الرقم المُعرَّف. القيمة الرقمية التي تأتي بعد النوع هي «طول» الحقل الذي ستُخزَّن فيه البيانات. لنقل الآن أننا نريد إضافة عمود جديد باسم last_name بعد العمود first_name سنقوم بذلك على النّحو التّالي: mysql> ALTER TABLE minttec ADD last_name varchar (20) AFTER first_name; Query OK, 0 rows affected (0.16 sec) Records: 0 Duplicates: 0 Warnings: 0 ثم سنتحقق من أعمدة الجدول: mysql> show cسolumns from minttec; +------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+-------+ | id | int(3) | YES | | NULL | | | first_name | varchar(15) | YES | | NULL | | | last_name | varchar(20) | YES | | NULL | | | email | varchar(20) | YES | | NULL | | +------------+-------------+------+-----+---------+-------+ 4 rows in set (0.00 sec) mysql> إضافة أعمدة في MySQL سنضيف الآن عمودًا باسم country بعد العمود email كالتّالي: mysql> ALTER TABLE minttec ADD country varchar (15) AFTER email; Query OK, 0 rows affected (0.16 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> لنتحقق من إضافة العمود: mysql> show columns from minttec; +------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+-------+ | id | int(3) | YES | | NULL | | | first_name | varchar(15) | YES | | NULL | | | last_name | varchar(20) | YES | | NULL | | | email | varchar(20) | YES | | NULL | | | country | varchar(15) | YES | | NULL | | +------------+-------------+------+-----+---------+-------+ 5 rows in set (0.00 sec) mysql> إضافة قيمة إلى الحقول ماذا لو أردنا إضافة قيم إلى حقول الجدول؟ سنقوم بذلك كالتّالي: mysql> INSERT INTO minttec VALUES ('1' , 'Ravi' , 'Saive' , 'raivsaive@xyz.com' , 'India' ); Query OK, 1 row affected (0.02 sec) mysql> ماذا عن إضافة أكثر من قيمة واحدة في آنٍ واحد: mysql> INSERT INTO minttec VALUES ('2' , 'Narad' , 'Shrestha' , 'narad@xyz.com' , 'India' ), ('3' , 'user' , 'singh' , 'user@xyz.com' , 'Aus' ), ('4' , 'tecmint' , '[dot]com' , 'tecmint@gmail.com' , 'India' ); Query OK, 3 rows affected (0.05 sec) Records: 3 Duplicates: 0 Warnings: 0 سنتحقق من إدخال المعلومات السابقة في الجدول: mysql> select * from minttec; +------+------------+-----------+-------------------+---------+ | id | first_name | last_name | email | country | +------+------------+-----------+-------------------+---------+ | 1 | Ravi | Saive | raivsaive@xyz.com | India | | 2 | Narad | Shrestha | narad@xyz.com | India | | 3 | user | singh | user@xyz.com | Aus | | 4 | tecmint | [dot]com | tecmint@gmail.com | India | +------+------------+-----------+-------------------+---------+ 4 rows in set (0.00 sec) mysql> حذف قيم في حقول الجدول لنقل أنَّ المُدخَلة الثالثة في الناتج السابق لم تكن صحيحةً ونريد أن نحذفها: mysql> DELETE FROM minttec WHERE id = 3; Query OK, 1 row affected (0.02 sec) التحقق من تنفيذ الاستعلام السابق: mysql> select * from minttec; +------+------------+-----------+-------------------+---------+ | id | first_name | last_name | email | country | +------+------------+-----------+-------------------+---------+ | 1 | Ravi | Saive | raivsaive@xyz.com | India | | 2 | Narad | Shrestha | narad@xyz.com | India | | 4 | tecmint | [dot]com | tecmint@gmail.com | India | +------+------------+-----------+-------------------+---------+ 3 rows in set (0.00 sec) تحديث قيم في حقول الجدول لنفترض أننا نريد تعديل السجل ذي المُعرِّف 4 (أي id=4): mysql> UPDATE minttec SET id = 3 WHERE first_name = 'tecmint'; Query OK, 1 row affected (0.02 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> لاحظ أنَّ الاستعلام السابق ليس مثاليًا، فستُغيّر الحقل id إلى القيمة 4 لكل سجل يكون اسمه الأول مساويًا للقيمة tecmint. من الجيد استخدام مُطابقة أكثر من عمود واحد في عبارة WHERE لتقليل نسبة حدوث خطأ، كما في الاستعلام الآتي: mysql> UPDATE minttec SET id = 6 WHERE first_name = 'tecmint'AND last_name = '[dot]com'; Query OK, 1 row affected (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> حذف أحد أعمدة الجدول لنفترض أنَّك تحتاج إلى حذف أحد أعمدة الجدول غير الضرورية، ولنقل أنَّه العمود country: mysql> ALTER TABLE minttec drop country; Query OK, 3 rows affected (0.15 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> عرض بُنية الجدول: mysql> select * from minttec; +------+------------+-----------+-------------------+ | id | first_name | last_name | email | +------+------------+-----------+-------------------+ | 1 | Ravi | Saive | raivsaive@xyz.com | | 2 | Narad | Shrestha | narad@xyz.com | | 6 | tecmint | [dot]com | tecmint@gmail.com | +------+------------+-----------+-------------------+ 3 rows in set (0.00 sec) mysql> إعادة تسمية الجداول في MySQL ربما لا تجد اسم minttec ذا معنى، وتريد تحويله مثلًا إلى tecmint_table سنقوم بتغييره كالتّالي: mysql> RENAME TABLE minttec TO tecmint_table; Query OK, 0 rows affected (0.03 sec) mysql> عرض جميع الجداول لرؤية جميع الجداول الموجودة في قاعدة البيانات الحالية: mysql> show tables; +-------------------+ | Tables_in_tecmint | +-------------------+ | tecmint_table | +-------------------+ 1 row in set (0.00 sec) mysql> لاحظ إعادة تسمية الجدول. لنأخذ الآن نسخةً احتياطيةً من قاعدة البيانات السابقة، وذلك عبر تنفيذ استعلامٍ من سطرٍ وحيد دون استخدام أيّة أدواتٍ معقدة. نفِّذ الشيفرة أدناه في سطر الأوامر وليس في مِحَث MySQL: # mysqldump -u root -p tecmint > tecmint.sql check the dumped file on your desktop which would have contents something like -- MySQL dump 10.13 Distrib 5.5.31, for debian-linux-gnu (i686) -- -- Server version 5.5.31-0+wheezy1 -- Dump completed on 2013-09-02 12:55:37 من المستحسن الإبقاء على نسخ احتياطية لقواعد بياناتك، فاستعادة قاعدة بيانات MySQL هو أمرٌ بسيطٌ ويجرى بتنفيذ أمرٍ قصيرٍ في سطر الأوامر (أكرِّر، في سطر الأوامر وليس في مِحَث MySQL). لكن ما رأيك أن نحذف قاعدة البيانات أولًا لنرى كيف ستتم عملية الاستعادة؟ حذف قاعدة بيانات mysql> drop database tecmint; Query OK, 1 row affected (0.02 sec) تحقق من وجود قاعدة بيانات باسم tecmint في خادوم قواعد البيانات عندك: mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | my_database | | mysql | | performance_schema | | phpmyadmin | | sisso | | test | +--------------------+ 7 rows in set (0.00 sec) mysql> رائع، لقد فقدنا قاعدة البيانات :-) لكن لا تقلق، فلقد أخذنا نسخةً احتياطيةً منها منذ قليل. استعادة قاعدة بيانات من نسخةٍ احتياطيةٍ منها نفِّذ الأمر الآتي لاستعادة قاعدة البيانات: # mysql -u root -p tecmint < tecmint.sql Enter password: ERROR 1049 (42000): Unknown database 'tecmint' ماذا حدث؟ لقد واجهنا رسالة خطأ، فنحن لم نُنشِئ قاعدة بيانات باسم tecmint بعد. لذا اذهب إلى مِحَث MySQL وأنشِئها: mysql> create database tecmint; Query OK, 1 row affected (0.00 sec) mysql> حان الآن الوقت لتنفيذ أمر الاستعادة في سطر الأوامر: # mysql -u root -p tecmint < tecmint.sql Enter password: لم تظهر بوجهنا أيّة رسائل خطأ مرعبة، لنتحقق الآن من وجود القاعدة في خادومنا: mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | tecmint | | test | +--------------------+ 8 rows in set (0.00 sec) ثم سنتحقق من محتويات قاعدة البيانات (أي جداولها): mysql> show tables from tecmint; +-------------------+ | Tables_in_tecmint | +-------------------+ | tecmint_table | +-------------------+ 1 row in set (0.00 sec) mysql> وليطمئن قلبنا، سنرى محتويات الجدول: mysql> select * from tecmint_table; +------+------------+-----------+-------------------+ | id | first_name | last_name | email | +------+------------+-----------+-------------------+ | 1 | Ravi | Saive | raivsaive@xyz.com | | 2 | Narad | Shrestha | narad@xyz.com | | 6 | tecmint | [dot]com | tecmint@gmail.com | +------+------------+-----------+-------------------+ 3 rows in set (0.00 sec) هذه ليست نهاية المطاف، ما زال أمامنا مناقشة بعض المفاهيم مثل primary key، و foreign key… ترجمة -وبتصرّف- للمقال MySQL Basic Database Administration Commands – Part I.
  13. أهلًا بك في هذه السلسلة التي تتحدث عن تأثيرات التمرير (Scrolling Effects)، سنستعرض في هذه السلسلة عددًا من تأثيرات التمرير وسنشرح آلية عملها وسنجرِّبها عمليًا. يمكننا الاستفادة من الحدث scroll في JavaScript لإجراء تأثيرات عند تمرير صفحة الويب؛ لكن إن فعلنا ذلك دون إتقان فالنتيجة كارثية، أما إذا أحسنا صنعنا فيمكن لتأثيرات التمرير أن تبهر الزوار وتشعرهم أنَّ موقعك مميز. هذه هي المقالة الأولى في هذه السلسلة، والتي تتضمن التأثيرات الآتية: إخفاء صورة خلفية تدريجيًا عند التمرير توضيح الصورة عند التمرير تدوير العناصر عند التمرير تأثير اختلاف المظهر parallax أما المقالة الثانية والثالثة فهي تتضمن التأثيرات الآتية: إظهار صورة الخلفية عند التمرير باستخدام CSS فقط تمرير سلس للصفحة تطبيق تأثير عدم الوضوح على المحتوى خلف شريط الانتقال إنشاء عنصر قابل للتمرير مع إمكانية وصول مخصصة من لوحة المفاتيح تأثير غروب الشمس باستخدام SVG إظهار فيديو في الخلفية صور متحركة بتأثير parallax باستخدام CSS 3D و JavaScript سأقدِّم لك في بداية كل قسم رابطًا لتجربة المثال تجربةً حيةً على المتصفح. سيسهل عليك كثيرًا أن تفهم الشرح والشيفرات بعد تجربتك للتأثير. إخفاء صورة خلفية تدريجيًا عند التمرير (تجربة حية) إذا كنتَ مِن مَن يستعملون صورًا كخلفية لكامل صفحة الويب، فاستخدام تأثير إخفاء تلك الصورة تدريجيًا عند التمرير هو أمرٌ حسن، حيث يمكّنك ذلك من استخدام أيّة صورة كخلفية دون التأثير على وضوح العناصر أو قابلية قراءة النص. ولعدم قدرة CSS على الاستجابة مباشرةً إلى موضع شريط التمرير، فنحن بحاجةٍ إلى استخدام بعض شيفرات JavaScript لمعرفة موضع التمرير لأحد العناصر. التقنية التي سأشرحها لك هنا سنستخدم فيها أنماط CSS أيضًا لإنشاء تأثير الإخفاء والتي ستُحدَّث ديناميكيًا عبر JavaScript. طريقة التفافية للتعويض عن عدم وجود الخاصية background-opacity للأسف لا يوجد لحد الآن خاصية باسم background-opacity لتحديد شفافية الخلفية؛ لكن من الممكن إنشاء التأثير عبر استخدام ميزة تعدد الخلفيات في CSS: حيث سنضع الصورة كطبقة (layer)، ثم الطبقة الثانية هي تدرجٌ لوني سنستخدم في ألوانه الشفافية alpha. لذا ستبدو شيفرة CSS كالآتي: body { background: linear-gradient(rgba(255, 255, 255, 0), rgba(255, 255, 255, 0)), url(times-square-perspective.jpg); background-repeat: no-repeat; background-attachment: fixed !important; background-size: 100% !important; background-position: center top !important; padding: 1rem; padding-top: 45%; color: #fff; } التدرج اللوني (الذي سيتم وضعه فوق الصورة، لأنَّه عُرِّفَ أولًا) غير ظاهر حاليًا، لأنَّ قيمة الشفافية alpha هي 0 للونين المشكلين للتدرج. استخدمنا الكلمة المفتاحية ‎!important للتأكّد أنَّ شيفرة JavaScript –التي سنُطبِّقها بعد قليل– لن تتمكن من إلغاء قيم خاصيات CSS السابقة. شيفرة HTML تحتوي على ما يلي: <h1>New York Stories</h1> <p>In my younger and more vulnerable years… في النهاية، علينا وضع العنصر h1 في الأعلى: h1 { text-shadow: 0 0 5px rgba(0,0,0,0.5); font-size: 4rem; color: #fff; line-height: 1; position: absolute; top: 10px; } ولكي تصبح الفقرة قابلةً للقراءة، فعلينا أن نحوِّل التدرج اللوني إلى اللون الأبيض تمامًا، مما يؤدي إلى إخفاء صورة الخلفية. تعديل التدرجات اللوني في CSS باستخدام JavaScript أضف شيفرة JavaScript الآتية في أسفل الصفحة: var nystories = document.querySelector("p").offsetTop; window.onscroll = function() { if (window.pageYOffset > 0) { var opac = window.pageYOffset / nystories; document.body.style.background = "linear-gradient(rgba(255, 255, 255, " + opac + "), rgba(255, 255, 255, " + opac + ")), url(times-square-perspective.jpg) no-repeat"; } } في الشيفرة السابقة، قيمةُ المتغير nystories هي موضع أوّل فقرة في الصفحة. عندما يبدأ المستخدم بالتمرير فستُنشِئ الشيفرة السابقة متغيرًا باسم opac الذي سيُقسِّم الموضع «الحالي» للنافذة على الموضع «البدائي» لأول فقرة. ومن ثم ستُجمَع النتيجة مع قيم rgb لألوان التدرج اللوني مكان قيمة الشفافية alpha، مما يعطي التأثير بإخفاء صورة الخلفية عندما يتم تمرير الصفحة. هذا أحد الأمثلة البسيطة عن التمرير، ما زال في جعبتنا المزيد. توضيح الصورة عند التمرير (تجربة حية) أعجبتني اللمسة الجميلة في تطبيق توتير على هواتف iPhone: عندما تمرّر إلى الأسفل في صفحة «Me» فستصبح صورة الترويسة غير واضحة وسيتم تقريبها. أرى أنَّ من المفيد تقليد هذه التقنية في متصفحات الويب، خصوصًا للصور البارزة التابعة للمقالات… شيفرة HTML بسيطة للغاية: <article> <header> <img src="placid-pond.jpg" alt> </header> … </article> وفي نفس الصفحة سنضيف شيفرة SVG: <svg xmlns="http://www.w3.org/2000/svg" width="0" height="0"> <filter id="blur"> <feGaussianBlur stdDeviation="0" /> </filter> </svg> الغرض من وضع شيفرة SVG السابقة هو إضافة تأثير عدم الوضوح (blur) في متصفح Firefox، والذي لا يدعم إلى الآن «مُرشّحات CSS» ‏(CSS Filters)؛ لاحظ أنَّ خاصية العرض والارتفاع لعنصر svg لها القيمة 0، لذا لن يؤثِّر على تخطيط الصفحة. سنضيف تأثير عدم الوضوح عبر أنماط CSS: header { overflow: hidden; font-size: 0; } article header img { width: 100%; height: auto; filter: url(#blur); } شيفرة JavaScript أكثر تعقيدًا مما سبق. يجب في البداية أن نضع جميع الشيفرات داخل دالة التي ستستدعى عندما يتم التمرير في المتصفح: window.onscroll = function (event) { } سنحتاج إلى الكثير من المعلومات داخل هذه الدالة. المتغيرات التي سنستعملها هي: var headerImg = document.querySelector("article header img"), headerImgOffset = headerImg.getBoundingClientRect(), imgTop = headerImgOffset.top, imgBottom = headerImgOffset.bottom, imgHeight = headerImg.offsetHeight, viewportHeight = document.documentElement.clientHeight, blur = document.getElementById("blur"), svgblur = blur.getElementsByTagName("feGaussianBlur")[0], topEffectStart = Math.abs((viewportHeight – imgHeight)/5); اقرأ الأسطر السابقة بتمعّن، يجب أن تبدو لك المتغيرات منطقيةً: المتغير headerImg يشير إلى صورة الترويسة الموجودة في أعلى المقالة (وللتبسيط، سأعتبر أنَّ الصفحة فيها مقالة وحيدة، وعنصر header وحيد). المتغير headerImgOffset يسمح لنا بالوصول إلى مكان وأبعاد الصورة، وفي حالتنا سنستخدم imgTop و imgBottom و imgHeight. المتغير viewportHeight يمثِّل ارتفاع نافذة المتصفح. المتغير blur يشير إلى شيفرة SVG في الصفحة، أما svgBlur فهو العنصر الذي سيسبِّب تأثير عدم الوضوح في متصفح Firefox. المتغير topEffectStart هو الفرق بين ارتفاع «إطار العرض» (viewport) الحالي وارتفاع الصورة، ومقسومًا على 5. وهذا يعني أنَّ تأثير عدم الوضوح سيبدأ فقط إذا كانت صورة الترويسة في الخُمس العلوي من نافذة المتصفح. استخدمتُ الدالة Math.abs لكي أحصل دومًا على عددٍ موجب، لأنَّ من الممكن أن تكون الصورة «أطول» من ارتفاع إطار العرض الحالي. بعد توضيح كل ما سبق، فلنضف عبارةً شرطيةً داخل الدالة: if (imgTop < topEffectStart && imgBottom > 0 ) { blurFactor = Math.abs(imgTop / 100); scaleFactor = 1+Math.abs(imgTop / 1000); headerImg.style.webkitFilter = "blur(" + blurFactor + "px)"; svgblur.setAttribute("stdDeviation", blurFactor); headerImg.style.webkitTransform = "scale(scaleFactor)"; headerImg.style.transform = "scale(scaleFactor)"; } هذا يعني إذا كان أعلى الصورة موجودٌ في أول خُمس من نافذة إطار العرض وما زالت الصورةُ معروضةً وظاهرةً للمستخدم، فافعل ما يلي: أخذ الموقع الحالي لأعلى الصورة نسبةً إلى أعلى إطار العرض، وتقسيم الناتج على 100، وتحويل الناتج إلى عدد عشري موجب، وتسمية الناتج باسم blurFactor. وبطريقةٍ مشابهة، سنأخذ الفرق، ونُقسِّمه على 1000 (لأن تغيير المقياس [scale] حساسٌ أكثر من تأثير عدم الوضوح) ومن ثم سنجمع العدد 1 مع الناتج، ونسمِّه scaleFactor. سنُطبِّق blurFactor (بعد إضافة “px” إليه) على صورة الترويسة، وذلك بوضعه كقيمة لمُرشِّح Webkit Blur. وبطريقةٍ مشابهة، سنُغيّر قيمة stdDeviation لنفس قيمة blurFactor وذلك لتطبيق التأثير في متصفح Firefox. في النهاية، سنسند قيمة scaleFactor إلى خاصية transform في CSS لصورة الترويسة. إحدى ميزات استخدام scale و blur معًا هي القدرة على إخفاء تأثير عدم الوضوح في جوانب الصورة، والتي لا يمكن إخفاؤها حتى باستخدام overflow: hidden في الحالات العادية. يمكن استخدام نفس السكربت السابق مع بعض التعديلات لكي يتم التركيز أو توضيح الصورة عندما تكون في منتصف الصفحة، مما يجذب انتباه المستخدم إليها. تدوير العناصر (المسننات) عند التمرير (تجربة حية) سأريك في هذا المثال كيفية تدوير العناصر أثناء تمرير الصفحة باستخدام JavaScript مباشرةً دون أيّة مكتبات خارجية. ضبط المسننات سيتم وضع المسننين في الصفحة باستخدام قيم id فريدة لكلٍ منهما؛ ولمّا كانا عبارةً عن رسوميات متجهة (vector shapes) فمن المعقول أن نُنشئهما باستخدام SVG: <div id="gearbox"> <img src="gear.svg" alt id="leftgear"> <img src="gear.svg" alt id="rightgear"> </div> هنالك الكثير من الخيارات لطريقة وضع المسننات: ففي أغلبية الأحيان سنستعمل موضعًا ثابتًا لها (أي position: fixed)، ومن الممكن أيضًا وضعها في مكانٍ معيّن ثم سيصبح موقعها ثابتًا عندما يتم التمرير بعدها (أي position: sticky). سأستعمل في هذا المثال flexbox لفصل العناصر، وسأستخدم الواحدات vm لقياسها؛ ويمكن أيضًا أن يكون موضع المسننات static وبالتالي ستختفي المسننات عند تمرير الصفحة. #gearbox { display: flex; justify-content: space-between; } #leftgear, #rightgear { width: 20vw; max-width: 20%; height: auto; } تدوير المسننات تدوير العناصر سهلٌ للغاية، كل ما عليك فعله هو إضافة الشيفرة الآتية في أسفل الصفحة: var leftgear = document.getElementById("leftgear"), rightgear = document.getElementById("rightgear"); window.addEventListener("scroll", function() { leftgear.style.transform = "rotate("+window.pageYOffset+"deg)"; rightgear.style.transform = "rotate(-"+window.pageYOffset+"deg)"; }); سيدور كل مسنن بنفس مقدار تمرير النافذة مقدرًا بالبكسل والذي سيحوّل إلى درجات. لتسريع أو تبطيء دوران المسننات نسبةً إلى مقدار التمرير، فيمكنك جعل window.pageYOffset جزءًا من تعبيرٍ رياضيٍ بسيط (كالقسمة أو الضرب بالرقم 2 على سبيل المثال). تفادي «تعليق» المسننات مشكلة شائعة مع أيّة تقنية التي تتعامل مع التمرير هي «تعليق» العناصر حيث ستحاول مطابقة مدخلات المستخدم. أسهل حل للتعامل مع هذه الإشكالية هو تحريك العناصر عندما يصبح المتصفح جاهزًا للتعامل مع تلك الحركة، وذلك عبر requestAnimationFrame. ولفعل ذلك سنُجعل الدالة addEventListener تستمع إلى حدث خاص (custom event): window.addEventListener("optimizedScroll", function() { … }) وقبل دالة معالجة الحدث، أضف دالةً مجهولةً (anonymous function): ;(function() { var throttle = function(type, name, obj) { var obj = obj || window; var running = false; var func = function() { if (running) { return; } running = true; requestAnimationFrame(function() { obj.dispatchEvent(new CustomEvent(name)); running = false; }); }; obj.addEventListener(type, func); }; throttle ("scroll", "optimizedScroll"); })(); طريقة سهلة لإنشاء تأثير اختلاف المظهر (تجربة حية) نَشَرَ «Adam Mustill» تقنيةً ذكيةً جدًا لإنشاء تأثير اختلاف المظهر (Parallax) عبر تعديل واحدة root em. يتساءل الكثيرون عن كيفية إنشاء تأثيرات اختلاف المظهر، وارتأيتُ أنَّ هذه الطريقة قد تكون نقطة بداية جيدة لتعلم إنشاء هذا التأثير. تأثير اختلاف المظهر (Parallax) يتطلب عادةً عمليات معالجة معقدة لعدد كبير من عناصر DOM المنفصلة، لكن التقنية التي سنستخدمها هنا تُسهِّل علينا معالجة العناصر بتغيير قياسٍ وحيد، وهي تستغل ميزة غريبة بعض الشيء لواحدة القياس em: إذا كان قياس العنصر الأب والعناصر الأبناء بواحدة em، فإن القياس النهائي للأبناء هو ناتج ضربها مع بعضها. وصحيحٌ أنَّ هذا السلوك قد يُسبِّب لنا صداعًا (وهو سببٌ وجيهٌ لاستخدام rem إن استطعنا) إلا أنَّ له ميزتين في هذه الحالة: 1. وحدة القياس em لها دعم أقوى في المتصفحات نسبةً إلى rem. 2. تتطلب em وجود عنصر أب، وهذا يعني أنَّ تأثير اختلاف المظهر يمكن أن يُطبَّق على حاوية معيّنة؛ أما في طريقة rem التي ابتكرها Adam، فإنَّ كل شيءٍ موجود في عنصر <body> سيتأثّر بالتمرير إلا إذا اتخذتَ إجراءاتٍ معينةً للحد من ذلك. ولقد حسّنتُ أيضًا من شيفرة Adam وجعلتها سطرًا وحيدًا من شيفرات JavaScript، بدلًا من عدِّة أسطر من jQuery، مما يُحسِّن من الأداء. شيفرات HTML و CSS شيفرة HTML لهذا المثال بسيطةٌ جدًا: إذ هنالك ثلاث صور وترويسة داخل عنصر <div>: <div id="parallax"> <h1>Simple EM Parallax Technique</h1> <img src="candles.jpg" alt> <img src="cherry-tree.jpg" alt> <img src="pagoda-surrounded-by-trees.jpg" alt> </div> وأنماط CSS ليست معقدةً أبدًا: #parallax { background-image: url(blurred-background-small.jpg); background-size: cover; padding-top: 62.5%; overflow: hidden; position: relative; font-size: .1em; } #parallax * { position: absolute; } #parallax img { width: 40%; height: auto; box-shadow: 0 .2em 8px 4px rgba(0,0,0,0.5); } #parallax h1 { font-size:3rem; color: #fff; z-index: 2; top: 0; text-transform: uppercase; width: 100%; text-align: center; text-shadow: 0 .2em 5px rgba(0,0,0,0.4); } #parallax img:nth-of-type(1) { left: 5%; bottom: 22em; } #parallax img:nth-of-type(2) { left: 28%; z-index: 3; bottom: 8em; } #parallax img:nth-of-type(3) { left: 55%; bottom: 12em; } الأمور المهمة التي يجب ملاحظتها هي القيمة الافتراضية الصغيرة جدًا لقياس الحاوية ‎#parallax بواحدة em، بالإضافة إلى قيم bottom لكل صورة، وأنَّ نص الترويسة مقاسٌ بواحدة rem وليس em. شيفرة JavaScript شيفرة JavaScript هي عبارة عن سطرٍ وحيدٍ فقط يجري تعديلًا على إحدى خاصيات CSS: window.onscroll = function() { if (window.pageYOffset > 0) { document.getElementById("parallax").style.fontSize = (window.pageYOffset/20)*.1+"em"; } } بشرح مبسّط: سيؤدي التمرير إلى تغيير قيمة الخاصية font-size لحاوية ‎#parallax، وهذا التغيير يعتمد على عدد البكسلات التي تم تمريرها، مقسومةً على 20، مضروبةً بقيمة ‎0.1 em‎ والتي هي حجم الخط الأصلي. التمرير إلى الأسفل سيؤدي إلى زيادة قيمة الخاصية bottom لكل صورة مما يدفعها نحو الأعلى؛ لكن الترويسة لن تتأثر لأنها مُقاسة بواحدة rem، وهي ذات خاصية z-index مناسبة مما يسمح للصور بالمرور أمامها وخلفها. الخلاصة استعرضنا التأثيرات السابقة بسرعة، بقي عليك أن تتمعّن بشيفراتها، وتحاول إيجاد استخدامات أخرى للتقنيات التي رأيتها. ترجمة وبتصرّف للمقالات: Fade A Responsive Background Image On Scroll Scroll-to-Focus Effect For Hero Images Rotate Elements on Scroll with JavaScript Easy Parallax Effects With Em لصاحبها Dudley Storey
  14. لشبكات ووردبريس متعددة المواقع الكثير من الاستعمالات، حيث يمكنك استخدمها لإنشاء شبكة مثل Edublogs التي تُساعِد الآخرين على إنشاء موقعٍ خاصٍ بهم، أو يمكنك استخدمها لشبكةٍ من المواقع أو المدونات التابعة لمنظمتك، ويمكنك أيضًا استخدامها لاستضافة مواقع لك أو لعملائك. إذا كنتَ كالغالبية من مطوري ومصممي الويب، فمكن المرجح أنَّك تملك عددًا كبيرًا من النطاقات التي سجّلتها والمواقع التي أنشأتها (أو التي ما زلتَ تعمل عليها)، ولا شكّ أنَّ ذلك قد يسبب لك الصداع. وبشكلٍ مشابه، إذا كنتَ تدير شركة أو كنتَ عاملًا حرًا توفِّر استضافةً لمواقع عملائك، فستحتاج إلى إبقاء عدِّة نسخ من ووردبريس محدثةً باستمرار، وهذا سيستهلك وقتًا منك. تستطيع ميزة الشبكات متعددة المواقع أن تحل هذه المشكلة لك. هذا هو الدرس السادس في سلسلتنا المكونة من عشرة دروس التي تشرح التعامل مع الشبكات متعددة المواقع في ووردبريس، ستتعلم في هذه السلسلة كل ما تحتاج له لكي تُنشِئ شبكتك، وتضيف المواقع إليها أو تسمح للمستخدمين بذلك، بالإضافة إلى إدارة الشبكة. وستتعلم كيف تتأكد أنَّ شبكتك آمنة وأداؤها عالٍ، وكيف يمكنك أن تُنشِئ مجتمعًا ناجحًا من المستخدمين والمواقع. ستتعلم في هذا الجزء من السلسلة كيف تستعمل الشبكات متعددة المواقع لاستضافة مواقع لك أو لعملائك، التي ستبدو وكأنها مواقع منفصلة. حيث سيمتلك كلٌ منها نطاقًا خاصًا به، وسيشعر الزوار أنَّ تلك المواقع منفصلة، سأريك أيضًا كيفية استخدام ميزة تعدد المواقع لتحسين سير عملك وسأعطيك بعض النصائح حول كيفية تتفادى المشاكل المحتملة، ثم سأشرح لك (في الدرس القادم) عملية ربط النطاقات بالتفصيل لكي تتمكن من ضبط الشبكة متعددة المواقع الخاصة بك ضبطًا سليمًا. استخدام الشبكة متعددة المواقع لاستضافة مواقعك أو مواقع عملائك أتوقع أنَّك تشعر كم أنني معجبٌ بميزة تعدد المواقع وأنني أستعملها لمختلف التطبيقات. أحد تلك التطبيقات هو استضافة مواقع العملاء. أدير شركةً صغيرة لتطوير الويب، وتكون أغلبية مواقع عملائي متشابهة وليست كبيرة جدًا والتي يمكن استضافتها بسهولة على شبكة من المواقع؛ بغض النظر أنَّ بعض عملائي لديهم استضافة خاصة أو يحتاجون إلى تثبيت ووردبريس مستقل بسبب بعض الخصوصيات في مواقعهم. أنا أفعل ذلك لمواقع العملاء، لكن لا يوجد سببٌ يمنعك من استخدام شبكة لاستضافة مواقعك الخاصة على أكثر من نطاق. التقنيات التي سنستعملها متماثلة. لننظر أولًا على إيجابيات وسلبيات ما سبق. إيجابيات استخدام شبكة متعددة المواقع لمواقع العملاء هنالك بعض المنافع الأساسية لاستضافة أغلبية مواقع العملاء في تثبيت ووردبريس وحيد: توفير مساحة على الخادوم. توفير الوقت اللازم لتثبيت ووردبريس في كل مرة أبدأ فيها العمل على موقع جديد. توفير الوقت اللازم لتحديث أكثر من نسخة ووردبريس. توفير الوقت اللازم لتحديث الإضافات والقوالب في عدِّة نسخ من ووردبريس. هذا يعني أنني أستطيع استخدام نفس الإضافات على أكثر من موقع دون الحاجة إلى تثبيتها مرارًا وتكرارًا. هذا يعني أنَّني أستطيع تثبيت إضافات مثل Support System للتواصل مع العملاء في مكانٍ واحد. بالنسبة لي، هذا يجعل الأمور أكثر فعالية، لكن علي أنَّ أعمل بطريقة تلائم المواقع التي تعمل على شبكة، وإجراء بعض الأمور للتأكد من عدم وقوعي ببعض المشاكل. سلبيات استضافة الكثير من المواقع في تثبيت ووردبريس وحيد من المحتمل أنَّ يقرأ هذا الكلام أشخاصٌ يجزعون من إبقاء كل هذه المواقع الثمينة في مكانٍ واحد. أعلم أنَّ هنالك البعض الذين يظنون أنَّ مخاطر فعل ذلك تفوق فوائده. إن كنتَ من هؤلاء، فيمكنك أن تستمر باستخدام تثبيت ووردبريس منفصل لكل موقع. هنالك بالفعل بعض السلبيات الناجمة عن استخدام شبكة لاستضافة جميع مواقعك: حجم قاعدة البيانات: قد تبدأ قاعدة البيانات بالتضخم بعد فترة من الزمن، لكن إذا تمكنت مواقع WordPress.com و Edublogs من استخدام شبكة متعددة المواقع لاستضافة ملايين المواقع، فلا يوجد سببٌ يمنعك من التعلم من تجربتهم لتوسعة تثبيت ووردبريس عندك. الحماية: إذا تم اختراق الشبكة متعددة المواقع، فستتأثر جميع المواقع المُستضافة عليها. هذا أمرٌ مرعبٌ، أليس كذلك؟ بلى! لكن من خبرتي عندما كنتُ ضحيةً للاختراق، كان ذلك على مستوى الخادوم، وأثّرَ ذلك على جميع المواقع المستضافة على أيّة حال. لكن عليك أنَّ تتأكد أنَّ مستوى الحماية والأمان في شبكتك عالٍ، خصوصًا إن كنتَ تستضيف عددًا كبيرًا من المستخدمين. إذا تعطّل شيءٌ ما، فسيُعطِّل كل الشبكة. هذه هو السبب لماذا لا يجدر بك إجراء تحديث على شبكتك الإنتاجية إلّا بعد أن تجرّبه على موقعٍ تجريبي أولًا. سننظر في هذه النقطة قريبًا. الأداء: لن تستطيع استضافة العديد من المواقع في تثبيت ووردبريس وحيد إن كنت تعمل على استضافة رخيصة وبطيئة أو محدودة بحجم قاعدة البيانات أو التراسل الشبكي أو رفع الملفات. إذا قررتَ أنت أو أحد عملائك أن تنقل الموقع إلى خارج الشبكة في المستقبل، فذلك أصعب من عملية نقل قاعدة بيانات موقع مفرد إلى خادوم جديد أو شركة استضافة أخرى. لكن ذلك ليس مستحيلًا، وهنالك طريقتان لفعل ذلك: يمكنك استخدام إضافات (طريقة أسهل لكنها قد تكون غير عملية) أو يمكنك تصدير الجداول اللازمة من قاعدة البيانات (وهذه الطريقة أصعب لكن أسرع وعملية ومرنة أكثر). هذا يعني أنَّ استخدام شبكة لاستضافة أكثر من موقع ستعمل بأفضل ما يمكن إذا تحقق الشرطان الآتيان: أخذت احتياطاتك وتأكدتَ أنَّ الشبكة آمنة ولن تتعطل بسهولة. تعمل بطريقة معينة تجعل نفس الشيفرة تتكرر في جميع أو أغلبية المواقع التي تطورها (مثلًا الإضافات والقوالب). تذكَّر أنَّ لأغلبنا قائمةٌ فيها الإضافات الأساسية التي نُثبِّتُها على كل موقع جديد نطوره. لننظر إلى معنى ما سبق عمليًا. تفادي السلبيات: الاحتياطات الوقائية هنالك بعض الاحتياطات الوقائية التي عليك اتخاذها لتتفادى المشاكل التي ذكرتا سابقًا: خذ نسخة احتياطيةً لشبكتك بشكلٍ دوري: كل يوم على الأقل، وأكثر من ذلك إن كانت مواقعك تُحدَّث يوميًا. استخدامُ إضافة Snapshot Pro لأخذ نسخة احتياطية للمواقع على شبكتي، وأستعمل Updraft Plus للتأكد من أخذ نسخة احتياطية من كامل قاعدة البيانات، وهذا يعني أنَّ لو تعطَّل موقعٌ واحد، فسأستخدم ميزة الاستعادة في إضافة Snapshot لاستعادته، وإذا حدثت مشاكل مع كل الشبكة، فسيكون عندي نسخةٌ احتياطيةٌ من قاعدة البيانات وسأعيد تثبيتها يدويًا. ابقِ شبكتك آمنةً قدر الإمكان. راجع سلسلة «تنصيب ووردبريس بأمان» وطبِّق النصائح الموجودة فيها. المخاطر الموجودة في شبكة المواقع زيادةً عن المواقع المفردة هي أنَّك تملك عددًا أكبر من المواقع ومستخدمين أكثر. يمكنك أن تُطبِّق الاحترازات الأمنية أثناء تسجيل الموقع وعملية تسجيل المستخدم لكي تتأكد أنَّ الآخرين لن يستطيعوا استعمال أسماء معيّنة لمواقعهم، ولحجب القدرة على تسجيل المواقع من نطاقات معينة، ولإبعاد المستخدمين المزعجين وعدم السماح للمستخدمين بضبط كلمات مرور ضعيفة. إن لم تسمح بتسجيل المواقع والمستخدمين من قِبل الزوار، فتأكّد أنَّ العملية التي ستتبعها في إنشاء المواقع آمنة. لا تُحدِّث ووردبريس أو الإضافات أو القوالب على شبكتك الإنتاجية قبل تجربة التحديث على نفس الإصدار في نسخة تجريبية من الشبكة أولًا. النسخة التجريبية هي نسخة من شبكتك التي يكون الغرض منها هو اختبار التحديثات أو ما شابه ذلك (وهي مختلفة عن النسخة «التطويرية» التي تتواجد عادةً في حاسوبك المحلي). من المستحسن أن تستضيف النسخة التجريبية على نفس الخادوم الذي يُشغِّل شبكتك الإنتاجية لذا ستتمكن من التجربة في نفس الشروط تقريبًا. احرص على حجب وصول محركات البحث وحاول إبقاء قاعدة البيانات مُحدَّثةً قدر الإمكان باستخدام إضافة للنسخ الاحتياطي أو أداة مثل Vagrant. استضف شبكتك عند مزود استضافة مختص بإدارة مواقع ووردبريس إن استطعتَ تحمل التكاليف. حيث سيعتنون بعملية النسخ الاحتياطي والحماية ويتمكنون من استعادة الشبكة ويوفرون لك بيئة تجريبية أيضًا. تحدَّث مع مزود الخدمة عن أفضل إعداد للاستضافة يلائم حالتك، مثل خادوم VPS (اختصار للعبارة virtual private server) الذي يناسب تثبيت الشبكات متعددة المواقع. استخدم إضافة أو أكثر من الإضافات التي ننصح بها لإدارة الشبكة لتسهيل عملية الإدارة. إحدى الإضافات التي أرى أنَّها مفيدةً كثيرًا هي Multisite Enhancements، لأنها تُساعدني بموضوع التحديثات عبر إظهار ما هي المواقع التي تستعمل قوالب أو إضافات معيّنة. وهذا يعني أنَّني سأعرف ما هي المواقع التي عليّ اختبارها. استخدم الشيفرات من مصادر تثق بها فقط، أو اكتب الشيفرات الخاصة بك، هذا الأمر مهمٌ لجميع أنواع مواقع ووردبريس، لكنه مهم جدًا في الشبكات متعددة المواقع، لأنه إذا كان لديك عدِّة مواقع تُشغِّل عدِّة قوالب وإضافات، فعليك أن تتأكَّد أنَّ كل إضافاتك وقوالبك تعمل عملًا صحيحًا مع بعضها بعضًا. إذا كنتَ تستعمل شيفراتٍ من طرف ثالث، فأنا أنصحك بأن تستقي تلك الشيفرات من موقع WPMU DEV، إذ أنَّ القوالب والإضافات من ذاك الموقع تعمل بتناغم مع بعضها وهي مُحسّنة خصيصًا لشبكات المواقع. أحاول اتباع النصائح السابقة ولم أواجه مشاكل مع الشبكات متعددة المواقع حتى الآن. الشبكات متعددة المواقع، وأسلوب عملك لكن استخدام الشبكات متعددة المواقع لاستضافة مواقع العملاء لا يعني تفادي المشكلات التي ذكرناها سابقًا فحسب، لكنه متعلقٌ أيضًا بأسلوب وسير العمل. هنالك جوانب متعلقة بأسلوب عملك التي ستجعل التطوير لشبكة متعددة المواقع أسهل وأيسر. وهذا يعني اتباع أسلوب عمل يجعل استخدام الشبكات أمرًا يزيد الكفاءة والفعالية، ويجعل من استخدام الشبكات طريقًا أفضل للتطوير بدلًا من استخدام عدد كبير من مواقع ووردبريس المفردة المستقلة. لننظر إلى بعض هذه الجوانب: ستعمل مع نفس القوالب لجميع مواقع شبكتك، أو «قالب ابن» (child theme) لنفس القالب الأب الأساسي. قد يتحقق هذا الشرط إذا استخدمتَ نظامًا لبناء القوالب مثل Upfront أو أحد إطارات عمل ووردبريس الموجودة. شخصيًا، لدي إطار عمل للقوالب خاصٌ بي الذي طوَّرتُه لأستخدمه في مواقع العملاء، ومن ثم أُنشِئ قالبًا ابنًا لكل مشروع جديد. يملك هذا القالب الكثير من الدوال (functions) والخطافات (hooks) التي أستفيد منها لجعل كل موقع مميز وفريد ولكي أضيف شيفراتٍ خاصة. وأستخدم أيضًا شيفرات CSS مكتوبة بطريقة تجعلني أستطيع تعديل مظهر الموقع الجديد بأقل قدر من العناء. يمكنك تثبيت مجموعة الإضافات نفسها لكل موقع تُنشِئه. كانت لدي قائمة بالإضافات الأساسية التي أثبِّتها على كل موقع قبل أن أستعمل الشبكات متعددة المواقع لاستضافة مواقع العملاء؛ وهذه القائمة تتضمن إضافات لأخذ نسخ احتياطية، ولتحسين SEO، ولتحسين الأداء والحماية. أما الآن، فبدلًا من الحاجة إلى تثبيت تلك الإضافات على كل موقع جديد، فأثبتها وأفعِّلها على الشبكة فحسب. تستطيع تحسين خدمة الزبائن باستخدام إضافات للدعم أو التدريب. استخدام إضافة مثل Support System تسمح لعملائك بطرح مشكلاتهم لكي تستطيع الإجابة عنها ثم تحول ذلك إلى «أسئلة شائعة» (FAQ) لعرضها في موقعك الرئيسي إن شئت. أستخدم هذا على إحدى شبكاتي لكي أُبقي على جميع نقاشات الدعم مع العملاء في مكانٍ واحد. إذا أردت أن توفِّر درسًا تعليميًا لعملائك وتُظهِر لهم كيف يستعملوا موقعهم، فيمكنك تثبيت إضافة مثل Integrated Video Tutorials التي تسمح لك بتقديم شرح مصور للعملاء؛ كل ما عليك فعله هو نشر الدرس التعليمي على شبكتك وسيصبح متاحًا لجميع العملاء. إذا أردتَ أن تُنشِئ مجتمعًا بين عملائك، فإن الشبكة متعددة المواقع هي منصةٌ رائعةٌ لإنشاء مجتمع، ولا يوجد سببٌ يمنعك من فعل ذلك مع عملائك. سنتحدث بالتفصيل عن هذا الموضوع في الجزء القادم من هذه السلسلة. حسنًا، يمكنك الآن أن تعي ماذا يعني استخدام شبكة متعددة المواقع لاستضافة عدِّة مواقع لعملائك (أو مواقع خاصة بك) على نطاقات مختلفة، ما ستحتاج له الآن هو معرفة كيف ستفعل ذلك، وهذا ما سنناقشه في الدرس القادم. ترجمة –وبتصرّف– للمقال WordPress Multisite Masterclass: Client Sites and Domain Mapping لصاحبته Rachel McCollin
  15. إحدى أفضل ميزات الشبكات متعددة المواقع في ووردبريس تكمن بإمكانية سماحك للمستخدمين بإنشاء مواقع خاصة بهم، سواءً مجانًا أو لقاء أجر. السماح للمستخدمين بالتسجيل في شبكتك وإنشاء موقع خاص بهم هو أمرٌ بسيطٌ جدًا، كل ما عليك فعله هو تفعيل هذا الخيار في إعدادات الشبكة، لكن يمكنك إجراء تحسينات على هذه العملية وجعل تجربة المستخدم أفضل. هذا هو الدرس الخامس من سلسلة الشبكات متعددة المواقع في ووردبريس. ستتعلم في هذه السلسلة كل ما تحتاج له لكي تُنشِئ شبكتك، وتضيف المواقع إليها أو تسمح للمستخدمين بذلك، بالإضافة إلى إدارة الشبكة. وستتعلم كيف تتأكد أنَّ شبكتك آمنة وأداؤها عالٍ، وكيف يمكنك أن تُنشِئ مجتمعًا ناجحًا من المستخدمين والمواقع. ستتعلم في هذا الدرس كيفية ضبط عملية التسجيل في الموقع، ثم سنتحدث عن كيف سيتمكن المستخدمون من إنشاء مواقع خاصة بهم، وسنستكشف كيف نتمكن من جعل تلك العملية أبسط، وكيفية تخصيص رسائل التسجيل؛ ثم سننظر حول كيفية جعل عملية إنشاء موقع أسهل عبر استخدام إحدى الإضافات. قبل أن نبدأ في هذا الدرس، أنصحك أن تراجع الدروس السابقة في السلسلة، التي ستوفر لك خلفيةً صلبةً عن ميزة تعدد المواقع في ووردبريس وكيفية ضبطها، وإنشاء المواقع والمستخدمين على الشبكة، وتثبيت القوالب والإضافات، وكيفية ضبط إعدادات الشبكة. عندما تنتهي من الاطلاع على ما سبق، فسنبدأ درسنا بإجراء الخطوة الأساسية الأولى: تفعيل تسجيل المواقع. تفعيل تسجيل المواقع تسجيل المواقع هو ميزة من ميزات تعدد المواقع التي تُشكِّل جزءًا من ووردبريس، لذا كل ما عليك عمله هو تفعيلها؛ وذلك عبر صفحة إعدادات الشبكة في لوحة التحكم. اذهب إلى صفحة «Settings > Network Settings» (الإعدادات > إعدادات الشبكة) في لوحة تحكم مدير الشبكة، لكي ترى ما يلي: القسم الثاني الموجود في الصفحة السابقة هو قسم «Registration Settings» (إعدادات التسجيل). يكون تسجيل المستخدمين والمواقع معطلًا افتراضيًا، وعليك تغيير ذلك. انتقِ إحدى الخيارات الأخرى التي تناسب احتياجاتك. هذه هي الخيارات المتاحة أمامك، وما الذي تفعله: التسجيل معطّل: يمكن لمدراء الشبكات أو المواقع فقط إنشاء المستخدمين الجدد، ويمكن لمدراء الشبكة فقط إنشاء مواقع جديدة (أي أنَّ تسجيل المواقع من قِبل المستخدمين مُعطَّلٌ). السماح بتسجيل عضويات: يمكن للآخرين إنشاء حساب مستخدم على شبكتك لكنهم لن يستطيعوا إنشاء موقع جديد (وهذا شبيهٌ بتسجيل المستخدمين في مواقع ووردبريس المفردة). السماح للأعضاء المتصلين بتسجيل مواقع جديدة: يمكن للأشخاص الذين يستطيعون تسجيل الدخول أن يُنشِئوا المواقع. استخدم هذا الخيار إن لم تكن تريد أن يُنشِئ الآخرون حسابات مستخدمين ومواقع خاصة بهم، لكنك تريد أن يكون تسجيل المواقع مقتصرًا على المستخدمين الذين أعددتهم بنفسك. هذا الخيار مفيدٌ للأنظمة المغلقة مثل شبكة من المواقع للمجتمع أو لشركةٍ ما. السماح بتسجيل مواقع وعضويات: يمكن للآخرين إنشاء مواقع وحسابات مستخدمين في نفس الوقت (أو يمكنهم إنشاء موقع باستخدام عضوية موجودة مسبقًا). في هذه المرحلة من سلسلتنا التعليمية، سنسمح للمستخدمين بإنشاء حسابات المستخدمين ومواقع خاصة بهم، لذا سنختار الخيار الرابع: «السماح بتسجيل مواقع وعضويات» (Both sites and user accounts can be registered). بعد أن تفعل ذلك، فلننظر إلى إعدادات الضبط التي تلي ما سبق: إشعار التسجيل: أبقِ هذا الحقل مُفعَّلًا لكي تحصل على تنبيه في كل مرة يحاول فيها شخصٌ ما إنشاء حساب مستخدم أو موقعًا جديدًا. إذا كانت شبكتك حديثةً، فأنصحك بتفعيل هذا الخيار لكي تستطيع أن تكتشف الأشخاص المزعجين؛ وعندما تنمو شبكتك فسيصبح من غير الملائم أن تستقبل رسائل بريدية طوال الوقت، وفي هذه الحالة ستحتاج إلى إضافة لمكافحة المستخدمين المزعجين، وسننظر في هذا الأمر بالتفصيل في آخر جزء من سلسلتنا، الذي سيكون عن إدارة الشبكة. إضافة مستخدمين جدد: إذا كانت شبكتك عامة، أو كنت تريد أن تسمح لمدراء المواقع بإضافة مستخدميهم، فيجب عليك تفعيل هذا الحقل؛ لكن إن كنت تريد تحكمًا أكبر بعملية إنشاء حسابات المستخدمين، فاترك هذا الحقل معطلًا. أحب عادةً أن أعطي مدراء المواقع عندي إمكانية تسجيل مستخدمين جدد لمواقعهم، لذا أنصحك بتفعيل هذا الحقل. الأسماء الممنوعة: تُضيف ووردبريس قائمةً بأسماء المدونات الممنوعة افتراضيًا، لكنك تستطيع الإضافة عليها. هذه هي الأسماء التي ستكون اختصاراتٍ للمواقع الجديدة. إذا أردتَ أن تُضيف المزيد منها، فاكتبها في الحقل وافصل بينهما بفراغ. ربما تود تضمين اسم علامتك التجارية، أو أيّة أسماء لصفحاتٍ أنشأتها في موقعك. نطاقات البريد الإلكتروني المسموحة: إذا كانت شبكتك تابعةً لمنظمةٍ يتشارك الأعضاء فيها بنطاق بريدهم الإلكتروني، فيمكنك أن تستعمل هذا الحقل لكي تمنع أي شخصٍ لا يملك عنوانًا بريديًا مسموحًا من إنشاء موقع. اكتب اسم النطاق دون رمز @، فلو كان اسم النطاق الخاص بك هو microsoft.com (على سبيل المثال)، فكتابة microsoft.com في ذاك الحقل تؤدي إلى تحديد عملية تسجيل المواقع للأشخاص الذين يملكون عنوانًا بريديًا من الشكل name@microsoft.com. نطاقات البريد الإلكتروني الممنوعة: استخدم هذا الحقل لذكر نطاقات البريد الإلكتروني التي لا تريد أن يتمكن مستخدموها من التسجيل في الموقع. وهذا يعني لو أنَّك أضفتَ microsoft.com هنا، فلن يتمكن أي شخصٍ يملك عنوانًا بريديًا من الشكل name@microsoft.com من إضافة موقع أو تسجيل حساب مستخدم. هذا مفيدٌ إذا واجهت محاولات تسجيل مزعجة من حسابات تستعمل نفس نطاق البريد الإلكتروني. بعد أن تضبط الإعدادات اللازمة لتفعيل تسجيل المواقع وإضافة أيّة أسماء أو نطاقات محظورة… فمرِّر إلى أسفل الصفحة واضغط على رز «Save Changes» (حفظ التغييرات). بقية الصفحة السابقة تتعلق بكيفية تخصيص عملية التسجيل، والتي سأشرحها بعد أن ننظر إلى طريقة إنشاء المستخدمين لمواقعَ خاصةٍ بهم. تسجيل موقع وحساب مستخدم بعد أن تُفعِّل تسجيل المواقع، سيتمكن المستخدمون من فعل ذلك بزيارة صفحة wp-signup.php في موقعك. فلو كان رابط موقعك هو http://mynetwork.com، فعليهم زيارة الصفحة http://mynetwork.com/wp-signup.php. حسنًا، لا أتوقع أن يعلم المستخدمون أنَّ بإمكانهم التسجيل دون أن نخبرهم بذلك! لذا ما عليك فعله الآن هو وضع نوع من أنوع الروابط لصفحة التسجيل. يمكنك فعل ذلك بإحدى الطرق الآتية: إضافة رابط إلى قامة التنقل الرئيسية إضافة زر يدعو المستخدمين إلى التسجيل إضافة رابط في التذييل أو الشريط الجانبي إضافة عدد من الروابط في الصفحة الرئيسية (أو أيّة صفحات أخرى مناسبة) استخدام ودجت للتسجيل (سنأتي عليها لاحقًا). اعتمادًا على حاجاتك وطبيعة مستخدمين، فربما يكون من المناسب استخدام أكثر من تقنية من التقنيات السابقة. لكن لتبسيط الأمر، سنبدأ بإضافة رابط إلى قائمة التنقل. إضافة رابط لصفحة التسجيل في قائمة التنقل يمكنك فعل هذا في صفحة «Menus» (قوائم) في لوحة تحكم المواقع أو عبر صفحة «التخصيص» في الموقع الرئيسي في شبكتك. لنستخدم صفحة التخصيص. اختر موقعك الرئيسي من قائمة «My Sites» (مواقعي) ثم اذهب إلى «Appearance > Customize» (مظهر > تخصيص) لفتح صفحة التخصيص: اختر لسان «Menus» (قوائم) من على الجانب الأيسر (على الجانب الأيمن في الواجهة العربية)، ثم اختر قائمة الرئيسية، أو إذا لم يملك موقعك قائمةً بعد، فأنشِئ واحدةً بالضغط على زر «Add a menu» (أضف قائمة). تأكد أنَّ قائمتك موجودةٌ في المكان الأساسي (Primary location) في قالبك (أو أيًا كان المصطلح المستخدم في القالب للدلالة على القائمة الرئيسية): بعد أن تفعل ذلك، فستتمكن من إضافة عناصر بالضغط على زر «Add items» (أضف عناصر)؛ ثم اختر «Custom Links» (روابط مخصصة)، ثم في حقل رابط URL اكتب http://mynetwork.com/wp-signup.php حيث mynetwork.com هو اسم نطاق موقعك؛ واكتب النص الذي سيظهر في القائمة في حقل «Link Text» (نص الرابط). يمكنك أن ترى ذلك في الصورة الآتية: اضغط على زر «Add to Menu» (أضف للقائمة) ثم اضغط على زر «Save & Publish» (حفظ ونشر) في الزاوية العليا اليسرى (الزاوية العليا اليمنى في الواجهة العربية). هذا سيحفظ القائمة التي فيها رابط لصفحة التسجيل: تسجيل موقع الآن، وبعد أن أعطيت مستخدميك رابطًا لتسجيل موقعهم، فكل ما سيحتاجون له هو الضغط على الرابط لرؤية صفحة التسجيل: ولمّا كنتَ مديرًا للشبكة، فسترى رسالةً في الأعلى، التي لن يراها بقية المستخدمين. وسترى إشعارًا من بقية المواقع التي تكون عضوًا فيها، وبعض المعلومات الأخرى. لنسجل خروجنا ونحاول إنشاء موقع جديد وحساب مستخدم جديد. سجل الخروج من حسابك كمدير للشبكة ثم حدِّث الصفحة (أو استخدم الرابط الموجود في قائمة التنقل لفتحها): يمكنك أن ترى حقلين يجب تعبئتهما للبدء: اسم المستخدم عنوان البريد الإلكتروني يجب أن يكون كلاهما فريدًا، فلو حاول أحدٌ التسجيل باسم مستخدم أو بريد إلكتروني مُسجَّل مسبقًا على الشبكة، فسيحتاج ذلك الشخص إلى تسجيل الدخول ومن ثم إنشاء موقع جديد (أي لا يمكن إنشاء حسابين بنفس الاسم أو البريد الإلكتروني). ملاحظة: بعد أن يملأ المستخدم هذين الحقلين، فعليه الاختيار بين تسجيل موقع أو تسجيل حساب مستخدم. إذا اختار تسجيل موقع، فسيُنشَأ حساب مستخدم جديد تلقائيًا، ولا حاجة لإنشائه يدويًا. إذا أبقى المستخدم على الخيار الافتراضي «Gimme a site!‎» (أريد موقعًا!) ثم ضغط على زر «Next» (التالي)، فسينتقل إلى صفحةٍ تسأله عن معلوماتٍ عن موقعه: سيحتاج هنا إلى توفير رابط مختصر (slug) لموقعه، الذي سيُملَأ تلقائيًا باسم المستخدم الذي اختاره، وسيُطلَب منه أيضًا توفير عنوان للموقع؛ ويجب أن يُحدِّد إن كان يريد أن تُفهرِس محركات البحث هذا الموقع. سأغيّر رابط الموقع وعنوانه، وسأعطِّل فهرسة الموقع الجديد، وذلك لأني لستُ مستعدًا لعرضه على الزوار بعد. لا تنسَ أنَّ مدراء المواقع يستطيعون تغيير هذا الضبط في إعدادات الموقع بعد إنشائه، وذلك بالذهاب إلى «Settings > Reading» (الإعدادات > قراءة). في النهاية، اضغط على زر «Signup» (تسجيل) لإنشاء الموقع. ملاحظة: إن بدا لك عدم تغيّر أي شيء في بادئ الأمر، فاصبر؛ فإذا ضغطتَ مرتين على زر التسجيل فستحصل على رسالة خطأ. سيحصل المستخدم على رسالةٍ مفادها أنَّ موقعه أصبح جاهزًا تقريبًا: لكن لأسبابٍ أمنية، يجب أن يضغط المستخدم على رابطٍ سيُرسَل له عبر البريد الإلكتروني قبل أن يعمل الموقع. تحقق من صندوق البريد الوارد في البريد الإلكتروني الذي استعملتَه للتسجيل؛ حيث ستحصل على رسالة إلكترونية شبيهة بالرسالة الآتية: اضغط على ذاك الرابط لتذهب إلى صفحة فيها معلومات الدخول الخاصة بك: يمكنك الآن زيارة موقعك أو تسجيل الدخول كمدير للموقع باستخدام الروابط الموجودة. ستُرسِل ووردبريس رسالةً إلى المستخدم على البريد الإلكتروني فيها تفاصيل الموقع الجديد: هذا هو الموقع الخاص بالمستخدم، مع قالب Twenty Sixteen المفعل افتراضيًا: تخصيص عملية التسجيل ما رأيته الآن هو العملية الافتراضية لتسجيل موقع، لكن إن أردت أن تُخصِّص بعض الأمور، فهذه هي الخيارات المتاحة أمامك: تخصيص رسالة الترحيب التي تصل على البريد (ثاني رسالة) عبر صفحة ضبط الشبكة تخصيص رسالة الترحيب للمستخدمين الجدد الذين لم يسجلوا موقعًا عبر صفحة ضبط الشبكة تخصيص المحتوى الافتراضي للمواقع الجديدة (أول منشور، وأول صفحة، وأول تعليق) عبر صفحة ضبط الشبكة تخصيص نموذج التسجيل عبر إضافة لنبدأ بتخصيص رسالة الترحيب التي تصل على البريد للمواقع الجديدة وللمستخدمين الجدد. تخصيص رسائل الترحيب الإلكترونية اذهب إلى «Settings > Network Settings» (الإعدادات > إعدادات الشبكة) ثم مرِّر إلى الأسفل إلى أن تصل إلى قسم «New Site Settings» (إعدادات الموقع الجديد): ابدأ بتعديل البريد الإلكتروني الذي سيُرسَل إلى الأشخاص الذين نجحوا بتفعيل موقعهم الجديد، وذلك بتعديل الرسالة الموجودة في حقل «Welcome Email» (رسالة الترحيب بأصحاب المواقع). لاحظ أنَّ هنالك بعض الأكواد الخاصة مكتوبة بأحرفٍ كبيرة التي من المستحسن الإبقاء عليها: USERNAME: اسم مستخدم مالك الموقع SITE_NAME: عنوان الشبكة (وليس الموقع الجديد) BLOG_URL: عنوان URL للموقع الجديد (مع شرطة مائلة في نهايته) PASSWORD: كلمة مرور المستخدم الجديد LOGINLINK: رابط لكي يسجِّل المستخدم دخوله إلى الشبكة أو إلى الموقع الذي أُضيف إليه من قِبل مدير موقع هذا هو النص الذي سأستعمله، الذي أرى أنَّه ملائم أكثر لموقعي: لنعدل الآن البريد الذي سيصل للمستخدمين الجدد الذين لم يضيفوا موقعًا جديدًا. هذه الرسالة تتضمن نصًا مشابهًا للرسالة السابقة، لكن دون أيّة إشارات إلى إدارة الموقع. عدِّل هذه الرسالة في حقل «Welcome User Email» (رسالة الترحيب بالأعضاء الجدد): بعد أن تُعدِّل هذه الرسائل، اضغط على زر «Save Changes» (حفظ التغييرات) في أسفل الصفحة لحفظ تعديلاتك. تخصيص المحتوى الافتراضي افتراضيًا، تملأ ووردبريس كل موقع على الشبكة بمنشور وصفحة وتعليق، وذلك بطريقةٍ شبيهةٍ بالمواقع المفردة. يمكنك أن تُعدِّل ذلك المحتوى. أرى شخصيًا أنَّ المحتوى الافتراضي غير مفيد أبدًا، لهذا أحب أن أعدِّله. لفعل ذلك، اذهب إلى «Settings > Network Settings» (الإعدادات > إعدادات الشبكة) ثم مرِّر إلى الأسفل إلى أن تصل إلى قسم «New Site Settings» (إعدادات الموقع الجديد) ثم تخطى الحقلين الخاصين برسائل البريد الذين عملنا عليهما في الفقرة السابقة. يمكنك استخدام شيفرات HTML في هذه الحقول لإضافة تعدادات أو روابط أو صور أو غير ذلك. كن مبدعًا! عدلتُ المنشور الافتراضي في شبكتي لكي يوفر مزيدًا من المعلومات حول كيفية عمل المنشورات والصفحات والتعليقات: وعندما يُنشِئ أحدهم موقعًا في شبكتي، فسيبدأ بموقع يحتوي منشورًا وصفحةً وتعليقًا كالتي ضبطتُها: تخصيص صفحة التسجيل إن لم تكن سعيدًا بصفحة التسجيل الافتراضية، فيمكنك تخصيصها عبر إضافة. هذه هي بعض الخيارات المطروحة أمامك: استخدام إضافة تسجيل (هذه قائمة بأفضل 20 إضافة للتسجيل وتسجيل الدخول) لإضافة ودجت (widget) إلى قائمة الودجات في موقعك على الشريط الجانبي أو في التذييل، أو في منطقة خاصة بالودجات ضمن سياق المحتوى الرئيسي إن كان متوفرًا للقالب الذي تستعمله. استخدام إضافة للنماذج مثل Gravity Forms، التي تسمح لك بإنشاء نموذج للتسجيل/تسجيل الدخول الذي تتم من خلاله عملية التسجيل. ستحتاج إلى مكوِّن User Registration لإضافة Gravity Forms لكي تربط نموذجك بعملية التسجيل. ويمكنك أن تستعمل مكوِّن Paypal لإضافة خيار الدفع كجزء من عملية التسجيل. استخدام إضافة لتسجيل العضويات مثل Pro Sites، التي تسمح لك ببيع المواقع مع خيارات خاصة. لننظر إلى كيفية إنشاء نموذج تسجيل خاص باستخدام Gravity Forms. ملاحظة: إضافة Gravity Forms هي إضافة مدفوعة، وستحتاج إلى رخصة مطوِّر لاستخدام مكوِّن التسجيل. إن لم تكن ميزانيتك تسمح بذلك، فاستخدم صفحة التسجيل الافتراضية في ووردبريس. تخصيص نموذج التسجيل باستخدام Gravity Forms يجب أن تكون الإضافة مثبتةً ومفعّلةً في موقعك الرئيسي. يمكنك رؤية ذلك واضحًا في لقطة الشاشة الآتية: الخطوة التالية هي إنشاء نموذج. اذهب إلى «Forms > New Form» لإنشاء نموذجك. ستحتاج إلى الحقول الآتية على الأقل: اسم المستخدم البريد الإلكتروني عنوان الموقع يمكنك إضافة حقول أخرى مثل الاسم الأول والكنية ورابط الموقع، التي يمكن أن تُستعمَل أثناء عملية تسجيل المستخدم. هذا هو النموذج الذي سأعتمده: نموذجٌ بسيطٌ جدًا كما ترى، خذ وقتك لإجراء أيّة تعديلات تلائمك. بعد أن تنتهي من هذه الخطوة، عليك أن تربط هذا النموذج بعملية تسجيل المستخدم. اذهب إلى «Forms > User Registration» ثم اضغط على زر «Add New». اختر الإجراء الذي تريده لنموذجك أولًا، والذي هو «Create User» ثم اختر النموذج الذي أنشأتَه منذ قليل من القائمة. ثم ستظهر حقولٌ إضافية: اختر الحقول لنموذج التي تريد أن تستخدمها لإتمام عملية التسجيل من القوائم المنسدلة. ثم مرِّر إلى الأسفل إلى قسم «Network Options» وفعِّل خيار «Create Site»: مما سيُظهِر حقولًا إضافية متعلقة بعملية إنشاء الموقع. اختر الحقول الموافقة من القوائم المنسدلة كما مرَّ معنا سابقًا. إذا قررتَ في هذه المرحلة أنَّ عليك تعديل أمرٍ ما في النموذج أو إضافة حقول أخرى، فلا حرج في ذلك، احفظ ما عدَّلتَه في هذه الصفحة، ثم ارجع إلى النموذج وعدِّل ما تشاء ثم عُد إلى هذه الصفحة وأكمل التحرير. مرِّر إلى الأسفل لتصل إلى «Additional Options» وفعِّل خيار «User Activation»؛ وهذا سيؤدي إلى تفعيل التأكد من المستخدم عبر البريد الإلكتروني وسيُحسِّن من مستوى الحماية في شبكتك. في النهاية، اضغط على زر «Save» لحفظ ما تم تعديله في هذه الصفحة. كل ما عليك فعله الآن هو إضافة النموذج إلى موقعك، تعطيك إضافة Gravity Forms ودجت تستطيع أن تستعملها في الشريط الجانبي أو في التذييل، أو يمكنك إضافتها إلى صفحتك الرئيسية. بشكلٍ بديل، يمكنك إنشاء صفحة جديدة الغرضُ منها هو إظهار نموذج التسجيل، والتي تُمثِّل نسخةً مُحسَّنةً من صفحة wp-signup الأصلية. لكني سأضيف هنا النموذج إلى الشريط الجانبي. يمكنك إضافة الودجات عبر صفحة الودجات أو عبر تخصيص القالب. سأستخدم هنا صفحة تخصيص القالب. اذهب إلى «Appearance > Customize» (مظهر > تخصيص) ثم اختر «Widgets» (ودجات)، ثم اختر منطقة الودجات التي تريد التعامل معها، ثم اضغط على زر «Add a Widget» (أضف ودجت)، ثم اختر ودجة «Forms»: ثم اختر النموذج الذي تريد استخدامه، ثم عدِّل عنوانه: في النهاية، اضغط على «Save & Publish» (حفظ ونشر)؛ وسترى نموذج التسجيل في موقعك: حاليًا، صفحتي الرئيسية تعرض التدوينات التي أكتبها، وهذا ليس مفيدًا أبدًا؛ لذا سأعدِّل الصفحة الرئيسية إلى صفحة ثابتة لحثّ الزوار على التسجيل. هذه هي النسخة المُحسّنة: يمكنني إضافة هذا النموذج إلى صفحتي الرئيسية أو إلى صفحةٍ أخرى إن شئت –بالإضافة إلى منطقة الودجات– وذلك باستخدام زر لإضافة نماذج Gravity Forms في صفحة تحرير المنشورات والصفحات. يمكن الآن لمستخدمي الشبكة أن يصلوا إلى نموذج يُمكِّنهم من إنشاء موقع خاص بهم. أستطيع أيضًا تثبيت مكوِّن Paypal لإضافة Gravity Forms لكي أجعل المستخدمين يدفعون لقاء التسجيل. أو يمكن استخدام إضافة Pro Sites، التي تسمح لك بضبط عدِّة خيارات متعلقة بعضوية الشبكة وبإنشاء المواقع. شبكة ووردبريس تحب المستخدمين! السماح بإنشاء المواقع من قِبل المستخدمين في شبكة ووردبريس بسيطٌ جدًا وذلك بتفعيل أحد الخيارات في إعدادات الشبكة. لكن، كما تعلم، جعل تلك العملية «صديقة» للمستخدم هو أمرٌ معقدٌ بعض الشيء. أنت تريد أن تَحُثَّ أكبر قدر ممكن من المستخدمين على التسجيل وإنشاء المواقع، ويمكن فعل ذلك بوضع روابط واضحة لصفحة التسجيل، ويمكنك أيضًا إضافة نموذج تسجيل مُخصَّص باستخدام إضافة Gravity Forms كما شرحنا أعلاه. في الجزء التالي من هذه السلسلة، سننظر إلى استخدامٍ آخر لشبكات ووردبريس لاستضافة المواقع الشخصية أو مواقع العملاء، وسنتعلم كيفية تسخير قدرات شبكات ووردبريس لاستضافة عدِّة مواقع لمستخدميك، وكيف تجعل سير العمل سلسًا قدر الإمكان. وسننظر أيضًا إلى كيفية ربط أسماء النطاقات كي نستعمل نسخة ووردبريس وحيدة لاستضافة عدد كبير من المواقع كلٌ على نطاقٍ خاصٍ به. ترجمة –وبتصرّف– للمقال WordPress Multisite Masterclass: Site and User Registration لصاحبته Rachel McCollin.
  16. دفع عجلة تطوير الويب تعني جعله أفضل للمستخدمين والمطورين على حدٍ سواء، وهذا يعني محاولة حلّ المشكلات التي تواجه الويب في الوقت الراهن؛ وهذا ينطبق أيضًا على جعل المواقع متوافقة مع اتجاه RTL بسهولة ويسر. قبل أن نكمل مشوارنا في الحديث عن المواضيع المتقدمة عن RTL، لنبدأ درسنا بمثالٍ عمليٍ بسيط لتتذكر فيه كيف نقلب الاتجاه إلى RTL بطريقةٍ صحيحة: سنكمل حيث انتهينا في درسنا السابق، وحان الوقت الآن لنتعمّق في بعض المواضيع المتقدمة المتعلقة بتطوير واجهات من اليمين إلى اليسار. شرحنا في الدرس الأول الأساسيات، وسنشرح هنا بعض الخاصيات المُحدَثَة التي أتت حديثًا على الويب والتي ستعطينا فكرةً عن مستقبل الويب. التقنيات الحديثة الأساس الذي تستند عليه الواجهات ذات الاتجاه من اليمين إلى اليسار (RTL) هو خاصيات CSS، وهذه الخاصيات تتطور مع الوقت كما هو حال بقية مكوّنات الويب. سأذكر هنا بعض خاصيات CSS التي يمكنك تجربتها على الفور في النسخ الحديثة من المتصفحات (من المحتمل أن تتغير هذه المعلومات بعد صدور تحديثات جديدة للمتصفحات). محاذاة النص: تعودنا في الماضي على تحديد المحاذاة الأفقية للنص عبر text-align: left أو right؛ أما الآن، فلدينا القيمتان start و end. فعلى سبيل المثال text-align: start ستعطي نتيجةً مختلفةً بناءً عمّا إذا كان اتجاه المحتوى من اليمين إلى اليسار أم من اليسار إلى اليمين. القيمة start تُشير إلى اليسار في اتجاه LTR وإلى اليمين في اتجاه RTL، والعكس صحيح للقيمة end. مثالٌ يستخدم left|right: #content { text-align: left: } html[dir="rtl"] #content { text-align: right; } أما لو استعملنا start|end: #content { text-align: start; } لا حاجة إلى استعمال قاعدة خاصة باتجاه RTL باستخدامنا للقيمتين start|end. دعم المتصفح: Chrome 1.0+‎، و Safari 3.1+‎، و Firefox 3.6+‎، وأندرويد، و iOS، غير مدعومة في متصفح Internet Explorer في الوقت الراهن. خاصيات padding و margin و border: هنالك تحسيناتٌ أُدخِلَت على تلك الخاصيات. أصبحت كل واحدة منها تقبل لاحقةً إضافيةً هي ‎-inline-start أو ‎-inline-end، فمثلًا يمكننا أن نكتب padding-inline-end أو margin-inline-start. تعطي هذه الكلمات المحجوزة الجديدة نفس تأثير start و end في محاذاة النص: الخاصية padding-inline-start تماثِل padding-left في اتجاه LTR وتماثِل padding-right في اتجاه RTL. أما margin-inline-end تعطي نفس تأثير margin-right في اتجاه LTR و margin-left في اتجاه RTL. مثالٌ يستعمل left|right: #content { padding-left: 12px: margin-right: 20px; } html[dir="rtl"] #content { padding-left: 0; padding-right: 12px; margin-left: 20px; margin-right: 0px; } نفس المثال لكن باستعمال start|end: #content { padding-inline-start: 12px: margin-inline-end: 20px; } أكرِّر أنَّه لا حاجة إلى قاعدة خاصة باتجاه RTL؛ فستصبح خاصية margin-inline-end وكأنها margin-right في اتجاه LTR و margin-left في اتجاه RTL. دعم المتصفحات: Firefox 41+‎ فقط. تحديد الموقع المطلق (absolute position) للعناصر: الخاصيتان left وright أساسيتان لتحديد الموقع المطلق، لكن قريبًا سترى استخدامًا لخاصياتٍ أذكى، ألا وهي offset-inline-startوoffset-inline-end. يجدر بالذكر أنَّك تستطيع استعمال offset-block-startوoffset-block-end بدلًا من top و bottom على التوالي وبالترتيب. مثالٌ يستعمل left|right: #content { position: absolute; left: 5rem; } html[dir="rtl"] #content { left: auto; right: 5rem; } نفس المثال لكن باستعمال start|end: #content { offset-inline-start: 5rem; } أكرر مرةً أخرى أنَّ مفهوم start|end وفَّر علينا كتابة بعض الشيفرات في ملف CSS. دعم المتصفحات: Firefox 41+‎ فقط. تحديد موقع العناصر باستخدام float: استعملنا float: left و float: right لوقتٍ طويل، لكنك ستتمكن قريبًا من استعمال float: inline-start و float: inline-end. خاصية inline-start ترتِّب عنصرك إلى اليسار في اتجاه LTR وإلى اليمين في اتجاه RTL. مثالٌ يستعمل left|right: #content { float: left; } html[dir="rtl"] #content { float: right; } نفس المثال لكن باستعمال start|end: #content { float: inline-start; } دعم المتصفحات: Firefox 44. Web Components (مكوِّنات الويب): وهي عناصر الواجهة الرسومية القابلة لإعادة الاستخدام. إذا تعاملت مع web components من قبل فستعلم أنَّ أنماط CSS الخاصة بها موجودة ضمن شجرة DOM فرعية (shadow DOM)، لذا لن تتمكن افتراضيًا من الحصول على اتجاه الصفحة التي تستعمل تلك المكوِّنة عبر html[dir="rtl"]، لكن شجرة DOM الفرعية (shadow DOM) تتضمن محدِّدًا جديدًا اسمه ‎:host-context()‎ الذي تستطيع استخدامه لتحديد عنصر في شجرة DOM الأساسية (host DOM). لنحاول تبسيط الأمر عبر مثال. لنقل أنَّ لديك عنصرًا داخل شجرة DOM فرعية اسمه back. كنت ستستخدم html[dir="rtl"] .back {}‎ في حال لم تكن داخل شجرة DOM فرعية، لكنك لا تستطيع استخدام هذا المُحدِّد من داخل مكوِّن (component). المُحدِّد المكافئ للمحدِّد السابق الذي تستطيع استخدامه داخل مكوِّن هو: .back:host-context(html[dir="rtl"]) { } ليس من الواضح ما مدى دعم هذا النوع من المُحدِّدات، لكن يمكنك استخدام هذه الطريقة الالتفافية. لا ترغب باستخدام الطرق الالتفافية لكنك تريد أن تجرِّب اتجاه RTL في web component في المتصفحات التي تدعمها مثل فيرفكس (بعد تفعيل الراية dom.webcomponents.enabled) ومتصفح Google Chrome؟ يمكنك فعل ذلك عبر Mutation Observers بمراقبة الخاصية document.documentElement.dir. ستبدو شيفرة المراقبة شبيهةً بالمثال الآتي: var dirObserver = new MutationObserver(updateShadowDir); dirObserver.observe(document.documentElement, { attributeFilter: ['dir'], attributes: true }); لا تنسَ أن تُهيّئ دالتك لأول مرة بعد تحميل الصفحة، بعد شيفرة المراقبة مباشرةً: updateShadowDir(); ستبدو دالة updateShadowDir()‎ كالآتي: function updateShadowDir() { var internal = myInnerElement.shadowRoot.firstElementChild; if (document.documentElement.dir === 'rtl') { internal.setAttribute('dir', 'rtl'); } else { internal.removeAttribute('dir'); } }; كل ذلك عبر JavaScript. سيملك أول «ابن» (first child) في المكوِّنة خاصية dir قابلة للتغيير، وستعتمد أنماط CSS عليه كمُحدِّد بدلًا من عنصر html. ولنقل أنَّ ذاك العنصر هو span، لذا سيكون مُحدِّدك شبيهًا بما يلي: span[dir="rtl"] rest-of-the-selectors-chain { … } أعلم أنَّ الأمر يبدو معقدًا، لكن –لحسن الحظ– المستقبل مشرق، لذا لنلقِ نظرةً على ما تُخبّؤه W3C لنا في المستقبل بما يخص اتجاه RTL. مستقبل اتجاه RTL في الويب إعلام الخادوم باتجاه النص: في الوقت الراهن نفقد قيمة اتجاه الصفحة (أو اتجاه عناصر النموذج) عند إرسال نموذج يحتوي على حقول إدخال نصية. أتت الخواديم بطرقٍ خاصةٍ بها لكي تُحدِّد اتجاه النص الُمرسَل إليها. لحل هذه المشكلة ولإضافة معلومات حول اتجاه النص المُرسَل، ابتكرت W3C خاصيةً جديدةً ووضعتها في مواصفة نماذج HTML5 اسمها dirname، التي ستُضيفها المتصفحات في المستقبل القريب. وكما ذَكَرَ المعيار، «تضمين خاصية dirname في حقول النموذج يُفعِّل إرسال اتجاه العنصر، ويعطي اسم الحقل الذي يحتوي على هذه القيمة أثناء عملية الإرسال. إذا حُدِّدت هذه الخاصية، فيجب ألّا تكون قيمتها فارغةً». بعبارة أخرى: إضافة هذه الخاصية إلى حقول <input> أو <textarea> يؤدي إلى تمرير اتجاهها مع معلومات GET أو POST التي ستُرسَل إلى الخادوم. لننظر إلى مثالٍ عملي. ليكن لدينا هذا النموذج: <form action="result.php" method="post"> <input name="comment" type="text" dirname="comment.dir"/> <button type=submit>Send!</button> </form> ستحتوي عبارة POST التي ستُرسَل إلى الخادوم على حقلٍ اسمه comment، وحقلٍ آخر اسمه comment.dir. وإذا كتب المستخدم الكلمة «Hello» في الحقل النصي وأرسل النموذج، فستكون النتيجة هي: comment=Hello&comment.dir=ltr أما إذا كتب «مرحبا» فستكون النتيجة هكذا: comment=%D9%85%D8%B1%D8%AD%D8%A8%D8%A7&comment.dir=rtl يمكنك قراءة المواصفة من هنا. ملاحظة: لكي تُعرَض المحارف العربية عرضًا صحيحًا في عناوين URL في متصفحك، فيجب أن تُرمَّز المحارف بترميز UTF-8، وكل حرف عربي يستعمل 4 محارف مفصولة فيما بينهما برمز %. على سبيل المثال، لو كان لديك هذا الرابط؛ فسيحوله متصفحك عندما تزوره إلى هذه الصّفحة طرق أفضل لكيفية التعامل مع الخلفيات والصور في RTL هل سئمتَ من استخدام transform: scaleX(-1) لعكس صور الخلفية؟ قدّمَت W3C كلمةً محجوزةً جديدةً في CSS اسمها rtlflip التي تُستعمل كما يلي: background-image: url(backbutton.png) rtlflip; ستقلل عليك هذه الكلمة المحجوزة من عبء قلب جميع صورك عبر خاصية transform: scaleX(-1) يدويًا. من الممكن استعمالها أيضًا في قاعدة صور القوائم كما يلي: list-style-image:url('sprite.png#xywh=10,30,60,20') rtlflip; تقول صفحة المواصفة أيضًا أنَّ هذه الكلمة المحجوزة يمكن أن تستعمل في جميع الطرق الممكنة لتحديد الصور في CSS3. على سبيل المثال: url و sprite و image-list و linear-gradient و radial-gradient. الواجهة البرمجية للتدويل إليكم بعض الأجزاء غير المشهورة المتعلقة باتجاه RTL في الواجهة البرمجية للتدويل (Internationalization APIs) في JavaScript تدعم الواجهة البرمجية للتدويل عددًا كبيرًا من اللغات مع مشتقاتها؛ فمثلًا لا تدعم هذه الواجهة البرمجية اللغة العربية فحسب، وإنما تدعم «العربية-مصر» و «العربية-تونس» وقائمة طويلة بالاشتقاقات الأخرى. استخدام الأرقام العربية المشرقية بدلًا من الأرقام العربية الغربية: تُستخدم الأرقام العربية المشرقية (١٢٣) في بعض البلدان بدلًا من الأرقام العربية الغربية (123). تسمح لنا واجهة التدويل البرمجية بتحديد متى نريد إظهار ١٢٣ ومتى نظهر 123. console.log(new Intl.NumberFormat('ar-EG').format(1234567890)); السطر السابق يقول أنَّنا نريد تنسيق الرقم 1234567890 بصيغة الأرقام التي تستعملها مصر (ar-EG). الناتج: ١٬٢٣٤٬٥٦٧٬٨٩٠ console.log(new Intl.NumberFormat('ar-TN').format(1234567890)); نقول هنا أننا نريد إظهار الرقم بالصيغة المعتمدة في تونس؛ ولمّا كانت تونس تستعمل الأرقام العربية الغربية، فسيكون الناتج: 1234567890 إظهار التواريخ بالتقويم الهجري بدلًا من الميلادي: هناك صفحة google.com/ramadan خاصة بإظهار معلومات حول شهر رمضان. وأحد أهم المعلومات الموجودة هي رقم اليوم في الشهر الهجري (القمري). تستخدم Google طريقة التفافية للحصول على هذه المعلومات. لكنك تستطيع الحصول على نفس المعلومات عبر الواجهة البرمجية للتدويل بسطرٍ وحيد بدلًا من مكتبة JavaScript كاملة. هذا مثال: console.log(new Intl.DateTimeFormat("fr-FR-u-ca-islamicc").format(new Date())); السطر السابق يعني أنَّنا نريد أن يكون التاريخ الحالي بالتقويم الهجري وأن يُعرَض بالأرقام العربية الغربية (fr-FR). الناتج هو: 16/12/1436 console.log(new Intl.DateTimeFormat("ar-SA-u-ca-islamicc").format(new Date())); نفس الأمر هنا، لكن التنسيق لمحليّة (locale) الخاصة بالسعودية التي تستعمل الأرقام العربية المشرقية. الناتج: ١٦‏/١٢‏/١٤٣٦ الخلاصة رأينا في هذا الدرس بعض التقنيات المتقدمة لدعم اتجاه RTL، وأخذنا فكرةً عن مستقبل دعم RTL من معايير الويب. ترجمة -وبتصرّف- للمقال Building RTL-Aware Web Apps & Websites: Part 2 لصاحبه أحمد نفزاوي
  17. فعّلنا في الدرس السابق شبكة المواقع في ووردبريس، وضبطتنا بعض الخيارات، وسنشرح في هذا الدرس إدارة المستخدمين والقوالب والإضافات. إدارة المستخدمين كما ذكرنا في الدرس السابق، يمكنك إضافة المستخدمين إلى موقعٍ معيّن عبر لسان Users (أعضاء) في صفحة Sites (المواقع) في لوحة تحكم مدير الشبكة. يمكنك أيضًا إضافة مستخدمين إلى الشبكة وتعديل بياناتهم عبر صفحة Users (أعضاء) في لوحة التحكم. هذه الصفحات تعمل بشكلٍ مشابهٍ لمواقع ووردبريس المفردة، ما عدا جزئية واحدة هي أنَّ هنالك معلومات عن المواقع التي يملك هذا المستخدم حسابًا فيها. سترى في الصورة الآتية مستخدمي الموقع الخاص بي، بالإضافة إلى حساب مدير الموقع الذي أنشأته للتو: سترى أيضًا عمودًا إضافيًا يُظهِر ما هي المواقع التي أُضيف إليها ذاك المستخدم. يمكنك استخدام هذه الصفحة للوصول إلى صفحة المستخدم، أو حذف المستخدم –ضع الفأرة فوق اسم المستخدم، ثم اضغط على رابط «حذف». حذف المستخدم لن يؤدي إلى حذف المواقع التي أنشأها– إذا كان لديك مستخدمٌ أنشأ حسابًا مزعجًا (spam) ومدونة لذاك الغرض، فعليك حينها حذف المستخدم والموقع. لإضافة مستخدم، اضغط على زر «Add New» (أضف جديد)، الذي يعمل بطريقة مشابهة لطريقة إضافة مستخدمين في المواقع المفردة. وإذا أردت إضافة ذاك المستخدم إلى موقع، فيمكنك فعل ذلك في صفحة «المواقع» في لوحة التحكم في لسان «Sites > Users» (المواقع > أعضاء). تثبيت القوالب والإضافات لا يمكن تثبيت القوالب والإضافات إلا من مدير الشبكة، إذ لا يستطيع مدراء المواقع فعل ذلك. لننظر إلى كيفية القيام بذلك، وكيف تتمكن بعدها من تفعيل أو تمكين تلك القوالب أو الإضافات لمواقع الشبكة. تثبيت وتفعيل القوالب بعد أن تُثبِّت قالبًا، فعليك تمكينه للمواقع الموجودة في شبكتك بإحدى الطريقتين الآتيتين: إما أن تُمكِّنه للمواقع كلًا على حدة، أو أن تُمكِّنه لجميع مواقع الشبكة. يمكن أن يُفعَّل القالب على موقعٍ ما (بوساطة مدير الشبكة أو مدير الموقع) إذا كان ذاك القالب مُمكَّنًا لكل مواقع الشبكة أو لذاك الموقع بالتحديد. هذه هي طريقة تثبيت قالب وتمكينه على الشبكة: في لوحة تحكم مدير الشبكة، اذهب إلى «Themes > Add New» (قوالب > أضف جديد)، ثم ثبِّت القالب بالطريقة المعتادة. في صفحة تثبيت القالب، اضغط على رابط «تفعيل في الشبكة» بشكلٍ بديل، يمكنك تمكين استخدام قالب مثبت مسبقًا بالذهاب إلى صفحة «Themes» (قوالب) ثم الضغط على رابط «تفعيل في الشبكة» الظاهر في أسفل القالب. يمكنك أيضًا أن تُمكِّن قالبًا لموقعٍ وحيد، وهذا مفيد إذا كانت تحتوي شبكتك على العديد من المواقع التي يجب أن يكون لكلٍ منها قالبٌ خاصٌ به؛ وهذا يكون عندما تستضيف شبكتك مواقع عملائك. تمكين القوالب لكل موقع على حدة يعني أنَّ بقية القوالب لن تكون متاحةً للمواقع التي لم تُمكِّن ذاك القالب فيها، لذا لن يستطيع مدراء المواقع تفعيل القالب الخاطئ دون قصد. هذه طريقة فعل ذلك: في لوحة تحكم الشبكة، اضغط على Sites (مواقع) لمشاهدة جميع المواقع التي عندك. مرر الفأرة فوق اسم الموقع الذي تريد تمكين القالب له ثم اضغط على رابط Edit (تحرير) الذي سيظهر. اضغط على لسان Themes (قوالب) لعرض صفحة تعديل ضبط القوالب لهذا الموقع: اضغط على رابط Enable (تفعيل). اذهب الآن إلى لوحة تحكم مدير الموقع واضغط على «Appearance > Themes» (مظهر > قوالب)، وسترى القالب الذي مكّنته موجودًا في القوالب القابلة للتفعيل: تثبيت وتفعيل الإضافات يجب أيضًا على مدير الشبكة تثبيت الإضافات، لكنها تعمل بشكلٍ مختلف عن القوالب، إذ لا تستطيع أن تُفعِّل إضافةً ما لموقعٍ معيّن، وإنما يمكنك أن تُفعِّل الإضافة لكل المواقع الموجودة على الشبكة، أو أن تثبِّتها لكي يتمكن مدراء المواقع من تفعيلها. تفعيل الإضافات على كل الشبكة مفيدٌ إذا كتبتَ أو نزلتَ إضافةً توفِّر ميزةً تريد لكل مواقع شبكتك أن تملكها، على سبيل المثال، لو أردت تفعيل إضافة للتخزين المؤقت (caching) أو إضافة لتحسين SEO. هنالك بعض الإضافات التي يمكن أن تُفعَّل لكامل الشبكة فقط، على سبيل المثال، أُثبِّت على شبكة عملائي إضافة Snapshot لأخذ نسخ احتياطية لكامل مواقع الشبكة بشكلٍ دوري. هذه هي طريقة تثبيت وتفعيل إضافة: في لوحة تحكم مدير الشبكة، اذهب إلى «Plugins > Add New» (إضافات > أضف جديد) وثبِّت الإضافة كما كنتَ تفعل في ما مضى. في صفحة تثبيت الإضافة، اضغط على رابط «تفعيل في الشبكة». ستعمل الإضافة الآن على جميع المواقع في الشبكة، ولن يتمكن مدراء المواقع من تعطيلها. لكن ماذا لو أردت أن تُفعِّل إضافةً ما في موقعٍ معيّن؟ يمكنك فعل ذلك بتثبيت الإضافة كمدير للشبكة، ثم تفعيلها لذاك الموقع. في لوحة تحكم مدير الشبكة، اذهب إلى «Plugins > Add New» (إضافات > أضف جديد) وثبت الإضافة كما تعودت. سأنزِّل إضافة WooCommerce كما هو ظاهر في الصورة التالية. ربما لا تريد تفعيل إضافة WooCommerce لكل المواقع في شبكتك إلا إذا كانت الشبكة مخصصة لمالكي المتاجر: في صفحة تثبيت الإضافة، اضغط على رابط العودة إلى صفحة الإضافات. اذهب إلى لوحة تحكم مدير الموقع الذي تريد تفعيل الإضافة فيه واضغط على رابط «إضافات» في شريط الإدارة. اضغط على رابط «تفعيل» الظاهر تحت اسم الإضافة التي تريد تفعيلها، وذلك كما في مواقع ووردبريس العادية. يجب أن تُفعَّل الإضافة الآن، كما هو ظاهر في لقطة الشاشة الآتية: ضبط إعدادات الشبكة آخر مجموعة من الصفحات التي عليك أن تستعملها كمدير للشبكة هي صفحة إعدادات الشبكة. هنالك صفحتان هما: تهيئة الشبكة (Network Setup) التي تُظهِر ما رأيتَه أثناء تثبيتك للشبكة مع الشيفرة التي ستحتاج إلى إضافتها إلى ملفَي wp-config.php و ‎.htaccess. يمكنك الرجوع إلى هذه الصفحة إذا حدثت معك مشاكل في المستقبل وعليك أن تُعدِّل الملفين السابقين. إعدادات الشبكة (Network Settings) التي تعطيك إمكانية تعديل ضبط شبكتك. للوصول إلى صفحة إعدادات الشبكة، اذهب إلى «Settings > Network Settings» (الإعدادات > إعدادات الشبكة) للدخول إلى صفحة الضبط الآتية: الإعدادات التي يمكنك تخصيصها هي: عنوان الشبكة البريد الإلكتروني لمدير الشبكة إعدادات التسجيل: هل تريد أن يتمكن المستخدمون من تسجيل حسابات و/أو مواقع، أم أن يُضيف مدراءُ المواقع المستخدمين، وما هي نطاقات البريد الإلكتروني وأسماء المواقع المحجوبة. إعدادات المواقع الجديدة: محتوى رسالة البريد الإلكتروني الترحيبية لمدراء المواقع والمستخدمين والصفحة الرئيسية، والمنشور والتعليق الافتراضي الذي سيُنشَأ على المواقع الجديدة. إعدادات الرفع: أنواع الملفات المسموحة والحجم المسموح الأقصى للملف المرفوع. إعدادات اللغة: اللغة الافتراضية للموقع. إعدادات القائمة: تفعيل أو تعطيل قائمة الإضافات لمدراء المواقع. يمكنك تعطيل هذه القائمة لمنع تفعيل أو تعطيل الإضافات. سنعود إلى هذه الصفحة وسنشرحها بالتفصيل لاحقًا في السلسلة عندما نتعلم كيف نضبط عملية تسجيل المستخدمين وإنشاء المواقع. تفعيل وضبط شبكة متعددة المواقع أسهل مما تتخيل أصبحتَ الآن تعرف كل ما يلزمك لتهيئة شبكة متعددة المواقع وضبطها، بما في ذلك إضافة مواقع جديدة، وتثبيت وتفعيل القوالب والإضافات. في المرحلة القادمة من هذه السلسلة، سنتعلم عن عملية إنشاء الموقع، وسنُفعِّل إمكانية إنشاء المواقع من قِبل المستخدمين وضبط العملية لتحسين تجربة المستخدم. سنفعل بعض هذه الأمور عبر صفحات الضبط وبعضها عبر كتابة بعض الشيفرات أو استخدام الإضافات. ترجمة –وبتصرّف– للمقال WordPress Multisite Masterclass: Activation and Configuration لصاحبته Rachel McCollin.
  18. أهلًا بك مجددًا في دورتنا التدريبية، سنشرح في هذا الدرس من السلسلة كيفية تفعيل ميزة تعدد المواقع وتشغيل شبكتك. سأشرح لك عملية التثبيت، ثم سأريك كيف تُنشِئ موقعًا في شبكتك، وتضيف المستخدمين، وتُثبِّت القوالب والإضافات وتضبط خيارات الشبكة. سأشرح لك في هذه السلسلة كل ما تحتاج معرفته لإنشاء شبكتك الخاصة، وطريقة إضافة مواقع إليها، أو السماح للمستخدمين بإضافة مواقعهم الخاصة، وكيفية إدارة الشبكة. ستتعلم أيضًا كيف تتأكد أنَّ شبكتك آمنة وأنَّ أداءها عالٍ، وكيف تُنشِئ مجتمعًا ناجحًا من المستخدمين والمواقع. قبل أن نبدأ في هذا الجزء من السلسلة التعليمية، أنصحك أن تقرأ الدرسين الأولين: مدخل إلى ووردبريس مُتعدّد المواقع أمور إضافية يجب أن تعرفها قبل أن تُطلق أول شبكة لك على ووردبريس مُتعدّد المواقع اللذان يوفران تقديمًا إلى ميزة تعدد المواقع في ووردبريس. أقرأتهما من قبل؟ رائع! فلنبدأ. ما الذي ستحتاج له لكي تتابع دروسنا في هذه السلسلة، فستحتاج إلى ما يلي: نسخة ووردبريس مُثبَّتة. قد تكون هذه النسخة موجودةً عندك من قبل أو أن تكون قد ثبتها حديثًا. أنا أرى أن تعمل على نسخةٍ جديدةٍ لكي تحصل على أغلبية الخيارات ولكي تتفادى خطر تعطيل موقعك. لا تفعل ذلك على موقعٍ إنتاجي قبل أن تأخذ نسخةً احتياطيةً أولًا! محرر شيفرات برمجية لتعديل ملفَي wp-config.php و ‎.htaccess الخاصَين بموقعك. سأستخدم محرر Coda لنظام ماك الذي يتضمن عميل FTP أيضًا؛ يمكنك اختيار أي محرر يعجبك. إن لم يتضمن محررك عميل FTP مُضمَّن داخله، فستحتاج إلى عميل FTP خارجي ليسمح لك بتنزيل ورفع ملفاتك إلى موقعك، مثل برنامج FileZilla. إذا كنت تُفضِّل أن تعمل على موقعٍ محلي بدلًا من موقعٍ يعمل على خادومٍ بعيد، فيمكن أن تستعمل نسخة ووردبريس مثبتة على خادوم محلي مثل MAMP أو ما شابهه (ولن تحتاج حينها إلى استخدام FTP لكن ذلك لن يغنيك عن محرر الشيفرات). سأفترض أنَّك معتادٌ على التعامل مع واجهة ووردبريس وأنَّك لا تخشى أن تُعدِّل الملفات مباشرةً، على الرغم من أنَّنا لن نفعل ذلك كثيرًا، لذا لا تقلق! تفعيل ميزة تعدد المواقع على نسخة ووردبريس هذه الميزة لا تتطلب تنزيل وتثبيت برمجيات جديدة لأنها جزءٌ لا يتجزأ من ووردبريس، لكن عليك تفعيلها لكي تجعلها تعمل. قبل أن تبدأ قبل أن تُفعِّل ميزة تعدد المواقع، فعليك أن تُقرِّر فيما إذا كنت تريد استخدام النطاقات الفرعية أو المجلدات الفرعية لمواقع شبكتك. هذه تذكرة سريعة ذكرناها سابقًا تبيّن لك معناها: استخدام النطاقات الفرعية يعني أنَّ لكل موقع رابط URL مثل http://site1.yournetwork.com، إذا كنت تخطط للسماح للآخرين بإنشاء مواقعهم الخاصة، فعليك أن تتأكد أنَّك تستطيع استخدام النطاقات الفرعية غير المحدودة في نطاقك الأساسي (عليك أن تراجع ذلك مع استضافتك). استخدام المجلدات الفرعية يعني أنَّ لكل موقع رابط URL مثل http://yournetwork.com/site1، لا يمكنك انتقاء هذا الخيار على موقعٍ موجودٍ مسبقًا والذي تحاول تحويله إلى شبكة لأن ذلك قد يسبب مشاكل مع روابط URL الموجودة مسبقًا في موقعك. إذا كنتَ تُفعِّل ميزة تعدد المواقع على موقعٍ محلي (أي موقع يعمل على حاسوبك المحلي)، فلن يُسمَح لك باستخدام النطاقات الفرعية عندما تحاول ضبط الشبكة، وإنما عليك استخدام المجلدات الفرعية. ضبط النطاقات الفرعية ملاحظة: لو أردت استعمال المجلدات الفرعية، فتجاوز هذه الفقرة. إذا كنت تستخدم النطاقات الفرعية وتتوقع أن تُنشَأ الكثير من المواقع على شبكتك، أو أنَّ المستخدمين سيُنشؤون مواقع خاصة بهم، فلن تعمل النطاقات الفرعية عملًا سليمًا إلا إذا كنت قد ضبطتَ ما يسمى «wildcard subdomains». أما إذا كنت تنوي ربط المواقع في شبكتك بنطاقات خارجية، أو لم تكن تمانع أن تضبط كل نطاق فرعي يدويًا عندما تُنشِئ موقعًا جديدًا، فحينها لن تحتاج إلى تفعيل wildcard subdomains. يمكنك أن تضبط النطاقات الفرعية عبر cPanel، التي يجب أن يعطيك مزود الاستضافة وصولًا إليها (راجع الدعم الفني إن لم تكن متأكدًا). ثم عبر cPanel اذهب إلى «Domains > Subdomains» لكي ترى الصفحة المسؤولة عن ضبط النطاقات الفرعية. هذه لقطة شاشة لموقعٍ ضبطتُ فيه wildcard subdomains: لضبط نطاق فرعي معيّن، عليك أن تضيفه إلى حقل «Subdomain» ثم الضغط على Create، فلو أضفتَ موقعًا إلى شبكتك له الرابط http://new-site.yournetwork.com فأضف new-site كقيمة لذاك الحقل. بشكلٍ بديل، يمكنك أن تضبط wildcard subdomains وذلك بكتابة رمز النجمة * في حقل «Subdomain» ثم اضغط على Create، وبهذا فلن تحتاج إلى إنشاء أيّة نطاقات فرعية يدويًا. ملاحظة: بعض شركات الاستضافة الرخصية لا يسمحون بتفعيل wildcard subdomains وبعضهم لا يعطيك وصولًا إلى لوحة cPanel. إذا وقعت في هذه الحالة، فأنصحك أن تبحث عن شركة استضافة أفضل، لكن إن لم تستطع فاطلب منهم أن يضبطوا النطاقات الفرعية لك. تفعيل ميزة تعدد المواقع ها قد أصبحتَ جاهزًا لتفعيل ميزة تعدد المواقع! إن لم تُثبِّت ووردبريس، فثبتها كالمعتاد، إما باستخدام سكربت يوفره مزود خدمة الاستضافة، أو بتنزيل ووردبريس وتثبيتها يدويًا على خادومك أو جهازك المحلي. افتح ملف wp-config.php الذي يجب أن تجده في المجلد الذي ثبتت ووردبريس فيه، ثم ابحث عن السطر الآتي: /* That's all, stop editing! Happy blogging. */ أو عن السطر الآتي (في النّسخة العربية): /* هذا هو المطلوب، توقف عن التعديل! نتمنى لك التوفيق. */ قبل ذلك السطر مباشرةً، افتح سطرًا جديدًا واكتب فيه المحتويات الآتية: define('WP_ALLOW_MULTISITE', true ); احفظ ملف wp-config.php. الخطوة الآتية هي زيادة لوحة تحكم ووردبريس وتثبيت ميزة تعدد المواقع. في لوحة تحكم ووردبريس، اذهب إلى «Tools > Network Setup» (أدوات > تهيئة الشبكة). ستنتقل إلى صفحة لإنشاء شبكة المواقع، وعليك إدخال أو اختيار ما يلي: تثبيت على مسار فرعي / نطاق فرعي. اختر ما تشاء إن كان متاحًا. عنوان الشبكة. هذا الحقل مملوء مسبقًا ويمكنك تعديله إن شئت، وتستطيع تعديله لاحقًا في ضبط الشبكة. البريد الإلكتروني لمدير الشبكة. إن كان عنوان البريد مختلفًا عن الذي أدخلتَه مسبقًا، فعدِّله. اضغط على زر «Install» (تنصيب). ستؤخذ بعد ذلك إلى صفحة لتفعيل الشبكة، التي ستظهر فيها بعض الشيفرات التي عليك إضافتها إلى ملفَي wp-config.php و ‎.htaccses: افتح ملفَي wp-config.php و ‎.htaccess وعدلهما لكي يتوافقا مع الشيفرات الموجودة في الصفحة السابقة. إن لم تعثر على ملف ‎.htaccess على خادومك، فقد يكون السبب هو أنَّ الملفات المخفية غير ظاهرة: عدِّل خيارات مُحرِّرك النصي إذا كنت تستعمله للوصول إلى تلك الملفات. احفظ كلا الملفين. يجب أن تكون ميزة الشبكة متعددة المواقع مثبتة الآن، وعليك تسجيل الدخول مرةً أخرى لكي ترى لوحة التحكم: يمكنك الآن البدء بإضافة مواقع وإضافات وقوالب والمزيد… إنشاء موقع ستملك شبكتك موقعًا وحيدًا في البداية، ألا وهو الموقع الأساسي، الذي هو الموقع الذي بدأت باستخدامه قبل تفعيل ميزة الشبكة متعددة المواقع. يمكنك إضافة مواقع أخرى بنفسك –كمدير للشبكة– أو يمكنك تفعيل إمكانية إنشاء المستخدمين لمواقع خاصة بهم. سنتعلم كيفية تفعيل إنشاء مواقع للمستخدمين لاحقًا في هذه السلسلة، لذا سأريك هنا كيف تفعل ذلك بنفسك. اذهب إلى لوحة تحكم مدير الشبكة بالضغط على «My Sites > Network Admin» (مواقعي > إدارة الشبكة) من على شريط الإدارة في الأعلى. اذهب إلى «Sites > Add New» (المواقع > أضف جديد). اكتب عنوان الموقع (إما كمجلد فرعي أو كنطاق فرعي)، واسم الموقع، والبريد الإلكتروني لمدير الموقع، كما هو ظاهر في الصورة أدناه: ثم اضغط على زر «Add Site» (أضف موقعًا) وستُنشِئ ووردبريس موقعًا لك. إذا استخدمتَ عنوان بريدك الإلكتروني الخاص بمدير الشبكة، فستتمكن من رؤية الموقع عندما تمرر الفأرة فورق رابط «My Sites» (مواقعي) في شريط الإدارة أعلى الشاشة. أما لو لم تكن المدير، فيمكنك أن تراه في لوحة تحكم إدارة الشبكة. اضغط على «Sites > All Sites» (المواقع > كافة المواقع) لرؤية جميع المواقع في الشبكة. سترى في الصورة الآتية الموقع الجديد مذكورًا بالإضافة إلى الموقع الأساسي: لاحظ أنَّ رابط URL لجميع مواقعي طويلٌ بعض الشيء لأنني ثبتتُ الشبكة متعددة المواقع في مجلدٍ فرعي في موقعي الرئيسي؛ ربما الروابط الخاصة بك أقصر. تعديل وضبط المواقع يمكنك كمدير للشبكة أن تُعدِّل المواقع إما عبر لوحة التحكم الخاصة بها، أو عبر قسم Sites (المواقع) في لوحة تحكم مدير الشبكة؛ وهنالك بعض الأمور التي يمكنك فعلها من صفحة Sites (المواقع) فقط، مثل تفعيل قالب لموقعٍ ما. تعديل حالة موقع من صفحة Sites (المواقع) في لوحة تحكم مدير الشبكة، يمكنك تغيير حالة كل موقع من مواقع الشبكة؛ الخيارات المتاحة أمامك هي: تعطيل. هذا ما سيحدث لموقعٍ على الشبكة لو قام مدير الموقع بحذفه. لن يتمكن مدير الموقع من الوصول إليه ولا يمكن للآخرين زيارته، لكنك –كمدير للشبكة– تستطيع فعل ذلك. تستطيع أن ترى في الصورة الآتية موقعًا معطّلًا ظاهرًا باللون الأحمر في لوحة تحكم مدير الشبكة. صحيحٌ أنَّه مُعلَّم على أنه «محذوف»، إلا أنه لم يُحذَف بعد، وإنما معطّل فقط. يمكنك الضغط على زر «Activate» (تفعيل) لتفعيل الموقع مرةً أخرى. أرشفة. تأثير الأرشفة مشابه لتعطيل الموقع، عدا أنَّ هنالك رسالة خطأ ستظهر عندما يحاول الآخرون زيارة الموقع. لن يتمكن مدير الموقع أو الزوار من الوصول إلى الموقع، لكن يمكنك فعل ذلك بصفتك مديرًا للشبكة وذلك من صفحة Sites (المواقع) في لوحة تحكم مدير الشبكة. مزعج. هذا الخيار لا يحذف الموقع، لكنه لن يكون متاحًا للوصول لأي شخص بما في ذلك مدير الشبكة. هذه هي الخطوة النهائية قبل الضغط على زر الحذف. حذف. هذا الخيار يحذف الموقع، مع جميع جداول قاعدة البيانات وجميع الملفات المرفوعة والمرتبطة معه. استخدم هذا الخيار بحذر! لاختيار أي شيء مما سبق، ضع الفأرة فوق اسم الموقع في صفحة Sites ثم اضغط على الرابط الموافق. معلومات الموقع في لوحة تحكم مدير الشبكة، اذهب إلى Sites (المواقع)، ثم مرر الفأرة فوق أحد المواقع ثم اضغط على Edit (تحرير)؛ وهذا سيأخذك إلى ألسنة (tabs) لتحرير الموقع، وستبدأ افتراضيًا بلسان Info: يمكنك هنا أن تستعرض وتعدِّل المعلومات الأساسية المرتبطة بهذا الموقع، مثل حالته ورابط URL. أحيانًا أُنشِئ موقعًا وأرتكب خطأ إملائيًا عندما أكتب رابط URL الخاص به، فإن حدث هذا معك، فهذا هو المكان الملائم لتصحيحه. مستخدمي الموقع يمكنك إضافة وتعديل مستخدمي الموقع بالضغط على لسان Users (أعضاء): سترى هنا كل مستخدمي الموقع، استخدم هذه الصفحة لإضافة مستخدم موجود مسبقًا في شبكتك إلى هذا الموقع، أو لإضافة مستخدم جديد؛ لكن أيًّا تكن الخيارات التي ستعتمدها، إلا أنَّك ستحتاج إلى تحديد دور (أو «رتبة») المستخدم؛ والتي ستكون رتبة المستخدم لهذا الموقع، وليس للشبكة ككل. قوالب الموقع اضغط على لسان Themes (قوالب) لتفعيل القوالب لمواقع معينة. هذا مفيدٌ إن كنت تدير شبكةً لمواقعك أو لمواقع عملاءك، وتريد أن يملك كل موقعٍ قالبًا خاصًا به. وبهذا الطريقة، لن تُفعِّل أنت (أو مدراء تلك المواقع) بالغلط القالب غير المخصص للموقع. إذا كان مستخدموك ينُشؤون مواقعهم الخاصة، فربما تريد توفير قوالب إضافية لهم، وهذا ما يمكنك فعله بتمكين تلك القوالب للشبكة (سنتحدث عن المزيد من هذا الموضوع قريبًا). يمكنك أن ترى قالبين مثبتين على الشبكة لكن غير مفعلين في لقطة الشاشة الآتية. القوالب المُفعّلة لكامل الشبكة لا تظهر هنا، حيث لا حاجة إلى تفعليها للمواقع كلًا على حدة لأنها مفعلة من قبل. لتفعيل قالب لموقعٍ ما، اضغط على رابط Enable (تفعيل) الظاهر تحت اسمه. ثم ستظهر في صفحة القوالب في لوحة تحكم الموقع. إعدادات الموقع يمنحك لسان Settings (إعدادات) وصولًا إلى المزيد من إعدادات الضبط للمواقع الموجودة على شبكتك: لديك هنا وصولٌ لجميع الخيارات المتعلقة بالموقع، أميل إلى تفادي التعديل على هذه الصفحة وأفضِّل استخدام لوحة تحكم مدير الموقع لكل موقع، لكن من الجيد وجود هذه الصفحة إذا تعذر الوصول إلى لوحة التحكم الخاصة بالموقع لسببٍ من الأسباب (مثلًا، النطاق لا يعمل) وتريد أن تُعدِّل في الإعدادات لكي يعمل الموقع مجددًا. إذا كنتَ تنوي تعديل الإعدادات الموجودة في هذه الصفحة، فاحذر أن تُعيد الكتابة فوق الإعدادات التي أجراها مدير الموقع. ترجمة –وبتصرّف– للمقال WordPress Multisite Masterclass: Activation and Configuration لصاحبته Rachel McCollin.
  19. أهلًا بك مجددًا في الدرس الثاني من سلسلة تعلم الاستفادة من ميزة تعدد المواقع في ووردبريس. شرحنا في الدرس السابق بعض الأمور الأساسية التي عليك أن تضعها بعين الاعتبار عند التعامل مع شبكة من المواقع، وسنكمل ذلك في درسنا هذا. النطاقات اختلافٌ آخر في الشبكة متعددة المواقع هو النطاقات (domains) المستخدمة لكل موقع على الشبكة، إذا يملك كلٌ منها رابطًا خاصًا به، وإما أن يكون ذلك عبر نطاق فرعي (subdomain) أو عبر وضع الموقع في مجلد فرعي ضمن نطاق الموقع الرئيسي. حيث لدينا الحالتين الآتيتين: استخدام النطاقات الفرعية يعني أنَّ لكل موقع رابط URL مثل http://site1.yournetwork.com، إذا كنت تخطط للسماح للآخرين بإنشاء مواقعهم الخاصة، فعليك أن تتأكد أنَّك تستطيع استخدام النطاقات الفرعية غير المحدودة في نطاقك الأساسي (عليك أن تراجع ذلك مع استضافتك). استخدام المجلدات الفرعية يعني أنَّ لكل موقع رابط URL مثل http://yournetwork.com/site1، لا يمكنك انتقاء هذا الخيار على موقعٍ موجودٍ مسبقًا والذي تحاول تحويله إلى شبكة لأن ذلك قد يسبب مشاكل مع روابط URL الموجودة مسبقًا في موقعك. إذا كنتَ تُفعِّل ميزة تعدد المواقع على موقعٍ محلي (أي موقعٍ يعمل على حاسوبك المحلي، راجع مقالة كيفية تنصيب ووردبريس محليا باستخدام MAMP)، فلن يُسمَح لك باستخدام النطاقات الفرعية عندما تحاول ضبط الشبكة، وإنما عليك استخدام المجلدات الفرعية. إذا كنتَ تُفعِّل ميزة تعدد المواقع على تثبيت ووردبريس قديم نسبيًا، فلن يُسمَح لك باستخدام المجلدات الفرعية، وعليك حينها أن تستعمل النطاقات الفرعية؛ هذا لأن موقعك قد يحتوي على منشورات أو صفحات ذات روابط قد تتعارض مع روابط المجلدات الفرعية للمواقع الجديدة التي ستُنشَأ على الشبكة. لكي تتفادى المشاكل في الروابط، فستتغير بنية الروابط الدائمة (paramlinks) في موقعك الرئيسي عندما تُفعِّل الشبكة متعددة المواقع الموجودة ضمن مجلدات فرعية؛ فلو كان لديك منشورٌ في http://yoursite.com/name-of-my-post فسيُنقَل إلى http://yoursite.com/blog/name-of-my-post. أُكرِّر أنَّ الأمر يحدث لمنع حدوث تضارب بين أسماء المنشورات والمجلدات الفرعية التي تُمثِّل المواقع الأخرى في شبكتك. سنشرح النطاقات وكيفية ربطها بالتفصيل في درسٍ لاحقٍ في هذه السلسلة. حالات استخدام شبكة متعددة المواقع يمكن توظيف الشبكات متعددة المواقع لعدِّة أغراض، بعضها مفيدٌ للمجتمع، وبعضها مفيدٌ للشركات. وهي تتضمن: إدارة مواقعك الخاصة استضافة المواقع للعملاء استضافة أكثر من موقع لمنظمة واحدة دفع الآخرين لإنشاء مواقعهم دعم المجتمع لننظر إلى كل حالة على حدة. إدارة مواقعك الخاصة أتحدث إلى الكثير من مستخدمي ومطوري ووردبريس الذي يملكون عددًا كبيرًا من المواقع. ربما يدعمون فيها المشاريع الشخصية، أو ربما لأغراض تجارية أخرى، أو ربما لكي يستعرضوا تقنياتٍ مختلفة. مثلًا، شبكة المواقع الموجودة في rachelmccollin.co.uk تحتوي على عشرات المواقع التي أنشأتها لغرض استعراض مختلف التقنيات التي أكتب عنها في الدروس والكتب والمقالات. أغلبية تلك المواقع صغيرة وفيها إضافة أو قالب واحد مفعل الذي يستعمل الشيفرات الموجودة في الدروس. والأخرى كبيرة لتضم كتابًا كاملًا. إبقاء هذه المواقع مرتبطةً بشبكة يساعدني كثيرًا عندما أحتاج إلى تحديث إضافة أو قالب أو حتى ترقية نسخة ووردبريس نفسها. الكثير من القوالب التي أستعملها هي «قوالب أبناء» (child themes) للقالب الافتراضي في ووردبريس (Twenty Sixteen)، ولا أحتاج سوى إلى تخزين وتحديث نسخة واحدة من قالب Twenty Sixteen. إذا كنت من الأشخاص الذين يحبون إنشاء مواقع شخصية، فميزة تعدد المواقع ستساعدك كثيرًا في إدارتها. وتستطيع أيضًا أن تستعمل نطاقًا مختلفًا لكل موقع، وحينها لن يعلم أحدٌ أنَّك تستعمل شبكةً من المواقع. استضافة المواقع للعملاء استعمال ميزة تعدد المواقع لاستضافة مواقع العملاء هي طريقةٌ ذات كفاءةٍ عالية وتستعمل مساحةً تخزينيةً أقل على الخادوم. تطور الشركة التي أعمل بها مواقع للشركات الصغيرة وتستضيفها. بالطبع لا نستضيف كل مواقع عملائنا في شبكةٍ واحدة، لأن الأمر سيصبح فوضويًا قليلًا؛ لكن نسبةً لا بأس بها من المواقع التي نستضيفها هي مواقع صغيرة فيها أقل من 20 صفحة. وجميع تلك المواقع تستعمل «قوالب أبناء» لنفس القالب التطويري (الذي برمجتُه بنفسي)، فلو أردتُ أن أُحدِّث القالب التطويري فسأحتاج إلى تحديثه مرةً واحدةً على الشبكة، والأمر سيانٌ للإضافات. هذا يجعل عملية التحديث أسهل وأسرع وأكثر كفاءة. لا تنسَ أنَّه بالإمكان استخدام نطاقات مختلفة لكل موقع، وبهذا لن يعلم أحدٌ أنَّ كل تلك المواقع مستضافةٌ على شبكةٍ واحدة. باستخدام إضافات مثل Support System و Snapshot، أتمكن من استخدام الشبكة متعددة المواقع لتحسين جودة الخدمة التي أقدمها لعملائي. إضافة Snapshot هي إضافة متوافقة مع الشبكات متعددة المواقع التي تسمح لي بضبط كل خيارات النسخ الاحتياطي من مكانٍ واحد؛ وإضافة Support System تسمح لي باستقبال والاستجابة إلى طلبات الدعم من العملاء. إذا كنتَ تستعمل شبكةً، فعليك توخي الحذر كما لو كنت تُجري تحديثًا، ولا تنسَ أن تختبر الإضافات والتحديثات على موقعٍ تطويري أولًا! أملك نسخةً محليةً من شبكتي، التي أُفعِّل فيها أيّة تحديثات لأختبرها قبل أن أُفعِّلها على الشبكة الإنتاجية. هذه المواقع للعملاء، لذا توخى الحذر معها! استضافة أكثر من موقع لمنظمة واحدة تخيل أنَّك مدير مواقع الويب لمنظمة كبيرة تعمل في بلدانٍ كثيرة. ربما لديك مواقع منفصلة لكل دولة من الدول، تخيل كم سيؤلمك رأسك جراء إدارتها جميعًا! أو ربما لديك عدِّة مواقع بنفس اللغة لكن لمختلف الأقسام. الشبكة متعددة المواقع تجعل من السهل الحصول على مواقع منفصلة لكن يمكن إدارتها من مكانٍ وحيد. إذا كانت جميع مواقعك تستعمل «قالب ابن» لقالب رئيسي وحيد فعليك أن تخزنه وتُحدِّثه بمكان واحد فقط. وإذا كنت تستعمل نفس الإضافات في كل مواقعك، فستستفيد من الشبكة متعددة المواقع خير استفادة؛ وكما أنَّك تستطيع أن تنشر نفس المحتوى في أكثر من موقع، ويمكنك إنشاء مجتمع من مستخدمي منظمتك، وتستطيع أن تُنشِئ موقعًا يُستعمَل كقالب لكي تستفيد منه عندما تُنشِئ موقعًا جديدًا لفرعٍ جديدٍ في دولةٍ ما أو لقسمٍ ما. جني الأموال عبر الشبكة متعددة المواقع قد تستفيد من الشبكة متعددة المواقع لدعم شركتك وجني الأموال. إذا كنت قد ضبطتَ شبكتك لكي تسمح للآخرين بإنشاء مواقعهم، فهنالك مختلف الأنواع لتقاضي الأموال عبر الشبكة، وهذا يتضمن: الدفع مقابل إنشاء موقع الدفع مقابل ميزات مُحسَّنة الدفع مقابل إضافات أو قوالب معينة الدفع للدعم الفني والخدمات الإضافية الدفع لقاء الحصول على نطاق منفصل نحن نستعمل بعض تلك الطرق في موقع Edublogs؛ إذ أنَّ إنشاء الموقع مجانيٌ، لكن إن كنت تريد ميزاتٍ متقدمة وإضافات أخرى، فعليك أن تدفع لقاء ذلك. موقع WordPress.com يعمل بشكلٍ مشابه. دعم المجتمع ليس الغرض من الشبكة متعددة المواقع هو جني الأموال فحسب، وإنما هي أداةٌ رائعة لدعم المجتمعات، حيث تسمح بإنشاء شبكة من المواقع التي يديرها المستخدمون الذين يشكلون جزءًا من المجتمع. وقد يكون هذا ناديًا أو مجموعةً من الأشخاص ذوي الاهتمامات المشتركة. لا تسمح الشبكة المتعددة المواقع لأعضاء مجتمع بإنشاء المواقع فقط، لكنها تسمح لهم أيضًا بالتواصل مع بعضهم بعضًا، بالإضافة إلى متابعة منشوراتهم، ومشاركة المحتوى. وهي توفر موردًا ممتازًا للمعلومات لأعضاء مجتمعك وتجعلهم يبقون دومًا على اتصال. للشبكات متعددة المواقع الكثير من الاستخدامات والميزات بعد أن قرأت أول درسين من هذه السلسلة، فيجب أن تتكون لديك صورة عن أهمية ومدى فائدة خاصية الشبكات متعددة المواقع في ووردبريس. سنشرح في الأجزاء القادمة من هذه السلسلة بعض الجوانب العملية لإنشاء وإدارة شبكة مواقع ووردبريس؛ بما في ذلك طريقة تفعيل ميزة تعدد المواقع وضبط الشبكة، وتفعيل وتحسين طريقة إنشاء المواقع من قِبل المستخدمين، وربط النطاقات مع مواقع في الشبكة، وطريقة إنشاء مجتمع، وإدارة شبكتك. ترجمة –وبتصرّف– للمقال WordPress Multisite Masterclass: Getting Started لصاحبته Rachel McCollin.
  20. تعلمنا في الدرسين السابقين كيف نوصِّف الأشخاص والمنظمات، وسنتناول في هذا الدرس الأحداث والمراجعات توصيف الأحداث تحدث بعض المناسبات في أوقاتٍ معيّنة، ألن يكون من الجميل أن تستطيع إخبار محركات البحث متى ستقع تلك المناسبات تحديدًا؟ هنالك طريقةٌ لفعل هذا في HTML5. لنبدأ بإلقاء نظرة على الجدول الزمني الخاص بالمحاضرات والكلمات التي سألقيها. <article> <h1>Google Developer Day 2009</h1> <img width="300" height="200" src="http://diveintohtml5.org/examples/gdd-2009-prague-pilgrim.jpg" alt="[Mark Pilgrim at podium]"> <p> Google Developer Days are a chance to learn about Google developer products from the engineers who built them. This one-day conference includes seminars and “office hours” on web technologies like Google Maps, OpenSocial, Android, AJAX APIs, Chrome, and Google Web Toolkit. </p> <p> <time datetime="2009-11-06T08:30+01:00">2009 November 6, 8:30</time> – <time datetime="2009-11-06T20:30+01:00">20:30</time> </p> <p> Congress Center<br> 5th května 65<br> 140 21 Praha 4<br> Czech Republic </p> <p><a href="http://code.google.com/intl/cs/events/developerday/2009/home.html">GDD/Prague home page</a></p> </article> جميع المعلومات التي تخص الحدث موجودةٌ في عنصر <article>، وهو المكان الذي نريد وضع خاصيتي itemtype و itemscope فيه. <article itemscope itemtype="http://schema.org/Event"> رابط URL لنوع الاصطلاحات Event هو http://schema.org/Event، الذي يحتوي أيضًا على جدولٍ يصف خاصيات هذه النوع من الاصطلاحات؛ التي ذكرتُ بعضها في هذا الجدول. الخاصية الشرح name اسم الحدث url رابط لصفحة تفاصيل الحدث location الموقع الذي سيُجرى فيه الحدث الذي يمكن أن يُمثَّل بنوع الاصطلاحات PostalAddress أو Place description وصفٌ قصيرٌ للحدث startDate تاريخ بدء فعاليات الحدث بصيغة ISO endDate تاريخ انتهاء فعاليات الحدث بصيغة ISO duration المدة الزمنية لفعاليات الحدث بصيغة ISO image صورة تعبيرية متعلقة بالحدث اسم الحدث موجودٌ في عنصر <h1>، ووفقًا للنموذج الهيكلي للبيانات الوصفية في HTML5، عنصر <h1> ليس له معالجةٌ خاصةٌ، وستكون قيمة خاصية البيانات الوصفية هي المحتوى النصي للعنصر <h1>، لذا كل ما نحتاج له هو إضافة الخاصية itemprop لكي نُصرِّح أنَّ هذا العنصر يحتوي على اسم الحدث. <h1 itemprop="name">Google Developer Day 2009</h1 نقول بالعربية: «اسم هذا الحدث هو Google Developer Day 2009». يحتوي الحدث على صورة، التي يمكن توصيفها باستخدام الخاصية image، وكما تتوقع، تُعرَض الصورةُ عبر عنصر <img>، وكما في خاصية image في نوع الاصطلاحات Person، الصورة في نوع الاصطلاحات Event هي رابط URL، ولأن النموذج الهيكلي للبيانات الوصفية يقول أنَّ قيمة الخاصية الموجودة في العنصر <img> هي قيمة خاصية src، فكل ما علينا فعله هو إضافة الخاصية itemprop إلى العنصر <img>. <img itemprop="image" width="300" height="200" src="http://diveintohtml5.org/examples/gdd-2009-prague-pilgrim.jpg" alt="[Mark Pilgrim at podium]"> نقول بالعربية: «إحدى الصور المتعلقة بهذا الحدث موجودٌ في رابط http://diveintohtml5.org/examples/gdd-2009-prague-pilgrim.jpg» يأتي بعد الصورة وصفٌ مختصرٌ للحدث، وهو فقرةٌ نصيةٌ من الكلام العادي. <p itemprop="description">Google Developer Days are a chance to learn about Google developer products from the engineers who built them. This one-day conference includes seminars and “office hours” on web technologies like Google Maps, OpenSocial, Android, AJAX APIs, Chrome, and Google Web Toolkit.</p> المعلومة التي تلي الوصف جديدةٌ علينا. تقع الأحداث عمومًا في تواريخ مُحدَّدة وتبدأ وتنتهي في أوقاتٍ معيّنة. يجب أن نضع الأوقات والتواريخ في HTML5 في عنصر <time>، وهذا ما فعلناه. لذا سيُصبِح السؤال الآن: كيف سنتمكن من إضافة خاصيات البيانات الوصفية إلى عناصر <time> السابقة؟ بالنظر مرةً أخرى إلى النموذج الهيكلي للبيانات الوصفية في HTML، سنلاحظ أنَّ هنالك معالجةٌ خاصةٌ للعنصر <time>. فقيمة خاصية البيانات الوصفية هي قيمة خاصية datetime في العنصر <time>. لكن مهلًا، أليست الصيغة المعيارية لخاصيات البيانات الوصفية startDate و endDate هي ISO، مَثَلُهَا كمَثَلِ خاصية datetime في العنصر <time>. وأكرر مرةً أخرى كيف تتوافق ةتتناغم البُنى الهيكلية من أساس HTML مع البُنى الهيكلية التي نُضيفها من نوع الاصطلاحات الخاص بالبيانات الوصفية. عملية توصيف تواريخ بداية ونهاية الحدث عبر البيانات الوصفية سهلةٌ وتتم كالآتي: استخدام HTML استخدامًا صحيحًا في المقام الأول (باستخدام عناصر <time> للوقت والتاريخ)، ومن ثم إضافة خاصية itemprop <p> <time itemprop="startDate" datetime="2009-11-06T08:30+01:00">2009 November 6, 8:30</time> &ndash; <time itemprop="endDate" datetime="2009-11-06T20:30+01:00">20:30</time> </p> بالعربية: «هذا الحديث يبدأ في November 6, 2009 الساعة 8:30 صباحًا، ويستمر إلى November 6, 2009 الساعة 20:30 (بتوقيت مدينة براغ المحلي، GMT+1)». ثم ستأتي خاصية location، التي تقول عنها صفحة تعريف نوع الاصطلاحات Event أنها قد تكون من نوع PostalAddress أو Place. وفي حالتنا، سيُقام الحدث في مكانٍ متخصصٍ بالمؤتمرات، وهو Congress Center في مدينة براغ. وإمكانية توصيفه على أنَّه «مكان» (Place) ستسمح لنا بتضمين اسمه بالإضافة إلى عنوانه. لنبدأ بالتصريح أنَّ العنصر <p> الذي يحتوي على العنوان هو خاصية location لنوع الاصطلاحات Event، وهذا العنصر يحتوي على خاصياتٍ تابعةٍ لنوع الاصطلاحات http://schema.org/Place. <p itemprop="location" itemscope itemtype="http://schema.org/Place"> ثم سنُعرِّف اسم المكان بوضعه في عنصر وإضافة الخاصية itemprop إليه. <span itemprop="name">Congress Center</span><br> وبسبب قواعد المجالات (scoping rules) في البيانات الوصفية، خاصية itemprop=”name”‎ السابقة تُعرِّف اسم المكان في نوع الاصطلاحات Place وليس في نوع الاصطلاحات Event. وذلك لأنَّ العنصر <p> السابق قد صرَّح عن بداية خاصيات المكان (Place)، ولمّا يُغلَق عنصر <p> بعدُ عبر وسم <‎/p>. أيّة خاصيات نُعرِّفها والتي تَتبَع للبياناتِ الوصفيةِ تكونُ من خصائصِ آخرِ نوعِ اصطلاحاتٍ دخلَ المجالَ. يمكن أن تتداخل أنواع الاصطلاحات مثل المكدس (stack). لم نحذف إلى الآن آخر عنصر من المكدس، وهذا يعني أننا ما زلنا ضمن مجال نوع الاصطلاحات Place. في الحقيقة، سيلزمنا إضافة نوع اصطلاحات ثالث إلى المكدس: عنوانٌ (Address) للمكان (Place) الذي سيُقام به الحدث (Event). <span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress"> مرةً أخرى، علينا أن نضع كل جزء من العنوان كخاصية بيانات وصفية مستقلة، لذلك علينا أن نُضيف عددًا من عناصر <span> لكي نضع خاصيات itemprop فيها (إذا رأيتني أشرح الأمور بسرعة هنا، فأنصحك بالعودة إلى الأقسام السابقة وقراءة كيفية توصيف العنوان للأفراد وكيفية توصيف العنوان للمنظمات). <span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress"> <span itemprop="streetAddress">5th května 65</span><br> <span itemprop="postalCode">140 21</span> <span itemprop="addressLocality">Praha 4</span><br> <span itemprop="addressCountry">Czech Republic</span> </span> لا توجد خاصيات إضافية للعنوان، لذا لنغلق عنصر <span> الذي بدأ المجال الخاص بنوع الاصطلاحات Address. </span> علينا الآن إضافة الخاصية geo لتمثيل الموقع الفيزيائي للحدث. سنستخدم نفس نوع الاصطلاحات (GeoCoordinates) الذي استعملناه في القسم السابق لتحديد موقع المنظمة. سنحتاج إلى عنصر <span> لكي يعمل كحاوية، والذي يملك الخاصتين itemtype و itemscope. وضمن العنصر <span> سنضع عنصرَي <meta>، واحدٌ لتحديد إحداثيات العرض (الخاصية latitude) والآخر لتحديد إحداثيات الطول (الخاصية longitude). <span itemprop="geo" itemscope itemtype="http://schema.org/GeoCoordinates"> <meta itemprop="latitude" content="50.047893" /> <meta itemprop="longitude" content="14.4491" /> </span> بعد إغلاقنا لعنصر <span> الذي يحوي خاصيات الموقع الجغرافي، سنعود إلى مجال Place، لكن لم تعد هنالك أيّة خاصيات لإضافتها إلى Place، لذا سنُغلِق العنصر <p> الذي بدأ مجال نوع الاصطلاحات Place، وبهذا سنعود إلى تعريف الخاصيات التابعة لنوع الاصطلاحات Event. </p> وأخيرًا وليس آخرًا، بقيت الخاصية url، التي يجب أن تكون مألوفةً لك. تُضاف روابط URL المتعلقة بالأحداث بنفس طريقة إضافة الروابط للأشخاص وطريقة إضافة روابط للمنظمات. إذا كنتَ تستعمل HTML استعمالًا صحيحًا (أي وضع الروابط في عنصر <a href>)، فآلية التصريح أنَّ الروابطَ تُمثِّلُ خاصيةَ url في البيانات الوصفية بسيطةٌ جدًا وذلك بإضافة خاصية itemprop إلى تلك العناصر فقط. <p> <a itemprop="url" href="http://code.google.com/intl/cs/events/developerday/2009/home.html"> GDD/Prague home page </a> </p> </article> يجدر بالذكر أنَّك تستطيع توصيف أكثر من حدث في نفس الصفحة. المقتطفات المنسقة من جديد! وفقًا لأداة اختبار البيانات المنظمة من Google، المعلومات التي تحصل عليها عناكب محرك البحث من صفحة الحدث السابقة هي: كما لاحظتَ، جميع البيانات التي وصَّفناها موجودةٌ هنا. لاحظ كيف تُظهِر أداة اختبار البيانات الهيكلية تشعّب أنواع الاصطلاحات؛ هذا التمثيل الرسومي سيساعدك كثيرًا على تخيّل الوضع. هذا رسمٌ توضيحيٌ للطريقة المتوقعة لتمثيل الصفحة في نتائج بحث Google (أكرر مرةً أخرى أنَّ هذا مجرد مثال، فقد يُغيّر Google طريقة تنسيق نتائج البحث في أيّ وقت، ولا توجد هنالك ضمانة أنَّ Google ستُفسِّر البيانات الوصفية في صفحتك من الأساس!). بعد عنوان الصفحة والمُقتطف المولَّد تلقائيًا، سيبدأ محرك Google باستعمال البيانات الوصفية التي أضفناها إلى الصفحة لعرض جدول المحتويات. لاحظ طريقة تنسيق التاريخ «Fri, Nov 6». لم ترد هذه السلسلة النصية في أيّ مكانٍ في عناصر HTML أو خاصيات البيانات الوصفية. لكننا استخدمنا سلسلتين نصيتين هما التاريخ بصيغةٍ معياريةٍ (‎2009-11-06T08:30+01:00 و ‎2009-11-06T20:30+01:00). أخذ Google هاذين التاريخين وعَرِفَ أنَّهما في نفس اليوم، وقرر عرض تاريخٍ وحيدٍ بصيغةٍ قراءتها أسهل. انظر الآن إلى العنوان الفيزيائي. اختار Google أن يعرض اسم المكان + البلدة (locality) + الدولة، لكنه لم يعرض عنوان الشارع المُفصَّل. أصبح هذا ممكنًا لأننا قسّمنا العنوان إلى خمسِ خاصياتٍ مستقلةً –streetAddress وaddressLocality و addressRegion و postalCode و addressCountry– استفاد Google من هذا لعرض عنوانٍ مختصرٍ للمكان. قد يختار مستهلكونَ آخرونَ للمعلوماتِ التي توفرُها عبر البيانات الوصفية استخدامها بطرائقَ مختلفةٍ، إذ سيقررون ما الذي سيَعرضوه وما الذي لن يعرضوه. لا يوجد خيارٌ صائب وخيارٌ خاطئ هنا. عليكَ أن توفرَ أكبرَ قدرٍ من البيانات الهيكلية، وبأكبر دقةٍ ممكنةٍ، واترك الباقي على الآخرين ليفسروه كيفما يشاؤون. توصيف المراجعات هذا مثالٌ آخر عن كيفية جعل الويب (وربما نتائج البحث) أفضل عبر استخدام البيانات الوصفية: مراجعات (reviews) الشركات والمنتجات. هذه مراجعةٌ قصيرةٌ كتبتُها لأحد مطاعم البيتزا المُفضَّلة لدي (بالمناسبة، هذا المطعم حقيقي). لننظر أولًا إلى الشيفرة الأصلية قبل إضافة البيانات الوصفية: <article> <h1>Anna’s Pizzeria</h1> <p>★★★★☆ (4 stars out of 5)</p> <p>New York-style pizza right in historic downtown Apex</p> <p> Food is top-notch. Atmosphere is just right for a “neighborhood pizza joint.” The restaurant itself is a bit cramped; if you’re overweight, you may have difficulty getting in and out of your seat and navigating between other tables. Used to give free garlic knots when you sat down; now they give you plain bread and you have to pay for the good stuff. Overall, it’s a winner. </p> <p> 100 North Salem Street<br> Apex, NC 27502<br> USA </p> <p>— reviewed by Mark Pilgrim, last updated March 31, 2010</p> </article> هذه المراجعة موجودةٌ ضمن عنصر <article>، الذي علينا وضع خاصيتي itemtype و itemscope فيه. رابط URL لمجال أسماء نوع الاصطلاحات الذي سنستعمل هو http://schema.org/Review. <article itemscope itemtype="http://schema.org/Review"> ما هي الخاصيات الموجودة في نوع الاصطلاحات Review؟ أنا ممتنٌ لسؤالك. الخاصية الشرح itemReviewed اسم العنصر الذي ستتم مراجعته. يمكن أن يكون منتجًا أو خدمةً أو شركةً… إلخ. reviewRating التقييم الذي أعطاه المُراجِع للعنصر. يُمثَّل بنوع الاصطلاحات Rating ‏(http://schema.org/Rating) author اسم الشخص الذي كتب المراجعة datePublished تاريخ نشر المراجعة بصيغة ISO name عنوان مختصر للمراجعة reviewBody الوصف الذي كتبه المُراجِع للعنصر أولُ خاصيةٍ بسيطةٌ: itemReviewed هي نصٌ عاديٌ، وقيمتها موجودةٌ في عنصر <h1>، لذا سنضع تلك الخاصية في ذاك العنصر. <h1 itemprop="itemReviewed">Anna’s Pizzeria</h1> سأتجاوز حاليًا قسم التقييم وسأعود إليه لاحقًا في النهاية. الخاصيتان التاليتان سهلتان وبسيطتان. خاصية name هي عنوانٌ مختصرٌ للمراجعة، وخاصية reviewBody هي النص الذي كتبه المراجع لوصف العنصر المُراجَع. <p itemprop="name">New York-style pizza right in historic downtown Apex</p> <p itemprop="reviewBody"> Food is top-notch. Atmosphere is just right for a “neighborhood pizza joint.” The restaurant itself is a bit cramped; if you’re overweight, you may have difficulty getting in and out of your seat and navigating between other tables. Used to give free garlic knots when you sat down; now they give you plain bread and you have to pay for the good stuff. Overall, it’s a winner. </p> يجب أن يكون توصيف العنوان وإحداثيات الموقع الجغرافي مألوفًا لديك الآن (إذا لم تكن تتابع معنا منذ بداية هذه الدروس، فراجع آلية توصيف عنوان شخص، وآلية توصيف عنوان منظمة، وآلية توصيف إحداثيات الموقع الجغرافي من الدروس السابقة). <p itemprop="contentLocation" itemscope itemtype="http://schema.org/Place"> <span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress"> <span itemprop="streetAddress">100 North Salem Street</span><br> <span itemprop="addressLocality">Apex</span>, <span itemprop="addressRegion">NC</span> <span itemprop="postalCode">27502</span><br> <span itemprop="addressCountry">USA</span> </span> <span itemprop="geo" itemscope itemtype="http://schema.org/GeoCoordinates"> <meta itemprop="latitude" content="50.047893" /> <meta itemprop="longitude" content="14.4491" /> </span> </p> في آخر سطرٍ مشكلةٌ شائعة: يحتوي على معلومتين في عنصرٍ وحيدٍ. اسم الشخص الذي كتب المراجعة هو Mark Pilgrim، وتاريخ المراجعة هو March 31, 2010. كيف نستطيع توصيف هاتين الخاصيتين المستقلتين؟ ضعهما في عنصرَين منفصلين وضع خاصية itemprop في كلٍ عنصرٍ. يجدر بنا في هذا المثال أن نضع التاريخ في عنصر <time>، لكي يوفر لنا طريقةً سليمةً لوضع خاصية itemprop المناسبة. لكن اسم المُراجِع يمكن أن يُحتوى في عنصرٍ ليس له قيمةٌ دلاليةٌ مثل <span>. <p>— <span itemprop="author">Mark Pilgrim</span>, last updated <time itemprop="datePublished" datetime="2010-03-31"> March 31, 2010 </time> </p> </article> حسنًا، لنتحدث عن التقييمات. أصعب جزء في توصيف المراجعة هو التقييم. افتراضيًا، التقييمات في نوع الاصطلاحات Rating تكون على مقياس من 1 إلى 5، حيث 1 هو «سيء جدًا» و5 هو «رائع». لكنك ما تزال قادرًا على توصيف التقييم إذا كنت تستخدم مقياسًا مختلفًا، لكن دعنا نناقش المقياس الافتراضي أولًا. <p>★★★★☆ (<span itemprop="reviewRating">4</span> stars out of 5)</p> إذا كنتَ تستعمل مقياسًا افتراضيًا من 1 إلى 5، فالخاصية الوحيدة التي عليك توصيفها هي التقييم نفسه (4 في مثالنا). لكن ماذا لو كنتَ تستعمل مقياسًا مختلفًا؟ كل ما عليك فعله هو التصريح عن حدود المقياس الذي تستعمل. على سبيل المثال، إذا أردت أن تستعمل مقياسًا من 0 إلى 10، فما يزال عليك التصريح عن خاصية itemprop=”rating”‎ لكن بدلًا من إعطاء قيمة التقييم مباشرةً، سيتوجب عليك استخدام نوع http://schema.org/Rating لتعيين أقل قيمة وأعلى قيمة في مقياسك المُخصَّص بالإضافة إلى تحديد قيمةٍ للتقييم الفعلي ضمن ذاك المقياس. <p itemprop="reviewRating" itemscope itemtype="http://schema.org/Rating"> ★★★★★★★★★☆ (<span itemprop="ratingValue">9</span> on a scale of <span itemprop="worstRating">0</span> to <span itemprop="bestRating">10</span>) </p> بالعربية: «هذا المنتج الذي أكتب مراجعةً عنه يملك تقييمًا قيمته 9 في مقياسٍ من 0 إلى 10». هل ذكرتُ لك أنَّ البيانات الوصفية المُضافة للمراجعات قد تؤثر على نتائج البحث؟ هذه هي البيانات التي تستيطع أداة اختبار البيانات المنظّمة استخلاصها من مراجعتنا: وهذه صورةٌ توضيحيةٌ لكيف يمكن أن تبدو المراجعة عند عرضها في نتائج البحث: أليس هذا مُبهرًا؟ مصادر إضافية مصادر عن البيانات الوصفية (Microdata): مواصفة Microdata في HTML5 صفحة Microdata في ويكيبيديا مصادر عن المقتطفات المنسقة: صفحة Rich Snippets أداة اختبار البيانات المنظمة موقع schema.org الذي يحتوي معلوماتٍ عن أنواع الاصطلاحات المختلفة التي ذكرناها في هذا دروس هذه السلسلة. ترجمة -وبتصرّف- لفصل «Microdata» من كتاب Dive Into HTML5 لمؤلفه Mark Pilgrim. اقرأ أيضًا المقال السابق: توصيف المنظمات/الشركات باستخدام microdata في HTML5 النسخة العربية الكاملة من كتاب نحو فهم أعمق لتقنيات HTML5
  21. البيانات الوصفية ليست محدودةً لنوع اصطلاحاتٍ وحيد. صفحة «About» التي أنشأناها في الدرس السابق جيدة، لكن من المرجح أنَّ لديك صفحةً واحدةً اسمها «About»، ولكنك متعطشٌ للمزيد؟ لنتعلم كيف نوصِّف المنظمات والشركات. هذه نموذجٌ لصفحة شركةٍ ما، لنلقِ نظرةً على شيفرة HTML دون البيانات الوصفية. <article> <h1>Google, Inc.</h1> <p> 1600 Amphitheatre Parkway<br> Mountain View, CA 94043<br> USA </p> <p>650-253-0000</p> <p><a href="http://www.google.com/">Google.com</a></p> </article> وصفٌ قصيرٌ ومنظَّم، فجميع المعلومات حول هذه المنظمة موجودةٌ ضمن عنصر <article>، فلنبدأ هناك. <article itemscope itemtype="http://schema.org/Organization"> وكما فعلنا عند توصيف الأشخاص في الدرس السابق، سنحتاج إلى ضبط الخاصيتين itemscope و itemtype في العنصر الحاوي لبقية العناصر، وهو في حالتنا العنصر <article>. خاصية itemtype تُصرِّح ما هو نوع الاصطلاحات التي تستعملها (في هذه الحالة http://schema.org/Organization)، وخاصية itemscope تُصرِّح أنَّ كل الخاصيات التي تضبطها للعناصر الأبناء للعنصر الحالي ترتبط بنوع الاصطلاحات هذا. إذًا، ماذا يوجد في نوع الاصطلاحات Organization؟ بضع خاصياتٍ بسيطة، التي يكون بعضها مألوفًا لديك. الخاصية الشرح name اسم المنظمة (على سبيل المثال: «Initech») url رابط URL لصفحة ويب، مثل الصفحة الرئيسية للمنظمة address العنوان الفيزيائي للمنظمة، يمكن أن يحتوي على خاصيات أخرى مثل streetAddress وaddressLocality و addressRegion و postalCode و addressCountry telephone رقم هاتف المنظمة geo تحديد الإحداثيات الجغرافية لموقع المنظمة، ويملك خاصيتين دائمًا: latitude و longitude أول قطعة من الشيفرات في عنصر <article> هي <h1>. يحتوي عنصر <h1> على اسم الشركة، ولهذا سأضيف خاصية itemprop="name"‎ إليه مباشرةً. <h1 itemprop="name">Google, Inc.</h1> ووفقًا للنموذج الهيكلي للبيانات الوصفية في HTML5، عناصر <h1> ليس لها معالجة خاصة، وستكون قيمة خاصية البيانات الوصفية هي المحتوى النصي للعنصر. أي أننا قلنا بالعربية: «اسم المنظمة هو "Google, inc.‎"». المعلومة التالية التي نريد توصيفها هي العنوان. توصيف عنوان المنظمة مماثل تمامًا لتوصيف عنوان شخصٍ ما. أضف أولًا خاصية itemprop="address"‎ إلى العنصر الذي يحتوي على العنوان (العنصر <p> في هذه الحالة). وهذا يُصرِّح أنَّ هذه هي خاصية address للمنظمة، لكن ماذا عن خاصيات العنوان نفسه؟ سنحتاج إلى الخاصيتين itemtype و itemscope لكي نقول أنَّ عنصر العنوان هذا له خاصياتٌ تابعة له. <p itemprop="address" itemscope itemtype="http://schema.org/PostalAddress"> في النهاية، علينا وضع كل قطعة من المعلومات في عنصر <span> لكي نتمكن من وضع الخاصية الملائمة (streetAddress وaddressLocality و addressRegion و postalCode و addressCountry) في كل عنصر من تلك العناصر. <p itemprop="address" itemscope itemtype="http://schema.org/PostalAddress"> <span itemprop="streetAddress">1600 Amphitheatre Parkway</span><br> <span itemprop="addressLocality">Mountain View</span>, <span itemprop="addressRegion">CA</span> <span itemprop="postalCode">94043</span><br> <span itemprop="addressCountry">USA</span> </p> بالعربية: «هذه المنظمة تملك عنوانًا بريديًا. اسم الشارع لذاك العنوان البريدي هو "1600 Amphitheatre Parkway"، أما البلدة (locality) فهي "Mountain View"، والإقليم (region) هو "CA"، والرمز البريدي (postal code) هو "94043"، واسم الدولة هو "USA"». الخطوة التالية هي توصيف رقم الهاتف للمنظمة، بُنيةُ أرقامِ الهواتفِ معقدةٌ بعض الشيء، والصيغة المُحدَّدة لها خاصةٌ بكل دولة (والأمر أسوأ إذا أردت الاتصال بدولةٍ أخرى). لدينا في مثالنا رقمٌ هاتفيٌ من الولايات المتحدة، وهو مكتوبٌ بصيغةٍ ملائمةٍ للاتصال من أي مكان داخل الولايات المتحدة. <p itemprop="telephone">650-253-0000</p> (في حال لم تنتبه، لقد خرج نوع الاصطلاحات Address من المجال [scope] عندما أُغلِق العنصر <p>. لقد عدنا الآن إلى تعريف الخاصيات لنوع الاصطلاحات Organization.) إذا كنت تريد وضع أكثر من رقم هاتف –ربما واحد للزبائن في الولايات المتحدة وآخر للزبائن من بقية دول العالم– فيمكنك فعل ذلك. إذ يمكن تكرار أي خاصية من خاصيات البيانات الوصفية أكثر من مرة. كل ما عليك فعله هو التأكد أنَّ لكل رقمٍ عنصرُ HTML خاصٌ به مفصولٌ عن أيّة لافتة وضعتَها له. <p> US customers: <span itemprop="telephone">650-253-0000</span><br> UK customers: <span itemprop="telephone">00 + 1* + 6502530000</span> </p> ووفقًا للنموذج الهيكلي للبيانات الوصفية في HTML5، عناصر <p> أو عناصر <span> ليس لها معالجةٌ خاصةٌ، وستكون قيمة خاصية telephone هي المحتوى النصي للعنصر. لا يحاول نوع الاصطلاحات Organization أن يُقسِّم ويُصنِّف مختلف أجزاء رقم الهاتف، فخاصية telephone هي نصٌ عاديٌ. حيث تستطيع وضع رمز المنطقة بين قوسين، أو أن تستعمل الفراغات بدلًا من الشرطات للفصل بين الأرقام. وإذا حاول العميل الذي يُفسِّر البيانات الوصفية أن يُفسِّر رقم الهاتف، فآلية ذلك عائدةٌ تمامًا إليه. لدينا بعد ذلك خاصيةٌ نألفها: url. ومثل روابط URL المتعلقة بشخصٍ ما، يمكن لروابط URL أن تتعلق بمنظمة. وقد تكون هذه الروابط هي الصفحة الرئيسية للشركة، أو صفحة التواصل، أو صفحة المنتجات، أو أيّة صفحة أخرى. بعبارةٍ أخرى، إذا كان لديك رابط URL عن أو من أو يتعلق بالمنظمة، فوصِّفه بخاصية itemprop="url"‎. <p><a itemprop="url" href="http://www.google.com/">Google.com</a></p> ووفقًا للنموذج الهيكلي للبيانات الوصفية في HTML5، عنصر <a> له معالجةٌ خاصةٌ، فقيمة خاصية البيانات الوصفية هي قيمة الخاصية href، وليس المحتوى النصي للرابط. بالعربية: «لدى هذه المنظمة رابط URL الآتي http://www.google.com/‎». لكن الخاصية لا تُحدِّد مزيدًا من المعلومات عن هذا الارتباط، ولا تُضمِّن السلسلة النصية للرابط Google.com». في النهاية، أريد الحديث عن الموقع الجغرافي. لا أقصد هنا الواجهة البرمجية لتحديد الموقع الجغرافي؛ وإنما أقصد كيفية توصيف الموقع الجغرافي للمنظمات باستخدام البيانات الوصفية. لحد هذه اللحظة، كل الأمثلة التي رأيناها ركَّزَت على توصيف البيانات المرئية. بعبارةٍ أخرى، لديك عنصر <h1> فيه اسم الشركة، لذا ستُضيف خاصية itemprop إلى عنصر <h1> لتُصرِّح أنَّ النص (المرئي) الموجود في تلك الترويسة هو اسم المنظمة. أو ربما لديك عنصر <img> الذي يُشير إلى صورةٍ ما، وتستطيع إضافة الخاصية itemprop لعنصر <img> لكي تُصرِّح أنَّ تلك الصورة (المرئية) هي صورةٌ لشخصٍ ما. أما في هذا المثال، لن تكون معلومات الموقع الجغرافي على هذا النحو؛ فلا يوجد نصٌ مرئيٌ يُعطي إحداثيات الطول والعرض (بدقة أربعة أرقام عشرية!) لموقع المنظمة. وفي الواقع، الصفحة التي نعمل عليها لا تحتوي على معلومات عن الموقع الجغرافي إطلاقًا. وحتى لو وُجِدَ رابطٌ إلى خرائط Google، لكنه لا يحتوي على إحداثيات الطول والعرض (يحتوي على معلومات مشابهة في صيغةٍ خاصةٍ بخرائط Google). لكن حتى لو افترضنا وجود رابط URL لإحدى خدمات الخرائط التي تضع إحداثيات خطوط الطول والعرض كوسائط في رابط URL، فلا توجد طريقة في البيانات الوصفية لفصل أجزاء URL عن بعضها؛ فلا تستطيع أن تقول أنَّ «أول وسيطٍ في طلبية URL هو إحداثيات الطول والوسيط الثاني هو إحداثيات العرض وبقية وسائط الطلبية غير مهمة بالنسبة إلينا». توفِّر HTML5 طريقةً لتوصيف البيانات غير المرئية للتعامل مع الحالات الخاصة مثل هذه الحالة. لا تَستعمل هذه التقنية إلا كملاذٍ أخيرٍ لك. فلو كانت هنالك طريقةٌ لعرض البيانات التي تريد توصيفها، فافعل ذلك. أرى أنَّ البيانات المخفية التي تستطيع «الآلات» قراءتها فقط «ستتعفن» بسرعة. وهذا يعني أنَّ أحدهم سيأتي عاجلًا أم آجلًا وسيُحدِّث النص المرئي الموجود في الصفحة لكنه سينسى تحديث البيانات غير المرئية. هذا يحدث بوتيرة كبيرة أكثر مما تتوقع، وأنا واثقٌ أنَّه سيحدث لك أيضًا. لكن مع هذا، هنالك وضع معلومات للموقع الجغرافي لكنه لا يريد أن تعم الفوضى في الواجهة بوجود زوجين من الأرقام غير المفهومة ذات ست خانات. الخيار الوحيد الذي أمامك هنا هو البيانات المخفية. كل ما تستطيع فعله هنا هو وضع البيانات المخفية بعد النص المرئي الذي يصفها مباشرةً، لعل ذلك يُذكِّر الشخص الذي أتى ليحدث النص المرئي لكي يُحدِّث البيانات المخفية بعده مباشرةً. في هذا المثال، أنشأنا عنصر <span> ضمن عنصر <article> الذي يحوي بقية خاصيات المنظمة، ثم وضعنا بيانات الموقع الجغرافي المخفية داخل عنصر <span> (هذه هي الطريقة التنظيمية لنوع الاصطلاحات Organization، راجع صفحة http://schema.org/Organization لمزيدٍ من المعلومات). <span itemprop="areaServed" itemscope itemtype="http://schema.org/Place"> <span itemprop="geo" itemscope itemtype="http://schema.org/GeoCoordinates"> <meta itemprop="latitude" content="37.4149" /> <meta itemprop="longitude" content="-122.078" /> </span> </span> </article> معلومات الموقع الجغرافي مُعرَّفةٌ في نوع الاصطلاحات الخاص بها، مثل «عنوان» (Address) الشخص أو المنظمة، وبالتالي، سيحتاج عنصر <span> إلى ثلاث خاصيات: itemprop="geo"‎ يقول أنَّ هذا العنصر يُمثِّل خاصية geo للمنظمة التي يتبع لها itemtype="http://schema.org/GeoCoordinates"‎ يُحدِّد أيُّ نوعِ اصطلاحاتٍ ستخضع له خاصيات هذا العنصر itemscope يقول أنَّ هذا العنصر هو عنصرٌ حاوٍ يملك نوع اصطلاحات خاص به (مُحدَّدٌ في خاصية itemtype). جميع الخاصيات الموجودة ضمن هذا العنصر هي خاصياتٌ لنوع الاصطلاحات http://schema.org/GeoCoordinates، وليس لنوع الاصطلاحات للعنصر الرئيسي http://schema.org/Organization السؤال المهم في هذا المثال هو: «كيف تستطيع توصيف البيانات غير المرئية؟» يمكنك استخدام العنصر <meta>. لم تكن في السابق تستطيع استخدام العنصر <meta> إلا داخل ترويسة صفحتك؛ أما في HTML5، فتستطيع استخدام العنصر <meta> في أيِّ مكانٍ، وهذا ما سنفعله تمامًا. <meta itemprop="latitude" content="37.4149" /> ووفقًا للنموذج الهيكلي للبيانات الوصفية في HTML5، عنصر <meta> له معالجةٌ خاصة، فقيمة خاصية البيانات الوصفية هي قيمة الخاصية content؛ ولأن هذه الخاصية لا تُعرَض أبدًا، فهي مثاليةٌ لضبط عددٍ غيرِ محدودٍ من البيانات المخفية. لكن ستزداد المسؤولية الملقاة على عاتقك هنا، حيث عليك التأكد أنَّ المعلومات المخفية ستبقى متوافقةً مع ما حولها من النص المرئي. لا يوجد دعمٌ مباشرٌ لنوع الاصطلاحات Organization في المُقتطفات المنسقة في Google، لذا لا أملك نتيجةَ بحثٍ جميلة لعرضها لك. لكن لها تأثيرٌ على الأحداث (events) والمراجعات (reviews)، اللتان تدعمهما المقتطفات المنسقة في Google (تقبل بعض خاصياتهما أن يكون نوع الخاصية Organization). الشكل 1: معلومات البيانات الوصفية كما تُظهِرها أداة اختبار البيانات المنظّمة ترجمة -وبتصرّف- لجزء من فصل «Microdata» من كتاب Dive Into HTML5 لمؤلفه Mark Pilgrim. اقرأ أيضًا المقال التالي: كيفية توصيف الأحداث والمراجعات باستخدام microdata على HTML5 المقال السابق: توصيف الأشخاص باستخدام metadata في HTML5 النسخة العربية الكاملة من كتاب نحو فهم أعمق لتقنيات HTML5
  22. إن كنت قد قرأت المقال السّابق الذي يشرح ماهية metadata وكيفية استخدامها فأود أن أنوّه إلى أنني لم أخترع الأمثلة في الدرس السابق من عندي تمامًا، فهنالك اصطلاحات للبيانات الوصفية لتوصيف المعلومات الخاصة بالأشخاص، ومن السهل فعل ذلك. لنلقي نظرةً أقرب. أسهل طريقة لدمج البيانات الوصفية في موقعك الشخصي تكون في صفحة About، من المرجح وجود صفحة About لديك، أليس كذلك؟ إن لم تكن لديك صفحة، فيمكنك المتابعة معي في توسعة صفحة About الآتية ببعض البنى الهيكلية. لننظر أولًا إلى الشيفرة المصدرية، قبل إضافة أيّة خاصيات لها علاقة بالبيانات الوصفية: <section> <img width="204" height="250" src="http://diveintohtml5.org/examples/2000_05_mark.jpg" alt="[Mark Pilgrim, circa 2000]"> <h1>Contact Information</h1> <dl> <dt>Name</dt> <dd>Mark Pilgrim</dd> <dt>Position</dt> <dd>Developer advocate for Google, Inc.</dd> <dt>Mailing address</dt> <dd> 100 Main Street<br> Anytown, PA 19999<br> USA </dd> </dl> <h1>My Digital Footprints</h1> <ul> <li><a href="http://diveintomark.org/">weblog</a></li> <li><a href="http://www.google.com/profiles/pilgrim">Google profile</a></li> <li><a href="http://www.reddit.com/user/MarkPilgrim">Reddit.com profile</a></li> <li><a href="http://www.twitter.com/diveintomark">Twitter</a></li> </ul> </section> أول شيء عليك فعله دائمًا هو التصريح عن نوع الاصطلاحات الذي ستستعمله، ومجال (scope) الخاصيات التي تريد إضافتها. يمكنك القيام بذلك عبر إضافة خاصيتَي itemtype و itemscope إلى العنصر الأب الذي يحتوي على بقية العناصر التي تريد توصيف البيانات فيها، وهو في حالتنا العنصر <section>. <section itemscope itemtype="http://schema.org/Person"> يمكنك الآن البدء بتعريف خاصيات البيانات الوصفية من نوع الاصطلاحات http://schema.org/Person، لكن ما هي هذه الخاصيات؟ كما هو واضح، تستطيع رؤية كامل قائمة الخاصيات بزيارة الصفحة http://schema.org/Person في متصفحك. لا تتطلب مواصفة البيانات الوصفية أن توضع قائمة الخاصيات هناك، لكنني أرى أنَّ ذلك مستحسنٌ. فلو أردت مثلًا أن تجعل المطورين يستعملون نوع اصطلاحات البيانات الوصفية الذي أنشأته، فستحتاج إلى توثيقه. ولا يوجد مكانٌ أفضل لوضع التوثيق فيه من رابط نوع الاصطلاحات نفسه، أليس كذلك؟ الخاصية الشرح name الاسم additionalName الاسم الإضافي، قد يكون الاسم الأوسط أو اللقب image رابطٌ لصورةٍ له jobTitle المُسمَّى الوظيفي (مثلًا، مدير مالي [Financial Manager]) url رابط URL لصفحة ويب، مثل الصفحة الرئيسية لمدونة ذاك الشخص affiliation المنظمة التي يرتبط بها هذا الشخص (أن يكون -على سبيل المثال- موظفًا أو طالبًا فيها) address العنوان الفيزيائي للشخص. يمكن أن يحتوي على خاصيات أخرى مثل streetAddress وaddressLocality و addressRegion و postalCode و addressCountry knows علاقة اجتماعية بين الشخص الموصوف وشخصٍ آخر أول شيء نصادفه في صفحة About السابقة هي صورةٌ موضوعةٌ ضمن عنصر <img>، ولكي نُصرِّح أنَّ الصورة الموجودة هي صورة الشخص الموصوف، فكل ما نحتاج له هو إضافة itemprop="image"‎ إلى عنصر <img>. <img itemprop="image" width="204" height="250" src="http://diveinto.html5doctor.com/examples/2000_05_mark.jpg" alt="[Mark Pilgrim, circa 2000]"> أين هي قيمة خاصية البيانات الوصفية؟ إنها موجودةٌ في خاصية src، وإذا كنتَ تتذكر من النموذج الهيكلي للبيانات الوصفية في HTML5، "قيمة" خاصية البيانات الوصفية في عنصر <img> هي محتوى الخاصية src. ولكل عنصر <img> خاصية src -وإلا فلن تُعرَض الصورة- وخاصية src تحتوي على رابط URL دائمًا، أترى؟ إذا كنت تكتب HTML بشكلٍ صحيح، فاستعمال البيانات الوصفية سهلٌ جدًا. علاوةً على ذلك، العنصر <img> ليس موجودًا لوحده في الصفحة، فهو عنصر ابن للعنصر <section>، الذي عرَّفناه مع الخاصية itemscope. تُعيد البيانات الوصفية استعمال علاقة "الأب-الابن" بين العناصر في الصفحة لتعريف مجال (scope) خاصيات البيانات الوصفية. أي أننا نقول بالعربية: "العنصر <section> يُمثِّل شخصًا، وأيّة خاصيات للبيانات الوصفية التي تجدها في العناصر التي تكون ابنًا للعنصر <section> هي خاصياتٌ تابعةٌ لذاك الشخص". يمكنك تخيل الأمر على أنَّ العنصر <section> هو الفاعل في الجملة، والخاصية itemprop تمثِّل الفعل (وهو يُشبِه: "مُصوَّرٌ في")، وقيمة خاصية البيانات الوصفية هي المفعول به في الجملة. يجب تعريف "الفاعل" مرةً واحدةً فقط، وذلك بوضع الخاصيتين itemscope و itemtype في عنصر <section> الأب. أما "الفعل" فيُعرَّف بوضع الخاصية itemprop="image"‎ في عنصر <img>. أما "المفعول به" فلا يحتاج إلى أيّة شيفرات خاصة، لأنَّ النموذج الهيكلي للبيانات الوصفية في HTML5 يقول أنَّ قيمة خاصية البيانات الوصفية في عنصر <img> هي في خاصية src. سننتقل الآن إلى القسم التالي من الشيفرة، سنشاهد ترويسة <h1> وبداية قائمة <dl>. ليس من الضروري إضافة خاصيات البيانات الوصفية إلى عنصرَي <h1> و <dl>، فلا حاجة إلى وضع خاصية من خاصيات البيانات الوصفية في كل عنصر من عناصر HTML. الغرض من البيانات الوصفية هو "توصيف" البيانات وليس الشيفرات أو الترويسات التي تحيط بها. ترويسة <h1> لا تحتوي على قيمة، فهي مجرد ترويسة. وكذلك الأمر لعنصر <dt> الذي يحتوي على السلسلة النصية "Name» التي لا تمثل خاصية، وإنما لافتة (label) فقط. <h1>Contact Information</h1> <dl> <dt>Name</dt> <dd>Mark Pilgrim</dd> أين توجد المعلومات الحقيقية؟ في عنصر <dd>، وهنالك سنحتاج إلى وضع خاصية itemprop، لكن أيّ خاصية منها؟ إنها خاصية name، وأين قيمة الخاصية؟ هي النص الموجود ضمن العنصر <dd>، لكن ألا نحتاج إلى وضع القيمة في شيفرة خاصة؟ النموذج الهيكلي للبيانات الوصفية في HTML5 يقول لا، فلا يوجد معنى خاص لعناصر <dd>، وستكون قيمة الخاصية هي النص الموجود ضمن العنصر. <dd itemprop="name">Mark Pilgrim</dd> كيف نستطيع التعبير عما سبق بالعربية؟ "اسم هذا الشخص هو Mark Pilgrim". حسنًا، لنتابع. إضافة الخاصيتين التاليتين صعبٌ قليلًا، هذه هي الشيفرة قبل إضافة البيانات الوصفية: <dt>Position</dt> <dd>Developer advocate for Google, Inc.</dd> إذا نظرتَ إلى نوع اصطلاحات Person، فستجد أنَّ النص "Developer advocate for Google, Inc.‎" يحتوي على خاصيتين: jobTitle ‏(قيمتها "Developer advocate") و affiliation‏ ( قيمتها "Google, Inc.‎")، لكن كيف تستطيع أن تُعبِّر عن ذلك عبر البيانات الوصفية؟ الجواب المختصر: لا يمكنك فعل ذلك. لا توجد طريقة في البيانات الوصفية تمكِّنك من تقسيم سلسلة نصية إلى عدِّة خاصيات. لا يمكنك القول "أول 18 محرفًا من هذه السلسلة النصية هي خاصيةُ بياناتٍ وصفية، وآخر 12 محرفًا هي خاصيةٌ أخرى". لكن هذا لا يعني أنَّ الأمر مستحيلٌ. تخيل أنك تريد أن تُنسِّق النص "Developer advocate" بنوع خطٍ مختلف عن النص "Google, Inc.‎". حسنًا، CSS لا تستطيع فعل ذلك أيضًا، لكن ماذا كنتَ ستفعل؟ ستحتاج أولًا إلى وضع كل قسم من السلسلة النصية في حاويات مختلفة، مثل <span>، ثم تُطبِّق أنماط CSS على كل عنصر <span> على حدة. يمكنك تطبيق هذه التقنية أيضًا على البيانات الوصفية، فهنالك معلومتان منفصلتان هنا: jobTitle و affiliation. إذا وضعت كل معلومة في عنصر <span>، فستستطيع أن تقول أنَّ كل عنصر <span> هو خاصيةٌ مستقلةٌ من خاصيات البيانات الوصفية. <dt>Position</dt> <dd><span itemprop="jobTitle">Developer advocate</span> for <span itemprop="affiliation">Google, Inc.<span></dd> هذا يعني: "وظيفة هذا الشخص هي "Developer advocate". هذا الشخص يعمل لدى "Google, Inc.‎"". تلك جملتان، وخاصيتا بياناتٍ وصفية. صحيحٌ أننا وضعنا مزيدًا من الشيفرات، لكننا استفدنا منها خيرَ استفادة. سنستفيد أيضًا من نفس التقنية لتوصيف معلومات العنوان، يُعرِّف نوع الاصطلاحات Person الخاصية address، التي هي بدورها عنصرٌ من عناصر البيانات الوصفية، وهذا يعني أنَّ للعنوان نوعُ اصطلاحاتٍ خاصٌ به (http://schema.org/PostalAddress)، وله خاصياتٌ متعلقةٌ به. يُعرِّف نوع الاصطلاحات PostalAddress خمسَ خاصياتٍ: streetAddress و addressLocality و addressRegion و postalCode و addressCountry. إذا كنتَ مبرمجًا، فمن المرجح أنَّك تعرف كيف تفصل النقطة بين الكائنات وخاصياتها، تخيل أنَّ العلاقة كالآتي: Person Person.PostalAddress Person.PostalAddress.streetAddress Person.PostalAddress.addressLocality Person.PostalAddress.addressRegion Person.PostalAddress.postalCode Person.PostalAddress.addressCountry لنعد إلى مثالنا. العنوان بأكمله موجودٌ في عنصر <dd> وحيد (أكرِّر مرةً أخرى أنَّ العنصر <dt> هو لافتة، ولا يلعب دورًا في إضافة معلومات إلى البيانات الوصفية). من السهل الإشارة إلى خاصية address، كل ما عليك فعله هو إضافة الخاصية itemprop في عنصر <dd>. <dt>Mailing address</dt> <dd itemprop="address"> لكن تذكَّر أنَّ خاصية address هي بدورها عنصرٌ من عناصر البيانات الوصفية، هذا يعني أننا نحتاج إلى وضع الخاصيتين itemscope و itemtype أيضًا. <dt>Mailing address</dt> <dd itemprop="address" itemscope itemtype="http://schema.org/PostalAddress"> لقد رأينا هذا من قبل، لكن للعناصر من المستوى الأول (top-level). عنصر <section> يحتوي على itemtype و itemscope، وجميع العناصر الموجودة ضمن العنصر <section> التي لديها خاصيات للبيانات الوصفية هي ضمن "مجال" (scope) نوع اصطلاحات البيانات الوصفية. لكن هذه هي أول مرة نرى فيها "تشعّب" المجالات، أي تعريف itemtype و itemscope (في عنصر <dd>) داخل مجال موجود مسبقًا (في عنصر <section>). المجالات المتشعبة تعمل تمامًا كما تعمل شجرة DOM في HTML. العنصر <dd> يحتوي على عددٍ معيّنٍ من العناصر الأبناء، ويكون مجالها هو نوع الاصطلاحات المُعرَّف في العنصر <dd>، وبعد أن ينتهي العنصر <dd> عبر وسم الإغلاق <‎/dd> فسيرجع المجال إلى نوع الاصطلاحات المُعرَّف في العنصر الأب (الذي هو <section> في حالتنا). تُعاني خاصيات العنوان من نفس المشكلة التي واجهناها عند تعريف الخاصيتين jobTitle و affiliation، لكن السلسلة النصية للعنوان أطول قليلًا، وعلينا تقسيمها إلى خمس خاصيات للبيانات الوصفية. وسنستعمل نفس الآلية التي اتبعناها سابقًا: وضع كل قطعة من المعلومات في عنصر <span>، ثم توصيف تلك المعلومات عبر خاصيات البيانات الوصفية. <dd itemprop="address" itemscope itemtype="http://schema.org/PostalAddress"> <span itemprop="streetAddress">100 Main Street</span><br> <span itemprop="addressLocality">Anytown</span>, <span itemprop="addressRegion">PA</span> <span itemprop="postalCode">19999</span> <span itemprop="addressCountry">USA</span> </dd> بالعربية: "هذا الشخص يملك عنوانًا بريديًا. اسم الشارع لذاك العنوان البريدي هو "100 Main Street"، أما البلدة (locality) فهي "Anytown"، والإقليم (region) هو "PA"، والرمز البريدي (postal code) هو "19999"، واسم الدولة هو "USA"". س: هل صيغة العنوان البريدي خاصةٌ بالولايات المتحدة؟ ج: لا. خاصيات نوع الاصطلاحات PostalAddress عامةٌ لتتمكن من وصف أي عنوان بريدي في العالم. لكن لن يكون لجميع العناوين قيمٌ لكل خاصية من الخاصيات، لكن لا بأس بهذا. وقد تتطلب بعض العناوين وضع أكثر من "سطر" واحد في خاصية معيّنة، ولا بأس بهذا أيضًا. فمثلًا، لو كان يحتوي العنوان البريدي على عنوان الشارع ورقم البناء، فسيمثِّل كلاهما الخاصية streetAddress: <p itemprop="address" itemscope itemtype="http://schema.org/PostalAddress"> <span itemprop="streetAddress"> 100 Main Street Suite 415 </span> ... </p> بقي شيءٌ أخيرٌ في صفحة About: قائمةٌ بروابط URL. لدى نوع الاصطلاحات Person خاصيةٌ لهذا الغرض اسمها url، التي يمكن أن تحتوي على أيّ نوعٍ من أنواع الروابط (المهم أن يكون "رابطًا"). ما أقصده هو أنَّ تعريف الخاصية url غير مُحدَّد، ويمكن أن تحتوي على أيّة روابط متعلقة بالشخص: مدونة، أو معرض صور، أو حساب شخصي على موقعٍ آخر مثل فيسبوك أو تويتر. من المهم أن تلاحظ أنَّ الشخص الواحد قد يمتلك أكثر من خاصية url. تقنيًا، يمكن لأي خاصية أن تتكرر، لكن إلى الآن لم نستفد من هذا. على سبيل المثال، قد يكون لديك أكثر من خاصية image تُشير إلى روابط URL لصورتين مختلفتين. أريد هنا أن أذكر أربعة روابط URL مختلفة: المدونة، وحساب Google، وحساب Reddit، وحساب تويتر. هنالك قائمة في HTML فيها أربعة روابط موجودة في أربعة عناصر <a>، كلُ واحدٍ منها موجودٌ في عنصر <li> خاص به. سنُضيف الخاصية itemprop="url"‎ إلى كل عنصر من عناصر <a>. <h1>My Digital Footprints</h1> <ul> <li><a href="http://diveintomark.org/" itemprop="url">weblog</a></li> <li><a href="http://www.google.com/profiles/pilgrim" itemprop="url">Google profile</a></li> <li><a href="http://www.reddit.com/user/MarkPilgrim" itemprop="url">Reddit.com profile</a></li> <li><a href="http://www.twitter.com/diveintomark" itemprop="url">Twitter</a></li> </ul> وفقًا للنموذج الهيكلي للبيانات الوصفية في HTML5، سيُعامَل العنصر <a> معاملةً خاصةً، فقيمة خاصية البيانات الوصفية تؤخذ من الخاصية href، وليس من المحتوى النصي للعنصر. وسيتم تجاهل المحتوى النصي لكل رابط من قِبَل مُفسِّر البيانات الوصفية. وهذا يعني -بالعربية-: "هذا الشخص لديه رابط URL في http://diveintomark.org/‎ وهذا الشخص لديه رابط URL آخر في http://www.google.com/profiles/pilgrim وهذا الشخص لديه رابط URL آخر في http://www.reddit.com/user/MarkPilgrim وهذا الشخص لديه رابط URL آخر في http://www.twitter.com/diveintomark" المقتطفات المنسقة Rich Snippets ربما تتساءل : "لماذا نفعل هذا؟" هل نُضيف البنى الهيكلية عبثًا؟ لماذا نأبه للبيانات الوصفية ونستعملها؟ هنالك نوعان رئيسيان من التطبيقات التي تستخدم HTML، وبطريقها تستخدم البيانات الوصفية أيضًا: متصفحات الويب محركات البحث أما للمتصفحات، فهنالك واجهةٌ برمجيةٌ في DOM لاستخلاص عناصر البيانات الوصفية وخاصياتها وقيم تلك الخاصيات من صفحة الويب، لكن للأسف هذه الواجهة البرمجية غير مدعومة إلا من الإصدارات الحديثة لبعض المتصفحات، لهذا اعتبر أنَّ هذا الطريق مسدودٌ إلى أن تدعم جميع المتصفحات هذه الواجهة البرمجية. مستهلكٌ آخر لشيفرات HTML هو محركات البحث. ماذا يمكن لمحركات البحث فعله مع خاصيات البيانات الوصفية التي تتحدث عن شخصٍ ما؟ تخيل هذا: بدلًا من عرض عنوان الصفحة ومُلخَّص عن محتواها، فسيعرض محرِّك البحث بعض المعلومات الهيكلية الموجودة فيها، مثل الاسم الكامل، والمُسمى الوظيفي، والشركة التي يعمل بها، والعنوان، وربما سيعرض أيضًا صورةً مُصغَّرةً له. هل جذب ذلك انتباهك؟ يدعم محرك البحث Google البيانات الوصفية كجزءٍ من برنامج "المقتطفات المنسقة" (Rich Snippets)، فعندما يُفسِّر عنكبوت البحث في Google صفحتك ويجد خاصيات للبيانات الوصفية التي تتطابق مع نوع الاصطلاحات http://schema.org/Preson، فسيحاول تفسير تلك الخاصيات ويُخزِّن قيمها بجانب بقية بيانات الصفحة. لدى Google أداةٌ رائعةٌ لكي ترى كيف "يرى" Google خاصيات البيانات الوصفية في صفحتك، واختبارها على صفحة About التي نعمل عليها سيُعطي النتيجة: الشكل 1: معلومات البيانات الوصفية كما تُظهِرها أداة اختبار البيانات المنظّمة كل البيانات الوصفية موجودٌ هنا: خاصية image من <img src>، جميع روابط URL من قائمة عناصر <a href>، وحتى كائن العنوان (مذكورٌ في "address") والخاصيات الخمس المتعلقة به. الآن، كيف يستعمل Google كل هذه المعلومات؟ الأمر نسبيٌ، فلا توجد قواعد مُلزِمَة لكيفية عرض خاصيات البيانات الوصفية، ولا أيُّها سيُعرَض، وحتى لا توجد قواعد تحكم إذا كانت ستُعرَض هذه الخاصيات أم لا. إذا بحث أحدهم عن "Mark Pilgrim" ورأى Google أنَّ صفحة "About" تستحق الظهور في نتائج البحث، وقرر Google أنَّ خاصيات البيانات الوصفية الموجودة في تلك الصفحة تستحق أن تُعرَض، فعندها ستبدو نتيجة البحث مشابهةً لما يلي: الشكل 2: مثالٌ عن نتيجة البحث عن صفحة فيها بياناتٌ وصفيةٌ أول سطر "About Mark Pilgrim" هو عنوان الصفحة الموجود في عنصر <title>، ولكن هذا ليس أمرًا مثيرًا للاهتمام؛ لأن محرك Google يفعل هذا لكل صفحة، لكن السطر الثاني مليءٌ بالمعلومات المأخوذة مباشرةً من البيانات الوصفية التي أضفناها إلى الصفحة. "Anytown PA" هو جزءٌ من العنوان البريدي، الموصوف عبر نوع الاصطلاحات http://schema.org/PostalAddress، أما "Developer advocate" و "Google, Inc.‎" هما الخاصيتان من نوع الاصطلاحات http://schema.org/Person (الخاصية jobTitle و affiliation على التوالي وبالترتيب). هذا رائع! لا تحتاج إلى أن تكون شركةً كبيرةً تُبرِمُ اتفاقياتٍ خاصةً مع شركات محركات البحث لتخصيص طريقة عرض نتيجة البحث. كل ما تحتاج له هو عشر دقائق وبعض خاصيات HTML لكي توصِّف فيها بياناتك التي ستنشرها في صفحتك. س: فعلتُ كل ما قلتَه لي، لكن لم تتغير طريقة عرض نتائج البحث عن صفحتي في Google، ما الخطب؟ ج: "لا تضمن Google أنَّ الشيفرة الموجودة في أيّة صفحة أو موقع ستُستخدَم في نتائج البحث"، لكن بغض النظر أنَّ محرك Google قرر ألّا يستعمل البيانات الوصفية في صفحتك، فقد يستعملها محركُ بحثٍ آخر. فمعيار البيانات الوصفية (Microdata) هو معيارٌ مفتوحٌ يستطيع أيُّ شخصٍ توظيفه -كما هي بقية HTML5-. من واجبك توفير أكبر قدر من البيانات تستطيع تقديمه. ثم اترك الأمر للآخرين لكي يُقرِّروا ماذا يفعلون معها. ربما يفاجئوك! ترجمة -وبتصرّف- لجزء من فصل "Microdata" من كتاب Dive Into HTML5 لمؤلفه Mark Pilgrim. اقرأ أيضًا المقال التالي: توصيف المنظمات/الشركات باستخدام microdata في HTML5 المقال السابق: مدخل إلى البيانات الوصفية (microdata) في HTML5 النسخة العربية الكاملة من كتاب نحو فهم أعمق لتقنيات HTML5
  23. إذا كنتَ من مطوري ووردبريس، فستُتحمّس للاستفادة من ميزة تعدد المواقع (Multisite)، ولهذا السبب قدمنا لك هذه الدورة التدريبية المؤلفة من عشر مقالات كي تحترف هذه الميزة المفيدة. ميزة تعدد المواقع لها فائدة كبيرةٌ في أنها ستساعدك على إنشاء شبكة من المواقع لتلبية مختلف الاحتياجات ولمختلف الأغراض، والتي تستطيع تخصيصها لتسهيل بعض الأمور لمستخدميك ولجعل شبكتك من المواقع تعمل بكفاءة عالية… ستتعلم في هذه الدورة كل شيء ستحتاج له كي تُنشِئ شبكتك الخاصة، وتضيف المواقع إليها أو تسمح للمستخدمين بإضافة مواقع إلى الشبكة وإدارتها. وستتعلم كيف تحافظ على أمان شبكتك وتضمن أداءها أداءً عاليًا وكيف تُنشِئ مجتمعًا ناجحًا من المستخدمين والمواقع. سنبدأ بأخذ فكرة عامة عن ميزة تعدد المواقع في هذا الجزء، وسأشرح لك فيه: تمهيد إلى تعدد المواقع: ما يمكنك أو لا يمكنك فعله ميزات الشبكات متعددة المواقع الفرق بين شبكة مُنشَأة عبر تعدد المواقع، وبين المواقع المفردة حالات استخدام تعدد المواقع لنبدأ جولتنا! مدخل إلى تعدد المواقع في ووردبريس خاصية تعدد المواقع هي جزءٌ من أساس ووردبريس، إلا أنها كانت نظامًا منفصلًا يدعى «WPMU» الذي دُمِجَ مع أساس ووردبريس في الإصدار 3.0. هذا يعني أنَّك تستطيع تفعيل تعدد المواقع في أي موقع يستخدم ووردبريس بكل سهولة، حتى لو كان موقعك يعمل منذ أشهر أو سنوات. لكن هنالك اختلافٌ أساسيٌ بين إضافة ميزة تعدد المواقع على موقعٍ موجودٍ مسبقًا وبين إضافته على موقعٍ جديد؛ وهذا الاختلاف مرتبط بالنطاقات الفرعية والمجلدات الفرعية. سنشرح ذلك بالتفصيل لاحقًا عندما نلقي نظرةً على البنية الهيكلية لشبكة متعددة المواقع. تسمح ميزة تعدد المواقع لك بإنشاء شبكة من المواقع، وهذا يعني أنَّ هنالك تثبيت ووردبريس وحيد، وتستطيع عبره أن تحصل على أي عدد تريده من المواقع. أنا أعي ما أقول، تستطيع أن تحصل على أي عدد من المواقع! فموقع WordPress.com هو شبكةٌ متعددة المواقع يُشغِّل حوالي 10% من مواقع الويب، وموقع Edublogs هو شبكةٌ متعددة المواقع الذي يُشغِّل أكثر من ثلاث ملايين مدونة تعليمية. ربما لديك تصور أنَّ هنالك بعض الإجراءات الإضافية عندما يأتي الأمر إلى إدارة مثل هذه الشبكات الضخمة، مثل توزيع وسائط التخزين على أكثر من خادوم؛ لكن الفكرة الأساسية هي استخدام ووردبريس كشبكة متعددة المواقع. لن تتعلم في هذه الدورة التدريبية كيف تُنشِئ وتدير شبكات ضخمة مثل Edubolgs –هذا يحتاج إلى أعوام من الخبرة والتجربة– لكنك ستتعلم كيف تُنشِئ شبكتك الخاصة من المواقع التي يمكنك استخدامها لأغراضٍ عدّة. هذا هو تعريف «تعدد المواقع» من دليل ووردبريس للمطورين: حسنًا، الشبكة متعددة المواقع هي ميزة من ميزات ووردبريس التي تسمح لك بإنشاء شبكة خاصة بك من المواقع، ويمكن أن يُدار كل موقع من تلك المواقع بشكلٍ منفصل، وأن يشير إليه نطاقٌ خاصٌ به لكي يستطيع الزوار الوصول إليه، ولن يستطيعوا أن يميّزوا أنَّ موقعك جزءٌ من شبكةٍ ما من المواقع. ستُسهِّل هذه الميزة الأمر عليك كثيرًا إذا كنت تدير عدِّة مواقع ولم تكن تريد أن تُتُعِبَ نفسك بمراقبة كل موقع على حدة، بما في ذلك تحديث الإضافات، والتعامل مع المشاكل الأمنية والمشاكل في الأداء، وإضافة المستخدمين …إلخ. هذه الميزة مفيدة للغاية إن كنت تريد أن تسمح لمستخدميك أن يتواصلوا مع بعضهم بعضًا عبر مجتمع (community) الذي تستطيع استضافته على شبكتك. ميزات تعدد المواقع هنالك عدّة ميزات لتعدد المواقع في ووردبريس مقارنةً مع إدارة عدد من المواقع لها أكثر من تثبيت ووردبريس: مساحة التخزين. هنالك نسخةٌ واحدةٌ فقط من ملفات ووردبريس ونسخةٌ واحدةٌ أيضًا من كل قالب أو إضافة مُخزَّنة على خادومك. التحديثات. ستحتاج إلى تحديث تثبيت ووردبريس والقوالب والإضافات مرةً واحدةً فقط بدلًا من فعل ذلك لكل موقعٍ على حدة (لكن عليك تجربة التحديث على موقع تجريبي أولًا!). المجتمع. يمكنك استخدام شبكة متعددة المواقع لإنشاء مجتمع من المواقع والمستخدمين. الخيارات المتاحة إليك تتضمن نشر المحتوى على أكثر من موقع في آنٍ واحد، والسماح للمستخدمين بمتابعة (follow) بعضهم بعضًا، والمزيد… سأشرح هذه النقطة بالتفصيل في هذه الدورة. إنشاء المواقع. تُمكِّنك ميزة تعدد المواقع من السماح للمستخدمين بإنشاء مواقع خاصة بهم في شبكتك. وهذه الميزة رائعة إذا كنت تدير شبكةً خاصةً بالمدرسة أو لنادٍ معيّن، أو إذا أردت أن تتلقى مقابلًا ماديًا لقاء إنشاء مواقع للآخرين. هنالك جزءٌ يتحدث عن إنشاء المواقع في هذه الدورة. الاختلافات الأساسية بين شبكة من المواقع والمواقع المفردة قبل أن تبدأ بالعمل على ميزة تعدد المواقع، يجب أن أنوِّه إلى بعض الاختلافات الرئيسية بينها وبين طريقة تثبيت ووردبريس الاعتيادية (أدعوها «المواقع المفردة» [standalone sites]). من الجيد أن تفهم هذه الاختلافات أولًا، لأنها ستساعدك في اتخاذ قرارك فيما إذا كانت شبكةٌ من المواقع المتعددة هي الأداة المثالية لك، وستساعدك أيضًا عندما تبدأ بإنشاء وإدارة شبكتك. لننظر إلى بعض هذه الاختلافات. ملاحظة عن الاصطلاحات: إذا كنت تستخدم مواقع ووردبريس المفردة من قبل، فستظن أنَّ «التثبيت» (installation) هو موقعك. لكنني سأستخدم هذا المصطلح في هذه الدورة بطريقةٍ مختلفة. الشبكة تمثل تثبيت ووردبريس، التي تتضمن عددًا من المواقع. والموقع هو أحد المواقع في الشبكة، وكانت تسمى تلك المواقع في الإصدارات القديمة من ميزة تعدد المواقع بالمدونات (blogs)، لكن ذلك تغيّر في إصدار 3.5 من ووردبريس. إدارة الشبكة عندما تُنشِئ شبكةً متعددة المواقع، فستصبح «مدير الشبكة» (super admin)، وهذا يعني أنَّ لديك القدرة على إدارة الشبكة بالإضافة إلى إدارة المواقع الموجودة فيها كُلًّا على حدة. عندما تُفعِّل الشبكة، فستشاهد بعض العناصر الإضافية في لوحة التحكم، وهي ظاهرةٌ في لقطة الشاشة الآتية: عناصر القائمة الإضافية هي: عنصر قائمة جديد اسمه «My Sites» (مواقعي) رابط «My Sites» (مواقعي) في شريط الإدارة العلوي الذي سيأخذك إلى صفحات إدارة الشبكة. صفحات إدارة الشبكة هي المكان الذي تُثبِّت وتُفعِّل فيه القوالب والإضافات وإنشاء وإدارة المواقع والمستخدمين: تتضمن قائمة إدارة الشبكة ستة أقسام: Dashboard (الرئيسية) – إدارة التحديثات والترقيات على الشبكة. Sites (المواقع) – إنشاء مواقع في الشبكة وإدارة المستخدمين والقوالب وضبط الخيارات لكلٍ منها. Users (أعضاء) – إضافة مستخدمين إلى شبكتك بنفس الطريقة التي كنتَ تُضيفهم فيها إلى المواقع المفردة. Themes (قوالب) – تثبيت القوالب، ومن ثم ستتمكن من تفعيلها لكامل الشبكة أو لمواقع معيّنة على الشبكة. Plugins (إضافات) – تثبيت الإضافات وتفعيلها على كامل الشبكة إن شئت. قد تتمكن من تفعيل بعض الإضافات لكامل الشبكة فقط، مثل إضافات النسخ الاحتياطي؛ بينما يمكن لبعضها الآخر أن يُفعَّل لكامل الشبكة إن شئت أن تعمل تلك الإضافة على جميع المواقع، أو يمكن لمدراء المواقع أن يختاروا ما الذي يريدون تفعيله على موقعهم. Settings (الإعدادات) – إدارة ضبط الشبكة. هذه هي بعض جوانب إدارة الشبكة التي قد تُحيّر بعض المبتدئين: الموقع الأساسي أو الرئيسي (Base site). عندما تُنشِئ شبكةً، فسيكون هنالك موقعٌ واحدٌ على الأقل لتبدأ معه ألا وهو «الموقع الرئيسي». هذا هو الموقع الذي بدأت فيه عبر تثبيت ووردبريس، وسيكون رابط URL الأساسي هو اسم النطاق (domain name). ستتمكن –كمدير للشبكة– أن تكون مديرًا لهذا الموقع أيضًا، ويمكنك إضافة مستخدمين آخرين بنفس طريقة إضافة المستخدمين للمواقع المفردة؛ لكن لا يمكنك إزالة هذا الموقع من الشبكة. تستطيع أيضًا أن تُفعِّل القوالب أو الإضافات كما في أي موقع آخر على الشبكة. تفعيل القوالب والإضافات. قد تتوقع أنك تستطيع تفعيل القوالب والإضافات بنفس الطريقة التي تعرفها. يمكنك تثبيت القوالب والإضافات عبر لوحة تحكم مدير الشبكة، لكن ستختلف الأمور عمّا اعتدت عليه بدءًا من هذه المرحلة. يمكنك أن تُفعِّل الإضافات على كامل مواقع الشبكة، أو ألّا تفعَّلها أبدًا، وفي هذه الحالة سيحتاج مدير الموقع إلى تفعيل الإضافات في صفحة الإضافات في لوحة تحكم الموقع. أما القوالب، فيمكنك أن تُمكِّن اختيارها عبر الشبكة، مما يُتيح لمدراء المواقع تفعيلها على موقعهم، أو يمكنك تمكين القوالب لمواقع معيّنة وذلك عبر صفحة «Sites» (المواقع) في لوحة التحكم، مما يعني أنَّ تلك المواقع هي المواقع التي تستطيع تفعيل القالب فقط ولن تتمكن بقية المواقع من رؤية القالب؛ قد تستفيد من هذه الميزة إن كنت تُدير شبكةً من مواقع العملاء ولدى كل موقع قالب خاصٌ به. إنشاء المستخدمين. يمكن لمدير الشبكة أو لمدراء المواقع إضافة المستخدمين؛ إذا أضفتُ مستخدمًا عبر لوحة تحكم مدير الشبكة، فسيُنشَأ حساب للمستخدم على الشبكة لكن دون أيّة امتيازات على المواقع الأخرى (بما في ذلك الموقع الرئيسي)؛ أما لو أضاف مدير موقعٍ ما مستخدمًا، فسيحصل المستخدم على وصول إلى ذاك الموقع فقط، لكن سيكون بإمكان بقية مدراء المواقع من إضافة المستخدم إلى مواقعهم أيضًا. التحديثات. عندما تُحدِّث قالبًا أو إضافةً أو نسخة ووردبريس نفسها، فعليك القيام بذلك من لوحة تحكم مدير الشبكة وستُطبَّق التغيرات على جميع المواقع في شبكتك. وهذا هو السبب وراء ضرورة اختبار أيّة تحديثات على موقعٍ تطويري قبل تطبيقها على شبكةٍ إنتاجية، فلو أدى تحديث إضافةٍ ما إلى حدوث خلل، فسيؤثر على جميع مواقع الشبكة التي تستعمل تلك الإضافة! يمكنك تثبيت إضافة تساعدك في التعرف على المواقع التي تستعمل قالبًا أو إضافةً معينة، وسنشرح ذلك بالتفصيل لاحقًا في هذه السلسلة. هنالك إمكانيات (capabilities) إضافية لمدير الشبكة مقارنةً بمدير الموقع: إمكانيات متعلقة بمدير الشبكة (أي superadmin): manage_network، و manage_sites، و manage_network_users، و manage_network_plugins، و manage_network_themes، و manage_network_options. إمكانيات كان يملكها مدير الموقع إن كان الموقع منفردًا ولكنها أصبحت متعلقة بمدير الشبكة في شبكة من المواقع: update_core، و update_plugins، و update_themes، و install_plugins، و install_themes، و delete_themes، و delete_plugins، و edit_plugins، و edit_themes، و edit_files، و edit_users، و create_users، و delete_users، و unfiltered_html. إمكانيات يملكها مدير الشبكة ومدير الموقع: activate_plugins، و delete_others_pages، و delete_others_posts، و delete_pages، و delete_posts، و delete_private_pages، و delete_private_posts، و delete_published_pages، و delete_published_posts، و edit_dashboard، و edit_others_pages، و edit_others_posts، و edit_pages، و edit_posts، و edit_private_pages، و edit_private_posts، و edit_published_pages، و edit_published_posts، و edit_theme_options، و export، و import، و list_users، و manage_categories، و manage_links، و manage_options، و moderate_comments، و promote_users، و publish_pages، و publish_posts، و read_private_pages، و read_private_posts، و read، و remove_users، و switch_themes، و upload_files. وهذا يعني أنَّ –كمدير شبكة– تستطيع أن تُعدل وتُدير المواقع الموجودة ضمن شبكتك. إدارة الموقع عندما يُنشَأ موقعٌ جديدٌ على شبكتك، فسيكون له مديرٌ خاصٌ به. فإذا أُنشِئ الموقع عبر مدير الشبكة، فسيكون هو مدير الموقع؛ أما لو أنشِئ الموقع عبر نموذج للتسجيل، فسيكون المستخدم الذي يُنشِئ الموقع هو مدير الموقع. من الممكن إضافة مدراء إضافيين لكل موقع كما لو كان موقع ووردبريس مفردًا. خصائص لوحة التحكم التي يستطيع مدراء المواقع الدخول إليها مختلفةٌ قليلًا عن المواقع المفردة. الاختلافات الجوهرية هي: تثبيت الإضافات والقوالب. لا يمكن لمدراء المواقع تثبيت إضافات أو قوالب. لكن إذا كان قالبٌ ما متاحًا على الشبكة أو متاحًا لموقعٍ معيّن، فيمكن لمدير الموقع أن يفعِّل القالب في صفحة القوالب بلوحة التحكم. وإذا أعطى مديرُ الشبكة مدراءَ المواقع امتيازاتٍ للتحكم بإدارة الإضافات، فيمكنهم تفعيل الإضافات، لكنهم لن يستطيعوا مشاهدة أيّة إضافات غير متاحة على الشبكة في صفحة الإضافات في لوحة التحكم، ولن يستطيع مدراء المواقع تحديث الإضافات أو القوالب. الضبط. هنالك بعض خيارات الضبط التي يستطيع مدير الشبكة الوصول إليها فقط؛ وهذا يتضمن الحجم الأقصى للملفات المرفوعة، وآلية تسجيل المستخدمين، وإعدادات المواقع الجديدة. لدى مدراء المواقع نفس الامتيازات وصفحات لوحة التحكم المتعلقة بإنشاء وتعديل المحتوى كما لو كان الموقع مفردًا، يمكنهم أيضًا إضافة مستخدمين جدد إلى مواقعهم، بما في ذلك المستخدمين الذي سبقَ وأن سجلوا على الشبكة، بالإضافة إلى المستخدمين الجدد. يمكن لمدراء المواقع أن يُفعِّلوا الإضافات غير المفعلة على كامل الشبكة إن سمح لهم مدير الشبكة بذلك. قد تستفيد من هذه الميزة إن كنت تسمح للأشخاص بإنشاء وإدارة مواقعهم بطريقة شبيهة بموقع edublogs أو WordPress.com. هيكلية الملفات تحتوي الشبكة متعددة المواقع على نفس ملفات ووردبريس كأي تثبيت آخر، لذا ستكون الملفات الموجودة في المجلد الجذر (أي المجلد الأساسي لووردبريس) ومجلد wp-admin ومجلد wp-includes متماثلة؛ وكذلك الأمر لملفات الإضافات والقوالب في مجلد wp-content. هذه هي طريقةٌ ذات كفاءةٍ عالية إذا كنت تُدير عدة مواقع: فبدلًا من تخزين كل قالب أو إضافة عدِّة مرات في عدة مواقع، يمكنك أن تخزن نسخة واحدة من القالب أو الإضافة على شبكة من المواقع ومن ثم تستعملها على أي عدد تريده من المواقع. الاختلاف الوحيد هو في كيفية هيكلة مجلد الملفات المرفوعة ضمن wp-content، حيث سيحتوي على مجلد uploads في المواقع المفردة الذي سيحتوي بدوره على مجلد لكل سنة، وفي ذاك المجلد عدِّة مجلدات للأشهر التي رُفعِتَ فيها الوسائط على الموقع. أما في شبكة من المواقع، فستخزن الملفات المرفوعة لكل موقع على حدة. ستُخزَّن الملفات المرفوعة للموقع الرئيسي بنفس طريقة تخزين الملفات المرفوعة للمواقع المفردة، وهذا مهم لأنك قد تفعل ميزة شبكة المواقع بعد أن أضفت محتوى ووسائط مرفوعة إلى الموقع الرئيسي، وبالتأكيد تريد أن تبقى تلك الملفات. لكن جميع المواقع الأخرى سيكون لها مجلد منفصل للوسائط المرفوعة، وذلك بإنشاء مجلد جديد باسم sites ضمن مجلد wp-content/uploads؛ وسيُنشَأ مجلد لكل موقع من مواقع الشبكة حيث يكون اسم المجلد هو مُعرِّف ID للموقع؛ إذ يملك كل موقع مُعرِّف ID رقمي خاص به يبدأ من الرقم 2. ومن ثم ستكون لتلك المجلدات نفس بنية مجلد uploads للمواقع المفردة (أي وجود مجلدات لكل سنة، ولكل شهر). هذا يعني أنك لو رفعت ملفًا اسمه media.png إلى موقع له المُعرِّف 10 ضمن شهر آذار عام 2016، فسيُخزَّن كالآتي: wp-content/uploads/sites/10/2016/03/media.png.. بنية قاعدة البيانات لدى قاعدة بيانات الشبكة متعددة المواقع بنية مختلقة عن المواقع المفردة. لدى موقع ووردبريس الاعتيادي أحد عشر جدولًا في قاعدة البيانات: wp_posts wp_postmeta wp_comments wp_commentmeta wp_links wp_term_relationships wp_term_taxonomy wp_terms wp_options wp_users wp_usermeta أما في الشبكة متعددة المواقع، فسُتفصَل جداول كل موقع. أي سيكون لديك نسخةٌ من الجداول السابقة (للموقع الرئيسي)، بالإضافة إلى نسخة لكل موقع؛ إذ سيُضاف تسعة جداول لكل موقع –أي كل الجداول ما عدا wp_users و wp_usermeta–. لا يُنسَخ جدولي المستخدمين وبياناتهم أكثر من مرة، لأن المستخدمين هم مستخدمون لكامل الشبكة وليسوا مستخدمين لموقعٍ واحدٍ فقط. أما بقية الجداول التسعة فتُنسَخ لكل موقع، مع إضافة مُعرِّف ID الموقع كسابقة لاسم الجدول، لذاك ستكون جداول موقع له المعرف 10 كالآتية: wp_10_posts wp_10_postmeta wp_10_comments wp_10_commentmeta wp_10_links wp_10_term_relationships wp_10_term_taxonomy wp_10_terms wp_10_options بالإضافة إلى ذلك، تُنشِئ ووردبريس بعض الجداول الإضافية لكي تُخزِّن فيها البيانات المتعلقة بالشبكة نفسها، تلك الجداول هي: wp_blogs wp_blog_versions wp_registration_log wp_signups wp_site wp_sitemeta wp_sitecategories (اختياري) تلك الجداول تُخزِّن البيانات المتعلقة بإعدادات الشبكة والمواقع المُنشَأة فيها. ترجمة –وبتصرّف– للمقال WordPress Multisite Masterclass: Getting Started لصاحبته Rachel McCollin.
  24. هذا هو الدرس الأول من درسين يشرحان لك كيف تطوِّر مواقع الويب ذات الاتجاه من اليمين إلى اليسار (RTL)، وهذا يعني جعل موقع الويب متوافقًا مع اللغات التي تُكتَب من اليمين إلى اليسار مثل العربية والفارسية والأردو. ماذا يعني اتجاه الكتابة من اليمين إلى اليسار؟ لتوضيح الأمور، هنالك فرقٌ بين اللغة (التي هي الشكل المحكي) والمخطوطة (script، أي طريقة الكتابة). أي تقنيًا، الاتجاه من اليمين إلى اليسار يكون للمخطوطات التي تُكتَب بها اللغات، وذلك مقارنةً مع الاتجاه من اليسار إلى اليمين في لغاتٍ مثل الإنكليزية أو الفرنسية. مصطلح «اليمين-إلى-اليسار» (Right-to-Left) أو RTL اختصارًا، يُشير إلى أكثر من مجرد المخطوطة المستعملة للكتابة؛ حيث يُشير إلى جميع الأمور المتعلقة بتطوير مواقع وتطبيقات الويب لكي تظهر بشكل سليم عند استخدام اللغة العربية أو غيرها من اللغات التي تُكتَب من اليمين إلى اليسار. قبل المتابعة، لنوضِّح بعض الالتباسات حول RTL. أولًا، RTL لا تعني ترجمة النص إلى العربية: فالأمر أكثر من مجرد ترجمة واجهة موقعك إلى العربية، وإنما جعل كل جزء من الواجهة الرسومية ملائمًا لاتجاه RTL؛ وأنصحك أن تفعل ذلك بشكلٍ صحيح، فعدم إكمالك لدعم اتجاه RTL سيفقدك زوارك ومصداقيتك. ثانيًا، اتجاه RTL لا يعني «قلب كل شيء»: لستُ متأكدًا إن أُصلِحتَ هذه العلة أم لا، لكن ضبط «المحلية» (locale) إلى العربية في واجهة Gnome سيؤدي إلى إظهار الوقت بالشكل «PM 33:12» بدلًا من «‏12:33‎ PM‏‏». هذا ليس صحيحًا، نحن لا نذكر الوقت بالمقلوب بالعربية. أي أنَّ هنالك استثناءات وأشياء يجب الانتباه إليها مثل الأرقام، وسنشرح ذلك لاحقًا. لماذا عليك أن تهتم بدعم موقعك لاتجاه RTL؟ ربما تطور مواقع عالمية بلغاتٍ مثل الإنكليزية أو الفرنسية، وأنت متخوفٌ من RTL وتحسبها صعبةً ومرعبةً وستُضيف كمًا كبيرًا من العمل على مشروعك. حسنًا، الأمر ليس كما تظن، فبعد أن تستوعب المبادئ الأساسية، فلن تحتاج إلا لبذل جهدٍ قليلٍ. من البدهي أن تهتم –كمطور ويب عربي– بدعم الموقع التي تطوره للغة العربية (أو لبقية اللغات التي تُكتَب من اليمين إلى اليسار)؛ فلا حاجة لتذكيرك أنَّ هنالك أكثر من 410 مليون شخص حول العالم يتحدث لغةً تُكتَب من اليمين إلى اليسار (وهذا عددٌ ضخمٌ جدًا. لاحظ أنَّ الرقم التقديري السابق مبنيٌ على قائمة اللغات في ويكيبيديا). أصبحت أغلبية الشركات تُضيف دعمًا للغات المكتوب من اليمين إلى اليسار في برمجياتها (مثل ويندوز، و iOS، وأندرويد) وكذلك الأمر للعديد من المواقع العالمية؛ لذا سيتوقع زوار موقعك مِمَن يتحدثون العربية (وغيرها من اللغات المكتوبة من اليمين إلى اليسار) أن يحقق موقعك هذه التوقعات بما يخص دعم RTL. فبدون هذا الدعم قد لا يتحول زوار موقعك إلى زوارٍ دائمين. دورة تطوير واجهات المستخدم ابدأ عملك الحر بتطوير واجهات المواقع والمتاجر الإلكترونية فور انتهائك من الدورة اشترك الآن نصائح عامة لدعم اتجاه RTL هذه بعض القواعد العامة التي أحببت أن أذكرك بها والتي عليك أن تبقيها ببالك عند تطوير تطبيقات ومواقع ويب تدعم RTL: ابدأ من اليمين: تُفتح الكتب من الطرف الأيمن في البلدان التي تتحدث بلغاتٍ مكتوبةٍ من اليمين إلى اليسار، ولهذا يجب أن تُقلَب أغلبية عناصر الواجهة المتعلقة بمقروئية النص. الأزرار العتادية لها نفس الترتيب في البلدان المتحدثة بالعربية: أماكن أزرار التحكم بالأجهزة الصوتية هو نفسه في البلدان التي تتحدث لغاتٍ تكُتَب من اليمين إلى اليسار. لذا لن تتغير أماكن أزرار «التشغيل» و«التمرير» و«الإيقاف المؤقت» و«الإيقاف». ولهذا فلا يُنصَح أن يُقلَب اتجاه أيٌ من تلك الأزرار. مثالٌ آخر هو أزرار الهواتف، فقبل ظهور الهواتف الذكية كانت هنالك الهواتف الأرضية التي ما تزال شائعةً جدًا في البلدان العربية. ولهذا السبب يكون من المستحسن ألّا نعكس مفاتيح الأرقام. لا تظن أنَّ مستخدمي RTL هم أشخاصٌ يستعملون أياديهم اليسرى. فأغلبية مَن يتحدث بالعربية يكتبها بيده اليمنى، كما هو الحال في بقية أنحاء العالم. لذا لا تقلب أيّ شيءٍ ليس متعلقًا بكيفية قراءة المستخدم لمحتوى الصفحة. مثالٌ على هذا هو شريط التمرير «أ-ي A-Z» (الموجود على يمين الصورة السابقة) في تطبيق «جهات الاتصال» في أغلبية الهواتف الذكية. هذا الشريط موضوعٌ على الجهة اليمنى لأنه من الأسهل استخدامه باليد اليمنى، لذا لا حاجة إلى قلب اتجاهه وجعله في الجزء الأيسر في نمط RTL. كيفية جعل المحتوى RTL أول خطوة نحو جعل اتجاه صفحة الويب من اليمين إلى اليسار هي إضافة dir="rtl"‎ إلى وسم <html>: <html dir="rtl"> الخاصية dir هي اختصارٌ لكلمة «direction»، وضبط قيمتها إلى rtl تجعل نقطة البداية الأفقية لعناصر صفحة الويب من اليمين بدلًا من اليسار. لكي تضع نمط CSS لعنصرٍ معيّن إذا كانت الصفحة RTL فقط: أنشِئ نسخةً من أيّة أنماط CSS اعتيادية التي ستُطبَّق على العنصر الهدف. أضف المُحدِّد html[dir="rtl"] قبل سلسلة المُحدِدات (selector chain). كلما وجدت خاصيةً أو قيمة تُمثِّل التموضع الأفقي للعنصر، فاستعمل القاعدة المُعاكسة لها. على سبيل المثال، إذا وجدتَ float: left فبدِّلها إلى float: right. كمثالٍ عمليٍ على كلامنا السابق، إذا كان أحد أنماط CSS كالآتي: .someClass { text-align: left; padding: 0 10px 0 0; text-decoration: underline; } فسنأخذ نسخةً منه ونحدِّثها كالآتي: html[dir="rtl"] .someClass { text-align: right; padding: 0 0 0 10px; } لاحظ أننا حذفنا القاعدة text-decoration: underline;‎، فلسنا بحاجة إلى إعادة تعريف هذه القيمة لنسخة RTL لأنها لا تؤثر على اتجاه أي عنصر. وبالتالي ستُطبَّق القاعدة الأصلية. هذا مثالٌ أكثر تفصيلًا. يمكنك أن تجربه مباشرةً على متصفحك. شيفرة HTML: <html dir="ltr"> <body> <input type="button" id="directionSwitch" value="Switch LTR/RTL"/> <hr/> <div class="boxOne"></div> <div class="boxTwo"></div> </body> </html> شيفرة CSS: .boxOne { width: 170px; height: 170px; background-color: #0072C6; margin: 0 0 0 20px; } .boxTwo { width: 120px; height: 120px; background-color: #C3191E; margin: 0 0 0 70px; } html[dir="rtl"] .boxOne { margin: 0 20px 0 0; } html[dir="rtl"] .boxTwo { margin: 0 70px 0 0; } شيفرة JavaScript: document.getElementById('directionSwitch').addEventListener('click', function() { var docDirection = document.documentElement.dir; var isRTL = (docDirection === 'rtl'); document.documentElement.dir = isRTL ? 'ltr' : 'rtl'; }); لن تكون الحالات العملية بهذه البساطة؛ فهنالك تطبيقاتٌ فيها عددٌ كبيرٌ جدًا من قواعد CSS ومن المحددات، ولديك عدِّة استراتيجيات يمكنك اتباعها. وهذه إحداها: انسخ القواعد واحذف ما ليس لازمًا: أولًا، انسخ محتوى صفحة الأنماط إلى ملفٍ آخر، وأضف html[dir="rtl"] إلى جميع القواعد، ثم احذف أيّة خاصيات لا تتعلق بالاتجاه الأفقي للعناصر. وسينتهي بك المطاف بملفٍ صغيرٍ هدفه هو التعامل مع اتجاه RTL فقط. اقلب الاتجاهات: عدِّل كل الخاصية التي تُشير إلى اليسار (left) في الملف الجديد إلى معاكسها: أي padding-left ستصبح padding-right، و float: right ستصبح float: left …إلخ. لاحظ أنَّه إذا كان عندك خاصية padding-left في الملف الأصلي ثم عدَّلتها إلى padding-right فستبقى الخاصية الأصلية padding-left مطبقةً. لذا عليك إضافة الخاصية padding-left: unset بالإضافة إلى خاصية padding-right، وإلا فسيُطبِّق المتصفح كلا القاعدتين: خاصية padding-left من ملف CSS الأصلي وخاصية padding-right من الملف المعدَّل لاتجاه RTL. والأمر مشابهٌ لبقية الخاصيات مثل margin-left|right و border-left|right … أعد لصق المحتويات في الملف الأصلي: بعد أن تنتهي من إكمال الخطوتين السابقتين، فالصق القواعد الجديدة في الملف الملف الأصلي بعد القواعد الأصلية. أفضِّل شخصيًا أن أضيف تعليقًا صغيرًا مثل /* **** RTL Content **** */ لكي أستطيع التفريق بسهولة بين الأنماط الأصلية والأنماط المُعدَّلة لاتجاه RTL. طريقة أفضل: فصل أنماط RTL و LTR عن بعضهما قد تواجه في بعض الأحيان حالاتٍ غريبة التي يحدث فيها تضاربٌ بين الأنماط. وهذا يتضمن وراثة قيم بعض الخاصيات من خاصياتٍ أخرى، مما يعني أنَّك في بعض الأحيان لا تعرف تمامًا ما هي القاعدة التي عليك تجاوزها. وربما أضفتَ margin-right إلى قواعد RTL لكنك لستَ متأكدًا ما هي القيمة التي عليك ضبطها إلى خاصية margin-left الأصلية. أرى أنَّه من المستحسن أن تتبع منهجية أخرى، والتي هي أفضل في الحالات العملية لكنها أطول بعض الشّيء. سنفصل الخاصيات التابعة لكل اتجاه (RTL و LTR) عن بعضها بعضًا تمامًا. هذا مثالٌ عنها: لنقل أنَّنا لدينا قاعدة تتضمن ‎.wrapper .boxContainer .fancyBox كالآتية: .wrapper .boxContainer .fancyBox { text-align: left; padding-left: 10px; text-decoration: underline; color: #4A8CF7; } بدلًا من إضافة خاصيات أخرى لاتجاه RTL فيها padding-left و padding-right، فيمكنك أن تكتب: .wrapper .boxContainer .fancyBox { text-decoration: underline; color: #4A8CF7; } html[dir="ltr"] .wrapper .boxContainer .fancyBox { text-align: left; padding-left: 10px; } html[dir="rtl"] .wrapper .boxContainer .fancyBox { text-align: right; padding-right: 10px; } هذا الحل يتضمن ثلاثة أجزاء: القاعدة (أو المُحدِّد) الأصلية وفيها خاصياتٌ ليست متعلقة بالاتجاه، لأنها مشتركة بين الاتجاهين RTL و LTR. محدد يُعالج الاتجاه من اليسار إلى اليمين –html[dir="ltr"]– لا يوجد فيه سوى خاصيات لها علاقة بالاتجاه والتي تتوافق قيمها مع التخطيط (layout) الذي لديك لاتجاه LTR. مُحدِّد يعالج الاتجاه من اليمين إلى اليسار –html[dir="rtl"]– بنفس خاصيات حالة LTR، لكن قيمها مضبوطة لكي تتوافق مع التخطيط الذي لديك لاتجاه RTL. لاحظ كيف أنَّ القاعدة الثانية تملك خاصية padding-left فقط، بينما القاعدة الثالثة تملك خاصية padding-right فقط. وهذا لأنَّ كل واحد منها خاصة بالاتجاه المُحدَّد في خاصية dir. هذه الطريقة جيدة وجميلة ويسهل التعامل معها، ولا تحتاج فيها إلى حذف قيم بعض الخاصيات (لاحظ أنَّ الكلمة المحجوزة unset غير مدعومة في جميع المتصفحات. لأكبر قدر من التوافقية، عليك أن تُعيد تعريف القيمة التي ترغب بها لأي خاصية تريد حذف قيمتها). كيفية ضبط اتجاه الصفحة باستخدام JavaScript؟ هذا سهلٌ جدًا، ويتطلب سطرًا وحيدًا فقط: document.documentElement.dir يمكنك طباعة هذه القيمة إلى console كما يلي: var direction = document.documentElement.dir; console.log(direction); أو تستطيع تجربة المثال الحي. استعمل السطر الآتي لضبط اتجاه الصفحة: document.documentElement.dir = "rtl" هذا مثالٌ متكاملٌ حول الحصول على قيمة اتجاه الصفحة وضبطها: شيفرة HTML: <html dir="ltr"> <body> <input type="button" value="Set document direction to RTL" id="setDirection"/> <div id="directionStatus"></div> </body> </html> شيفرة JavaScript: function getDirection() { var direction = document.documentElement.dir; document.getElementById('directionStatus').textContent = 'This document\'s direction is: ' + direction; } var dirButton = document.getElementById('setDirection'); dirButton.addEventListener('click', function(evt) { var isRTL = (document.documentElement.dir === 'rtl'); document.documentElement.dir = isRTL ? 'ltr' : 'rtl'; dirButton.value = isRTL ? 'Set document direction to RTL' : 'Set document direction to LTR'; getDirection(); }); حلول مؤتمتة تحدثنا بما فيه الكفاية عن الطرق اليدوية لقلب الاتجاه إلى RTL. لننظر الآن إلى بعض الحلول المؤتمتة. css-flip طوَّرت تويتر حلًا لأتمتة كامل العملية وجعل قلب الاتجاه إلى RTL أسهل للمشاريع الكبيرة. هذا المشروع مفتوح المصدر ويمكنك أن تجده على Github. إضافة NPM هذه تغطي جميع الحالات التي قد تواجهها عندما تعمل على قلب الاتجاه إلى RTL، بما في ذلك الحالات الغريبة. بعض ميزاتها: no-flip: لإخبار مُحرِّك القلب أنَّك لا تريد أن تُقلَب هذه الخاصية وذلك بإضافة /* @noflip*/ في بداية الخاصية. على سبيل المثال، إذا كتبتَ ‎/* @noflip*/ float: left فستبقى الخاصية float: left عند تشغيل css-flip. replace: عندما تكون لديك صور خلفية تختلف بين RTL و LTR، فيمكنك أن تُحدِّد صورةً بديلةً بتضمين ‎/*@replace: url(my/image/path) */‎ قبل الخاصية الأصلية. فلنقل أنَّ لديك الخاصية background-image: url(arrow-left.png) وإذا حدثت السطر إلى ‎/*@replace: url(arrow-rightish.png) */ background-image: url(arrow-left.png);‎ فستصبح الخاصية النهائية في اتجاه RTL كالآتية: background-image: url(arrow-rightish.png);‎. يمكنك استعمال css-flip عبر سطر الأوامر بتنفيذ css-flip path/to/file.css > path/to/file.rtl.css أو عبر تضمين css-flip في صفحتك. للمزيد من المعلومات راجع مستودع github. يجدر بالذكر أنَّ css-flip يُستعمَل في برمجيات تويتر. rtlcss أداةٌ أخرى لأتمتة العملية برمجها «محمد يونس» تدعى rtlcss التي تتوفر على github وتوفر ميزاتٍ رائعة. يمكنك باستخدام هذه الأداة أن: تعيد تسمية القواعد (مثلًا، إعادة تسمية ‎#boxLeft إلى ‎#boxRightSide). تتجاهل بعض القواعد من عملية القلب. تتجاهل خاصياتٍ معينة. تضيف قيمًا جديدة. تضيف قيم خاصيات جديدة بين قيم الخاصيات الأخرى. يمكنك استخدام هذه الأداة عبر سطر الأوامر؛ ويمكنك إنشاء ملف أنماط RTL بتنفيذ الأمر الآتي في نفس المجلد الذي يتوفر فيه ملف CSS الأصلي: rtlcss input.css output.rtl.css أو يمكنك أن تضمنه في صفحتك. للمزيد من المعلومات راجع صفحة المشروع على github. هذا المشروع مشهور جدًا ويستعمل من عدِّة مشاريع بما فيها ووردبريس. خاتمة ما يزال هنالك الكثير لنغطيه، لكن هذه المقالة أمدتك بالمعلومات اللازمة لبدء مشوارك مع RTL. سنشرح في المقالة القادمة مواضيع متقدمة عن RTL. إذا كانت لديك أيّة أسئلة حول RTL، فاطرحها في التعليقات. ترجمة -وبتصرّف- للمقال Building RTL-Aware Web Apps & Websites: Part 1 لصاحبه أحمد نفزاوي
  25. مضت فترةٌ لا بأس بها على ظهور إطارات العمل، وازدادت شهرتها في مجال تطوير واجهات المواقع. توفِّر تلك الإطارات مقتطفاتٍ من الشيفرات التي تستطيع نسخها ولصقها في موقعك لبناء تخطيط الصفحة وواجهة المستخدم. ربما قرأت مقالاتٍ كثيرة عن كيفية الاستفادة من تلك الإطارات في مشاريعك، لكنني هنا لأفعل العكس: أنوهك لبعض السلبيات التي قد تجلبها إطارات العمل إلى مواقعك أو تطبيقات الويب التي تبرمجها؛ وكيف تستطيع أن تتفاداها أو تقلل من تأثيرها. عندما أسألُ الآخرين لماذا يستعملون إطار عملٍ معيّن، فسيقع جوابهم تحت التصنيفات الآتية: السرعة: أغلبية الأشخاص يعتقدون أنهم سيطورون الموقع بشكلٍ أسرع. وربما يكون هذا صحيحًا في المراحل الأولى للمشروع؛ لكنه سيشكِّل حِملًا على عاتقك (سنتعرف لاحقًا لماذا). يعتقد بعض الأشخاص أنَّه من المستحسن أن يستعملوا إطار عمل، خصوصًا أولاءك الذين يبدؤون تطوير واجهات الويب لتوِّهم. ويدعم هذا الاعتقاد تضمين إطارات العمل في الورشات التدريبية أو في متطلبات الوظائف. التصميم: هنالك الكثير من المطورين الذين يرغبون بإطلاق مشاريعهم لكن لا يتوفر لديهم مصمِّم، لذا يلجؤون إلى إطارات العمل، التي توفِّر تصميمًا أساسيًا يستطيع المطورون الاعتماد عليه واستخدامه. وعلى الرغم من الفائدة العظيمة وراء ذلك، إلا أنَّ موقعك أو تطبيقك سينتهي به المطاف ليبدو كغيره من المواقع الحديثة الموجودة على الإنترنت، لكن قد ترى أنَّ ذلك لا يؤثر على مشروعك، فالأمر عائدٌ إليك في النهاية. السلبيات بغض النظر عن الأسباب التي تدفعك لاستخدام إطارات العمل، هنالك سلبيات لها. لكن قد تتغاضى عنها في بعض الحالات لكي تنشر مشروعك في أسرع وقت ممكن أو لتبني نسخةً أوليةً التي لن تَستعمِل شيفرتها في مشروعك النهائي. بيد أنَّ تلك السلبيات، إن وجدت في موقعٍ أو تطبيقٍ منشورٍ على الشبكة، قد تُسبِّب عرقلة عملية التطوير أو جعلها صعبة الإدارة. شيفرات HTML لا تحمل بُعدًا دلاليًا (Unsemantic HTML code) هذه المشكلة ليس مقتصرةً على إطارات العمل، لكنني أراها متفشيةً كثيرًا في أشهرها. على سبيل المثال، ربما تقرأ في توثيق إطار العمل الذي يتحدث عن تنسيق الأزرار، وتجد قطعةً من الشيفرات تخبرك كيف تستخدم صنفًا (class) من أصناف CSS للأزرار المُعطَّلة (disabled) بدلًا من إضافة خاصية disabled إلى عنصر <button> نفسه. وهنالك أمثلةٌ كثيرةٌ تستعمل عناصر <div> أو <span> في أماكن يُفضَّل أن يُستعمَل فيها عنصرٌ هيكليٌ مثل <article> أو <date>. ودعنا لا نتحدث عن وجود عنصر <div> داخل عنصر <div> داخل عنصر <div>… مُحدِّدات دقيقة جدًا مرةً أخرى، هذه المشكلة ليست خاصة بإطارات العمل، لكن يمكنك ملاحظتها في أشهرها: الميل إلى استخدام مُحدِّدات (selectors) دقيقة جدًا لإنشاء قواعد CSS. على سبيل المثال: .table-responsive > .table-bordered > thead > tr > th:first-child ماذا يحدث لو حاولت تجاوز بعض خاصيات <th>؟ ستحتاج إلى إنشاء مُحدَّد أكثر دقةً وتخصيصًا! لا يمكنك استعمال قاعدة CSS كالآتية: th.important-heading { color: #000; } وإنما عليك إنشاء قاعدة مثل هذه: .table-responsive > .table-bordered > thead > tr > th:first-child.important-heading { color: #000; } الذي يحدث فعلًا هو أنَّ الجميع يتفادون كتابة مثل هذه الشيفرات. لذا سنبدأ برؤية مثل هذه القاعدة: th.important-heading { color: #000; !important } والتي تزيد من تعقيد الأمر بشكل أكبر. قواعد لا تحتاج لها إذا ضمَّنتَ إطار العمل بأكمله بدلًا من استخدامك لأجزاءٍ تحتاج لها منه، فسينتهي بك المطاف بقواعد CSS لا تستعملها. ربما تتعامل مع هذه الحالة بمساعدة أدوات لمعالجة الشيفرات لإزالة القواعد غير المستخدمة، لكن عندما تبدأ بإضافة أو إزالة الأصناف (classes) ديناميكيًا باستخدام JavaScript، فلن تكون متأكدًا 100% أنَّك لن تحتاج إلى تلك الشيفرات. قواعد CSS غير المستخدمة تجعل ملفاتك كبيرةً، مما يُشكِّل مشكلةً للهواتف النقالة التي تتصل بالإنترنت عبر الشبكة الخلوية بدلًا من Wi-Fi. لكنك علاوةً على ذلك، ستجعل كمية الشيفرات في مشروعك كبيرةً مما يُصعِّب عملية الصيانة وتتبع الأخطاء. اتخذ قرارك جميع إطارات العمل تتبع وجهات نظر معيّنة، وهذه ليس مشكلةً إذا كانت لديك وجهة نظر متطابقة مع إطار العمل. لكن في بعض الأحيان لا تتطابق وجهة نظرك مع أسلوب إطار العمل. على سبيل المثال، هذه هي شيفرة HTML التي يقترحها أحد إطارات العمل لإنشاء لافتات نصيّة (text labels) ملونة: <span class=“label label-warning”>Out of stock</span> أرى أنَّ أسماء الأصناف مكررة، لأنني أفضِّل استخدام الأصناف التي أجدها ضروريةً فقط. إذا كنتُ صاحب الشيفرة السابقة، فسأستخدم الصنف label-warning فقط. ماذا لو كنتَ معجبًا بإحدى طرق الهيكلة في CSS التي لا يستعملها إطار عملك؟ بدائل إطارات العمل كتابة شيفرات HTML و CSS يدويًا! إذا لم تحب الشيفرات التي يُنتِجها إطار العمل، فلِمَ لا تكتب الشيفرات الخاصة بك. إذا كانت القواعد التي يوفرها إطار العمل تجعلك لا تعمل بكفاءة، فيجدر بك كتابة قواعدك الخاصة. إذا كنتَ تحتاج إلى شبكة (grid)، فيمكنك أن تستعمل Flexbox، التي تُسهِّل إنشاء تخطيط للصفحة مقارنةً مع استعمال عناصر <div> عائمة (float). إذا لم تكن تعرف كيفية التعامل مع Flexbox، فألق نظرة على هذا هذا الدرس. وإذا أردتَ أن تعرف كيف ستبدو الشيفرة، فانظر إلى المثال الآتي: شيفرة HTML <header class="main-header">Header</header> <div class="row"> <aside class="primary-sidebar">Sidebar (left)</aside> <main class="content">Main content goes here</main> <aside class="secondary-sidebar">Sidebar (right)</aside> </div> <footer class="main-footer">Footer</footer> شيفرة CSS * { padding: 0; margin: 0; } body { font-size: 1.2em; display: flex; flex-direction: column; height: 100vh; text-align: center; } .row { flex: 1 1 auto; background: green; display: flex; } .main-header { background: red; flex: 0 0 auto; } .main-footer { background: red; flex: 0 0 auto; } .primary-sidebar, .secondary-sidebar { background: turquoise; flex: 0 0 auto; width: 20%; } .content { flex: 1 1 auto; min-width: 400px; } سيكون لدينا Grid في المستقبل القريب، والتي ستُسهِّل إنشاء الشّبكات، ولن تشعر أنَّك بحاجة إلى استعمال شبكة أخرى قط. ملاحظة: لكي ترى الناتج على متصفحك، فجرِّب النسخة الليلية من Firefox أو آخر نسخة من متصفح Firefox Developer Edition. أما لكي تُشاهد هذه الأمثلة في نسخة Firefox أخرى، فعليك تفعيل الراية layout.css.grid.enabled بالذهاب إلى about:config. شيفرة HTML <header class="main-header">Header</header> <main class="content">Main content goes here</main> <aside class="primary-sidebar">Sidebar (left)</aside> <aside class="secondary-sidebar">Sidebar (right)</aside> <footer class="main-footer">Footer</footer> شيفرة CSS * { padding: 0; margin: 0; } body { font-size: 1.2em; text-align: center; height: 100vh; display: grid; grid-template-columns: 20% 1fr 20%; grid-template-rows: auto 1fr auto; grid-template-areas: "header header header" "sidebar-pri content sidebar-alt" "footer footer footer"; } .main-header { background: red; grid-area: header; } .main-footer { background: red; grid-area: footer; } .primary-sidebar, .secondary-sidebar { background: turquoise; } .primary-sidebar { grid-area: sidebar-pri; } .secondary-sidebar { grid-area: sidebar-alt; } .content { background: green; grid-area: content; } إذا كنتَ تحتاج إلى بعض عناصر الواجهة الرسومية، مثل القوائم المنسدلة، فلا حاجة إلى كتابتها من الصفر، وإنما تستطيع أخذ ذاك الجزء من إطار العمل (عوضًا عن كامل الإطار) أو أن تستعمل مكتبة خارجية ليس لها اعتماديات. إذ كنتَ تحتاج إلى تصميمٍ لواجهة موقعك أو تطبيقك، فيمكنك أن تحصل على ملفات Sass أو Less بدلًا من شيفرات CSS النهائية. وبهذا تستطيع إنشاء مُحدِّدات خاصة بك، مما يسمح لك باستخدام شيفرات HTML كما تحب. لكن تذكّر بأنَّ موقعك سيبدو كغيره من العديد من المواقع. إذا كنتَ تريد طريقةً لتوحيد عملية إنشاء عناصر الواجهة الرسومية في مشروعك، لكي يعرف الآخرون ما هي الشيفرة التي يجب أن يستخدموها وكيف يُضيفون عناصر جديدة؛ فالذي تبحث عنه هو «دليل لكتابة الأنماط» (style guide. باختصار: إطار عمل خاص بك). أرى أنَّ عليك استخدام هذه الطريقة في المشاريع الكبيرة. الخلاصة هنالك إيجابياتٌ كثيرة لاستخدام إطارات العمل، لكن هنالك أيضًا سلبياتٌ عليك توخي الحذر منها، ولا تنسَ أن تتعرف على الأدوات والواجهات البرمجية (APIs) المتاحة لك لإنشاء أنماط CSS خاصة بمشروعك أو تطبيقك. ترجمة -وبتصرّف- للمقال You might not need a CSS framework لصاحبته Belén Albeza.
×
×
  • أضف...