لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 06/10/15 in مقالات البرمجة
-
هل صنعت قالب HTML وأحببته لكنّك لم تعرف كيف تُحوّله إلى قالب ووردبريس؟ ليس بعد الآن، ستتعلم في هذا الدرس كيف تقوم بذلك. هل تعلم بأنّ هناك الكثير من المُطوّرين الذين يكسبون رزقهم عن طريق إنشاء قوالب وإضافات ووردبريس (Wordpress) وبيعها؟ وهل تعلم أنّه بإمكان مطوّري ووردبريس الحصول على آلاف الدولارات سنويًَّا من خلال بيع مُنتجاتهم؟ هذا الدّرس مُخصّص لمطوّري الويب، على فرض أن القارئ على اطّلاع (ولو بشكل مُبسّط) بما يتعلّق بلغة PHP وMySQL ومعلومات عامّة عن كيفية تنصيب واستخدام ووردبريس. هذا الدرس جزء من سلسلة تعلم كيفية تطوير قوالب ووردبريس: مقدمة إلى تطوير قوالب ووردبريس: تحويل صفحة HTML إلى قالب ووردبريس (هذا الدرس) التصفيح (Pagination) في قوالب ووردبريس إضافة قوائم التنقل (Navigation Menu) إلى قالب ووردبريس صف وتسجيل ملفات Javascript و CSS في قوالب ووردبريس متطلبات التّشغيل نحتاج إلى تحميل نسخة ووردبريس من الموقع الرسمي ، سنستخدم النّسخة العربية من هذا الرّابط. تحتاج ووردبريس إلى خادوم ويب، سواء كان Apache أو Nginx أو الخادوم المُدمج مع لغة PHP (بإصدار5.4 وما فوق). وتحتاج أيضًا إلى خادوم قواعد البيانات MySQL. لنقم بإنشاء مُجلّد جديد wordpress_tutorials ونضع فيه نسخة ووردبريس النّاتجة عن فكّ ضغط الملف الذي قمنا بتحميله. ملاحظة: يمكن أن تستخدم البرامج المُجهّزة خصّيصًا بخواديم Apache و MySQL مثل MAMP ،WAMP أو XAMPP. مع مُراعاة الاختلاف بين رابط خادوم الويب ومعلومات خادوم MySQL مع ما سنستخدمه في هذا الدّرس. سنقوم باستخدام الخادوم المُدمج مع PHP لتجنّب تنصيب خادوم Apache أو Nginx وتجنب الخوض في الإعدادات الخاصّة بكل واحد منها. لتشغيل الخادوم المُدمج نتوجه باستخدام سطر اﻷوامر إلى المجلّد الذي يحوي نسخة ووردبريس. ثم نكتب أمر: php -S localhost:8000 يتمّ تشغيل خادوم الويب المُدمج مع PHP على الحاسوب، يمكن التّوجّه عن طريق المُتصفّح إلى الرّابط localhost:8000 للتّأكد من أن الخادوم يعمل. تهيئة قالب HTML سنقوم بالاعتماد على قالبٍ قمتُ بإعداده مُسبقاً، يمكن تحميله من هذا الرابط، التّصميم عبارة عن قالب عادي يحوي بضع ملفّات HTML ،CSS و JavaScript. وهو مبني اعتمادًا على إطار عمل Foundation مع بعض التّعديلات والإضافات. هذا القالب تجريبيّ فقط لرؤية كيفية ظهور الشكل العامّ له. نتوجه إلى مجلّد المشروع الذي يحوي ملفات ووردبريس، ومنه نتوجّه إلى مجلد wp-content ثم إلى مُجلّد themes. نقوم بإنشاء مُجلّد اسمه my_theme بمثابة مُجلّد القالب الذي سنقوم بإنشائه. ملفات القالب الأساسية نحتاج إلى وجود ملفّين على الأقل ضمن مجلد القالب الذي أنشأناه، وهما: - style.css - index.php وهذا أقل ما يجب توفّره في القالب ليكون قالبًا صالحًا للاستخدام. نتجه إلى صفحة تغيير القوالب من لوحة تحكم ووردبريس لنرى ما يشبه: كما تلاحظون لا نرى القالب الجديد الذي أنشأناه ضمن القوالب، وذلك ﻷن هناك شيئًا آخر علينا فعله قبل أن نرى القالب الجديد في هذه الصفحة. نحتاج إلى إضافة تعليق في ملف style.css كالتّالي (يمكن تعديل أيّ قيمة أيضًا): /* Theme Name: قالبي الجديد Author: عمار العقاد Author URI: http://aalakkad.me Description: قالب جديد، نقوم من خلاله بالتّدرّب على إنشاء قوالب WordPress. Version: 1.0 */ تقوم ووردبريس بالدخول إلى كل مجلد في مجلد القوالب، ثم تبحث عن ملف style.css بداخله تعليق يشبه التّعليق السابق، ثم تقوم بتفسير هذه التّعليقات ووضعها في صفحة القوالب التي تظهر للمُستخدم من خلالها أسماء وتوصيف القوالب. وهناك تفصيلات أخرى للتعليقات في ملف style.css يمكن الاطلاع عليها كاملة من ملفات التوثيق. يمكن التوجه إلى صفحة القوالب من خلال لوحة التحكم، لنرى شيئًا مُشابهًا لما يلي: لنقم بتفعيل هذا القالب الجديد، ثم نتوجّه إلى الصّفحة الرّئيسية للمُدوّنة (الصفحة التي تُظهر المقالات وليست صفحة لوحة التّحكم). إن كنت تستخدم الخادوم المُدمج مع PHP بالطريقة التي ذكرناها، فيكون رابط الصّفحة الرئيسية هو: localhost:8000. سنرى صفحة بيضاء دون أن تحوي أيّ شيء، وذلك ﻷن القالب ما زال فارغًا تمامًا. سيتغيّر الوضع بعد قليل. نقل قالب HTML إلى قالب ووردبريس ما سنفعله في الخطوة الأولى هو وضع قالب HTML في ملف index.php ثم نقوم بتعديل مسارات ملفات CSS و JavaScript. ستكون جميع الصفحات التي نستخدمها من ووردبريس بعد تفعيل القالب الجديد مُتطابقة، وكأنها قالب HTML نفسه. وهذا هو المطلوب في هذه المرحلة، سنقوم بإضافة التّفاصيل فيما بعد وعلى عدة مراحل. نقوم الآن بنسخ محتوى ملف index.html كاملًا من قالب HTML ونضعه في ملف index.php في قالبنا الجديد my_theme ضمن ووردبريس. ثم ننسخ مجلد assets كما هو إلى داخل مجلد قالبنا الجديد. لنرى كيف أصبح شكل الموقع بعد أن وضعنا محتوى ملف index.html في ملف index.php: يظهر الآن القالب بهذا الشّكل ﻷن ملفات CSS وJavaScript أصبحت في مسار مختلف عن المسار الذي كان موجودًا في قالب HTML. علينا الآن أن نقوم بتعديل مسارات هذه الملفات كي يُصبح شكل قالب ووردبريس الجديد مُطابقًا لشكل قالب HTML. توفّر لنا ووردبريس عددًا من الدّوالّ (functions) مهمتها تسهيل إنشاء القوالب، سنستخدم منها get_template_directory_uri()، تقوم هذه الدالّة بإرجاع قيمة نصّيّة هي رابط القالب. مثلاً، إن كان مجلد القالب هو my_theme ورابط خادوم الويب الذي نعمل عليه هو http://localhost:8000 ستكون نتيجة الدالّة هي: http://localhost:8000/wp-content/my_theme يجب أن نستخدم هذه الدالّة أو ما يشابهها لنحصل على الرّوابط، ولا نستخدم روابط نضعها بشكل يدوي، فيُمكن لرابط خادوم الويب أن يتغير، وإن كانت الروابط موضوعةً بشكل يدوي فسيظهر شكل القالب كما في الأعلى خاليًّا من ملفات CSS و .JavaScript. نقوم بتعديل ملف index.html في قسم head، نبحث عن سطر استدعاء ملفات CSS، ثم نقوم بالتّعديل عليها لتصبح بالشّكل: في قسم head أيضًا نُريد استبدال رابط استدعاء ملف modernizr.js ليستخدم دالّة get_template_directory()، فيُصبح: <script src="<?php echo get_template_directory_uri(); ?>/assets/js/modernizr.js"></script> أخيرًا نبحث في نهاية ملف index.php عن سطر استدعاء ملف JavaScript، ونقوم بالتّعديل عليه ليُصبح كما يلي: <script src="<?php echo get_template_directory_uri(); ?>/assets/js/vendor.js"></script> الآن عندما يتم طلب المُدوّنة من المُتصفّح، ستكون النّتيجة النّهائية للتعديلات الثلاثة التي قمنها بها كالتالي: <link rel="stylesheet" href="http://localhost:8000/wp-content/themes/my_theme/assets/css/main.css"> <script src="http://localhost:8000/wp-content/themes/my_theme/assets/js/modernizr.js"></script> <script src="http://localhost:8000/wp-content/themes/my_theme/assets/js/vendor.js"></script> نذهب الآن إلى الصّفحة الرّئيسية للمُدوّنة لنرى كيف أصبح القالب. في آخر فقرة من هذا الدرس سنقوم بتعديل ترويسة الموقع التي نصّها الحالي هو: "عنوان الموقع"، والذي يظهر في الجُزء العُلويّ. نريد تغيير هذا النصّ ليصبح اسم المدونة التي قمنا بإدخالها أثناء مرحلة التّنصيب، يمكنك تغيير اسم المدونة من لوحة التحكم ثم الإعدادات. لنفتح صفحة index.php في المُحرّر، ثم نبحث عن السطر الذي يحوي: <h1 class="logo">عنون الموقع</h1> ,نقوم باستبداله بما يلي بعض إضافة وسم PHP له: <h1 class="logo"><?php bloginfo('name'); ?></h1> وسم: <?php php bloginfo('name'); ?> يقوم بإظهار/طباعة نصّ يتم جلبه من قاعدة البيانات، النصّ هو اسم المُدوّنة. نلاحظ أن الدّالّة bloginfo() تقوم بالإظهار وليست الإرجاع return كما تفعل دالّة ()get_template_directory_uri. الآن عندما نتوجّه إلى الصفحة الرئيسية للمدونة تكون الترويسة شبيهة بالصورة: فصل محتوى الملفات من قواعد البرمجة الهامة إلغاء التّرابط أو الفصل (decoupling)، فنحاول فصل العناصر المُترابطة قدر الإمكان ووضعها في ملفات مُنفصلة. مثلًا سنقوم لاحقًا بإنشاء صفحة خاصّة لعرض المواضيع المُنفردة، وستحتاج تلك الصّفحة إلى وجود الترويسة (header) والتذييل (footer) كي تحوي ملفات CSS و JavaScript وتكون متناغمة مع باقي القالب. توفّر لنا ووردبريس عدة طُرق لإلغاء التّرابط في الملفات، إمّا أن يتم استخدام التّسلسل الهرمي لملفّات القالب (theme hierarchy) أو يتم استخدام قِطَع القالب (template parts). التّسلسل الهرمي لملفّات القالب (أو ملفات القالب للاختصار) هي ملفات بأسماء ثابتة، تقوم ووردبريس باستخدام الملف المُتوفّر منها حسب الطلب الذي يأتيها من المتصفح؛ مثلاً طلبتَ من المدونة رابط مقالٍ معيّن، تقوم ووردبريس بتحليل الطّلب ومعرفة أن المطلوب هو مقال، فتبحث عن ملف باسم single.php، إن كان موجودًا يتمّ استخدامه، إن لم يكن موجودًا تبحث ووردبريس عن ملف index.php. وهكذا الأمر بالنسبة لجميع الطلبات. أما قِطع القالب، فهي ملفات يقوم المستخدم بإنشائها دون أن يلتزم باستخدام أسماء مُحدّدة كما في ملفات القالب. ثم يقوم المطوّر باستخدام هذه القِطع في أي مكان يريده ضمن القالب. يقوم المُطوّر مثلًا بإنشاء قطعة مُخصّصة لعرض أزرار المُشاركة، يقوم بتسمية الملف: sharing.php، ويضع فيه الوسوم التي يُريدها. ثم يقوم باستدعاء هذا الملف في الصّفحة الرّئيسيّة index.php وصفحة المقال المُنفرد single.php على النّحو التّالي: <?php get_template_part('sharing'); ?> هناك تفصيلات حول كيفية إنشاء قطع القالب والتّعامل معها، ما سنذكره هنا فقط لإعطاء فكرة عامة عنها وليس لشرحها بالتّفصيل. سنستخدم في هذا الدرس التّسلسل الهرمي فقط لسهولته وشهرته. إن كان الاسم غريبًا بالنّسبة إليك فستألفه بمُجرد أن تشرع في استخدامه. سنقوم بإنشاء 3 ملفّات في القالب هي: - header.php - footer.php - sidebar.php ومن ثم يمكننا استخدام هذه الملفّات في أي مكان ضمن القالب عن طريق الدّوال: - get_header() - get_footer() - get_sidebar() هذه الدّوال تعمل بشكل مُشابه لـ require التّي نعرفها في لغة PHP. بهذه الطّريقة لن نحتاج إلى القيام بالنّسخ واللصق في كل مرة نريد إدراج الترويسة في ملفات القالب، وفي حال أردنا تعديل شيء في الترويسة فلن نضطرّ إلى تطبيق التعديل في جميع ملفات القالب. الخطوة التّالية هي نقل المحتوى المُناسب لكل ملفّ من الملفّات السّابقة من ملف index.php إلى الملفّات الثّلاثة الجديدة التي أنشأناها. سنقوم حرفيًا بالنّسخ واللّصق من ملف index.php إلى الملفات الثّلاثة، ثم نقوم بوضع إحدى الدّوال الثلاثة في ملف index.php بدل النصّ الذي قمنا باقتصاصه. ملف الترويسة header.php نقوم باقتصاص مُحتوى ملف index.php من بدايته وحتى نهاية وسم </header> في السطر 57. نضع ما اقتصصناه في ملف header.php. ثم نضع مكان الاقتصاص في ملف index.php ما يلي: <?php get_header(); ?> فتصبح بداية ملف index.php مشابهةً لما يلي: <?php get_header(); ?> <div class="main-content"> <div class="row"> ملف التذييل footer.php نقوم الآن باقتصاص الجزء الخاص بالتذييل من ملف index.php، في السطر 71 بدءاً من وسم: <div class="site-footer"> وحتى نهاية الملف. نقوم بوضع المُحتوى في ملف footer.php، ثم نستبدل مكان الوسوم المقصوصة في ملف index.php بما يلي: <?php get_footer(); ?> ملف الشريط الجانبي sidebar.php الوسوم الخاصّة بالشريط الجانبي ما هي إلا أربعة أسطر، تبدأ من السطر 64، المحتوى هو: <div class="large-4 columns sidebar"> <div class="card"> Sidebar </div> </div> نقوم بنقل المحتوى السّابق من ملف index.php إلى ملف sidebar.php، ونضع مكانه في ملف index.php: <?php get_sidebar(); ?> بهذا ننتهي من المرحلة الأولى من إلغاء الترابط بين الوسوم، وضعنا كل جزءٍ منها في ملفٍّ خاصٍّ به، وكلما أردنا استخدام ذلك الجزء نقوم باستدعاء الدّالّة المناسبة لذلك. أصبح ملف index.php أقصر طولًا، ويؤدّي نفس الغرض الذي كان يؤدّيه قبل أن نقوم بالتّعديلات، محتوى الملف كالتالي: <?php get_header(); ?> <div class="main-content"> <div class="row"> <div class="large-8 right columns news"> <div class="row"> <div class="medium-12 columns"> <article class="card"> <header> <h1>Post title</h1> </header> <div class="date">4 كانون الأول 2014</div> <p>خلافاَ للاعتقاد <a href="#">السائد</a> فإن لوريم إيبسوم ليس نصاَ عشوائياً، بنذ العام 45 قبل الميلاد، مما يجعله أكثر من 2000 عام في القدم. قام البروفيسور "ريتشارد ماك لينتوك" (Richard McClintock) وهو بروفيسور اللغة اللاتينية في جامعة هامبدن-سيدني في فيرجينيا بالبحث عن أصول كلمة لاتينية غامضة في نص لوريم إيبسوم وهي "consectetur"، وخلال تتبعه لهذه الكلمة في الأدب اللاتيني اكتشف المصدر الغير قابل للشك. فلقد اتضح أن كلمات نص لوريم إيبسوم تأتي من الأقسام 1.10.32 و 1.10.33 من كتاب "حول أقاصي الخير والشر" (de Finibus Bonorum et Malorum) للمفكر شيشيرون (Cicero) والذي كتبه في عام 45 قبل الميلاد. هذا الكتاب هو بمثابة مقالة علمية مطولة في نظرية الأخلاق، وكان له شعبية كبيرة في عصر النهضة. السطر الأول من لوريم إيبسوم "Lorem ipsum dolor sit amet.." يأتي من سطر في القسم 1.20.32 من هذا الكتاب.</p> <div class="read-more text-left"> <a href="#">تابع قراءة المقال »</a> </div> <footer class="tags"> <span class="label">تقني</span> <span class="label">تنمية</span> <span class="label">منوعات</span> </footer> </article> </div> <div class="medium-12 columns"> <article class="card"> <header> <h1>Post title</h1> </header> <div class="date">4 كانون الأول 2014</div> <p>خلافاَ للاعتقاد <a href="#">السائد</a> فإن لوريم إيبسوم ليس نصاَ عشوائياً، بنذ العام 45 قبل الميلاد، مما يجعله أكثر من 2000 عام في القدم. قام البروفيسور "ريتشارد ماك لينتوك" (Richard McClintock) وهو بروفيسور اللغة اللاتينية في جامعة هامبدن-سيدني في فيرجينيا بالبحث عن أصول كلمة لاتينية غامضة في نص لوريم إيبسوم وهي "consectetur"، وخلال تتبعه لهذه الكلمة في الأدب اللاتيني اكتشف المصدر الغير قابل للشك. فلقد اتضح أن كلمات نص لوريم إيبسوم تأتي من الأقسام 1.10.32 و 1.10.33 من كتاب "حول أقاصي الخير والشر" (de Finibus Bonorum et Malorum) للمفكر شيشيرون (Cicero) والذي كتبه في عام 45 قبل الميلاد. هذا الكتاب هو بمثابة مقالة علمية مطولة في نظرية الأخلاق، وكان له شعبية كبيرة في عصر النهضة. السطر الأول من لوريم إيبسوم "Lorem ipsum dolor sit amet.." يأتي من سطر في القسم 1.20.32 من هذا الكتاب.</p> <div class="read-more text-left"> <a href="#">تابع قراءة المقال »</a> </div> <footer class="tags"> <span class="label">تقني</span> <span class="label">تنمية</span> </footer> </article> </div> </div> <div class="row"> <div class="medium-12 columns"> <ul class="pagination"> <li class="arrow unavailable"><a href="">«</a></li> <li class="current"><a href="">1</a></li> <li><a href="">2</a></li> <li><a href="">3</a></li> <li><a href="">4</a></li> <li class="unavailable"><a href="">…</a></li> <li><a href="">12</a></li> <li><a href="">13</a></li> <li class="arrow"><a href="">»</a></li> </ul> </div> </div> </div> <?php get_sidebar(); ?> </div> </div> <?php get_footer(); ?> جلب المقالات من قاعدة البيانات نحتاج الآن إلى عرض المقالات المحفوظة في قاعدة البيانات (والتي يتم التّحكم فيها من لوحة التّحكم الخاصّة بووردبريس)، سنقوم بعرضها في ملف index.php وفي دروس لاحقة سنستخدم نفس طريقة عرض المقالات في باقي ملفات القالب، سواءً في ملف single.php أو في archive.php أو في غيرها. ضمن ملف index.php نجد أن كل مقال مُحاط بالوسوم: <div class="medium-12 columns"> <article class="card"> كل مقال يجب أن يبدأ بهذه الوسوم، وينتهي بإغلاق هذه الوسوم. نلاحظ أن قالب HTML يحوي مقالين شكليين، سنحذف واحدًا منها ونكتفي بالآخر لنقوم باستخدامه كمعيار لعرض المقالات مثله. نحيط وسوم بداية المقال بالحلقة الرّئيسية التي تكلّمنا عنها سابقًا، فتُصبح الوسوم كما يلي: <?php while(have_posts()) { the_post(); ?> <div class="medium-12 columns"> <article class="card"> وبعد إغلاق الوُسوم التي بدأ المقال عندها نضع نهاية الحلقة (قوس إغلاق الحلقة) كما يلي: </article> </div> <?php } ?> إن قمنا بحفظ التّعديلات والتجربة، سنجد أن المقال الشّكليّ سيتكرّر بعدد المقالات الموجودة في قاعدة بيانات ووردبريس لدينا. لكن جميع المقالات ستكون بنفس الشّكل وبنفس المُحتوى. سنقوم الآن باستبدال المُحتوى الشّكليّ بالمُحتوى المُناسب من قاعدة البيانات حسب كل مقال. تقدم ووردبريس دالّة the_title لطباعة عُنوان المقال الحالي، سنستخدمها بدل عنوان المقال الشّكلي، فتصبح الوسوم كما يلي: <h1><?php the_title();?></h1> وبنفس الطريقة نستخدم دالّة the_date لعرض تاريخ نشر المقال كما يلي: <div class="date"><?php the_date();?></div> ثم لعرض محتوى المقال نستخدم دالّة the_content بدل وسم <p></p> الذي يحوي المحتوى الشكليّ، كما يلي: <p><?php the_content();?></p> يُمكن أن نقوم بحفظ التّعديلات على الملف ومشاهدة النّتيجة في المُتصفّح لنتأكد من أن التّعديلات التي قمنا بها تم تطبيقها وتعرض النّتيجة الصّحيحة. بقي لدينا تعديلان مُشابهان لما قمنا به، الأول لتعديل رابط “تابع قراءة المقال” والثاني لعرض الوسوم الخاصّة بالمقال. لتعديل رابط المقال نستخدم دالّة the_permalink التي وظيفتها عرض رابط الويب الخاصّ بالمقال، لكن لا تقوم الدّالّة سوى بطباعة الرّابط دون وضعه في وسم <a></a> كي يصبح قابلًا للنّقر والاستخدام. علينا إذًا وضع الرّابط في مكانه المُناسب كما يلي: <a href="<?php the_permalink();?>">تابع قراءة المقال »</a> قمنا باستبدال قيمة حقل href="#" بدالّة طباعة رابط المقال. الآن أصبح بإمكاننا مُشاهدة الصّفحة الرّئيسيّة للقالب التي تعرض المقالات ويمكن الضّغط على رابط “تابع قراءة المقال” للوصول إلى المقال بعينه ضمن صفحة مُستقلّة. بقي الآن أن نعرض الوسوم الخاصّة بكل مقال. مكان الوسوم هو داخل وسم: <footer class="tags"> </footer> سنقوم باستخدام دالّة wp_get_post_tags التي مهمتها إرجاع مصفوفة تحوي جميع الوسوم الخاصّة بالمقال على شكل كائنات (Objects) وليس مُجرّد نصّ عادي. وعليه فإنه سيكون بإمكاننا الوصول إلى اسم كل وسم عن طريق: tag->name$ كما يلي: <footer class="tags"> <?php $tags = wp_get_post_tags(get_the_ID()); foreach($tags as $tag) { echo '<span class="label"> ' . $tag->name . '</span> '; } </footer> يُمكننا الآن استعراض المقالات في الصّفحة الرّئيسية للمُدوّنة والوصول إلى كل مقال عن طريق الرّابط الخاص به ورؤية الوسوم الخاصّة بكل مقال أيضًا. سنتوقف هنا في هذا الدرس كي لا تكون المعلومات كثيفة يصعب استيعابها، وسنتابع في دروس أخرى استخدام أرقام الصّفحات في الأسفل بشكل صحيح. (يمكن الآن إضافة تعليق حول وسوم الصفحات كي لا تظهر بشكل خاطئ وبدون روابط صحيحة). خلاصة تعلّمنا في هذا الدّرس كيف نقوم بتجهيز قالب HTML ليُصبح قالبَ ووردبريس، وكيف نُعدّل مسارات ملفات JavaScript وCSS لتُصبح متناغمةً مع رابط الويب الخاص بقالب ووردبريس. وفي القسم الثاني من الدرس تعلّمنا كيف نقوم بفصل المحتوى عن ملف index.php إلى ملفّات فرعية أخرى، لنقوم بإعادة استخدامها في أي ملف ضمن القالب. وفي القسم الأخير رأينا كيف يمكن جلب المقالات من قاعدة البيانات وإظهارها للمُستخدم مع عرض الوسوم الخاصّة بكل مقال. أرجو أن يكون الدرس سهلاً بسيطاً، في حال وجود أي استفسار أو مداخلة نرحّب به في التعليقات.1 نقطة
-
تحدثنا في الدرس السابق مُقدّمة إلى تطوير قوالب ووردبريس حول إنشاء قالب ووردبريس بسيط، واليوم سنقوم بإكمال العمل عليه لعرض أرقام الصفحات أو عرض رابطيّ السابق والتالي للتنقل بين الصفحات والوصول إلى جميع المقالات ضمن المدوّنة. عند وجود عدد كبير من المقالات في المدوّنة، فلن يتم عرضها جميعاً في صفحة واحدة، بل يتم تقسيمها على عدد من الصفحات، بشكل افتراضي يتم عرض 10 مقالات في الصفحة الرئيسية أو الأرشيف (تصنيف أو وسم)، ويمكن تغيير رقم المقالات في الصفحة الواحدة من لوحة التحكم. فهرس السلسلة: مقدمة إلى تطوير قوالب ووردبريس: تحويل صفحة HTML إلى قالب ووردبريس التصفيح (Pagination) في قوالب ووردبريس (هذا الدرس) إضافة قوائم التنقل (Navigation Menu) إلى قالب ووردبريس صف وتسجيل ملفات Javascript و CSS في قوالب ووردبريس Pagination تقدّم ووردبريس دالّة مخصّصة لعرض أرقام الصفحات هي ()paginate_links. سنقوم بالاطلاع على كيفية استخدامها وخياراتها، وننوه بوجود طرق أخرى لعرض أرقام الصفحات، مثل إضافة WP-PageNavi. يتم استخدام الدالّة بهذه الطريقة: <?php echo paginate_links($args);?> حيث متحول args$ هو مصفوفة تحوي إعدادات مخصصة لهذه الدالّة، يمكن أن نستخدم الإضافة دون تمرير هذا المتحول، أو يمكن أن تكون قيمة هذه المتحول هي بعض من الإعدادات الخاصة بالدالّة وليس جميعها. الإعدادات الكاملة هي كالتالي بقيمها الافتراضية: <?php $args = array( 'base' => '%_%', 'format' => '?page=%#%', 'total' => 1, 'current' => 0, 'show_all' => False, 'end_size' => 1, 'mid_size' => 2, 'prev_next' => True, 'prev_text' => __('« Previous'), 'next_text' => __('Next »'), 'type' => 'plain', 'add_args' => False, 'add_fragment' => '', 'before_page_number' => '', 'after_page_number' => '' ); ?> يمكننا أن نضع بعض هذه الإعدادات في المتحول، وتقوم ووردبريس بمعالجة الإعدادات التي نقدّمها للدالّة، بحيث تضيف للإعدادات المُدخلة ما يكملها من الإعدادات الافتراضية. سنقوم الآن باستخدام هذه الدالّة ورؤية كيف تظهر الروابط دون وجود إعدادات للدالّة، نضع ما يلي في نهاية ملف index.php فيصبح: <div class="row"> <div class="medium-12 columns"> <?php echo paginate_links(); ?> </div> </div> </div> <?php get_sidebar(); ?> عندما نقوم بزيارة الصفحة الرئيسية للمدونة، نجد أن روابط أرقام الصفحات تظهر بشكل مشابه لهذه الصورة: سنرى في الفقرة التالية كيف يمكن تخصيص ظهور هذه الروابط. إضافة Style جديد سنحتاج إلى إضافة Style جديد إلى القالب الذي نقوم باستخدامه، وذلك لكي تظهر أرقام الصفحات بشكل يتناسب مع باقي القالب. قد يتبادر للذهن في البداية أن يتم استخدام النسخ واللصق لإضافة Style جديد إلى ملف css الرئيسي. رغم أن هذا ممكن ويؤدي الغرض المطلوب، إلا أن الطريقة الأفضل هي استخدام دالّة تدعى wp_enqueue_style. 1. إضافة دالّة ()wp_head إلى ملف header.php قبل إغلاق وسم </head> نقوم بإضافة السطر التالي: <?php wp_head();?> وهي دالّة مهمة جداً في أي قالب ووردبريس، حيث تقوم ووردبريس (والعديد من الإضافات) باستخدام هذه الدالّة سواءً لإضافة ملفات الشكل (CSS) أواستدعاء ملفات جافاسكريبت أو حتى إضافة وسوم إضافية تتعلق بـ SEO. قمنا بإضافة دالّة wp_head ﻷننا نريد استخدام دالّة ()wp_enqueue_style التي ستقوم بإدراج وسم HTML لاستيراد ملف CSS جديد. 2. إضافة ملف CSS الجديد نقوم بإنشاء ملف جديد هو custom.css، وهو الذي سنقوم باستدعاءه من خلال دالّة ()wp_enqueue_style. نقوم بنسخ ولصق محتوى هذا الرابط ونضعه ضمن ملف custom.css الذي أنشأناه، وهو ما سيقوم بإضافة الشكل المناسب ﻷرقام الصفحات في القالب. 3. استخدام دالّة ()wp_enqueue_style لنقم بفتح ملف functions.php من ملفات القالب، ولنضف عليه ما يلي: // Enqueue custom style add_action('wp_enqueue_scripts', function() { wp_enqueue_style('custom-pagination', get_template_directory_uri() . '/custom.css'); }); ما قمنا بفعله هو أننا أخبرنا ووردبريس أن تنفذ دالّة ()wp_queue_style عند وصول دورة تنفيذ ووردبريس إلى الحدث (action) المُسمّى wp_enqueue_scripts وهو المسؤول عن ترتيب وتنسيق وطباعة ملفات جافاسكريبت و CSS وتحليل متطلبات كل ملف -إن وجدت له متطلبات-، وفي النهاية يتم استخدام الملف/الملفات المطلوبة بعد أن يتم طلب جميع متطلباتها. الآن إن قمنا بفتح المصدر الخاص بالصفحة الرئيسية من المتصفح، نجد أن المصدر أصبح يحوي شيئاً مشابهاً لما يلي: <link rel='stylesheet' id='custom-pagination-css' href='http://localhost:8000/wp-content/themes/my_theme/custom.css?ver=4.1' type='text/css' media='all' /> وهو استدعاء ملف CSS خاص، الذي أردنا وجوده قبل البدء بعرض إرقام الصفحات. لننظر الآن كيف تبدو أرقام الصفحات: أجمل بكثير من سابقتها أليس كذلك؟ شرح إعدادات دالّة paginate_links كما أسلفنا، يمكن أن نمرر جزءًا من الإعدادات ويمكن ألا نمرر أي شيء على الإطلاق، فتقوم ووردبريس باستخدام الإعدادات الافتراضية التي أوردناها في الأعلى. base (القيمة اختيارية)، نوعها سلسلة نصيّة. القيمة الافتراضية: %_% تُستخدم للإشارة إلى الرابط، الذي سيتم استخدامه لإنشاء روابط الصفحات. في رابط مثل: http://example.com/all_posts.php%_% يتم استبدال القيمة الافتراضية: %_% بقيمة format التي سنتحدث عنها في الفقرة التالية. format (القيمة اختيارية)، نوعها سلسلة نصيّة. القيمة الافتراضية: ?page=%#% تُستخدم كهيكل للصفحات. في حال كنا نريد أو كنا نستخدم عناوين نظيفة (pretty permalinks) ستكون القيمة هي /page/%_%، حيث تعبير %_% يتم استبداله برقم الصفحة. total (القيمة اختيارية)، نوعها رقميّ. القيمة الافتراضية: 1 مجموع عدد الصفحات، عند استخدام دالّة ()paginate_links داخل حلقة ووردبريس، تكون القيمة الافتراضية تساوي خاصّية max_num_pages$ في WP_Query. current (القيمة اختيارية)، نوعها رقميّ. القيمة الافتراضية: 0 رقم الصفحة الحالية. show_all (القيمة اختيارية)، نوعها قيمة منطقية (true أو false). القيمة الافتراضية: false إذا كانت القيمة true عندها سيتم إظهار جميع الصفحات بدلاً من قائمة قصيرة من الأرقام المجاورة لرقم الصفحات الحالية. بشكل افتراضي هذا الخيار تكون قيمته false ويتم التحكم به عن طريق الخيارين end_size و mid_size. end_size (القيمة اختيارية)، نوعها رقميّ. القيمة الافتراضية: 1 عدد الأرقام عند بداية ونهاية أطراف القائمة. mid_size (القيمة اختيارية)، نوعها رقميّ. القيمة الافتراضية: 2 عدد الأرقام على جانبيّ الصفحة الحالية، (مع ملاحظة أن الرقم لا يشمل الصفحة الحالية). prev_next (القيمة اختيارية)، نوعها قيمة منطقية (true أو false). القيمة الافتراضية: true لتحديد إن كنا نريد روابط التالي والسابق أن يتم استخدامها في القائمة أم لا. prev_text (القيمة اختيارية)، نوعها سلسلة نصّية. القيمة الافتراضية: __('« Previous') حيث __() هي دالّة مسؤولة عن الترجمة. نص رابط الصفحة السابقة، تعمل فقط إن كان الخيار السابق (prev_next) فعّالاً (قيمته true). next_text (القيمة اختيارية)، نوعها سلسلة نصّية. القيمة الافتراضية: __('Next »') حيث __() هي دالّة مسؤولة عن الترجمة. نص رابط الصفحة التاية، تعمل فقط إن كان خيار (prev_next) فعّالاً (قيمته true). type (القيمة اختيارية)، نوعها سلسلة نصّية. القيمة الافتراضية: ‘plain’ تتحكم بشكل القيمة التي تقوم الدالّة بإرجاعها. القيمة الممكنة هي: plain: تكون القيمة التي يتم ارجاعها عبارة عن سلسلة نصّية مؤلفة من روابط مفصول بينها بمحرف السطر الجديد. array: تكون القيمة التي يتم ارجاعها عبارة عن مصفوفة من روابط الصفحات لتوفّر تحكم كامل بكيفية الظهور. list: تكون القيمة التي يتم ارجاعها عبارة عن قائمة HTML غير مرتّبة (ul). add_args (القيمة اختيارية)، نوعها مصفوفة. القيمة الافتراضية: false مصفوفة اسمية من المحددات ليتم إضافتها إلى الرابط، تكون المصفوفة على شكل: اسم => قيمة. add_fragment (القيمة اختيارية)، نوعها سلسلة نصيّة. القيمة الافتراضية: لا يوجد قيمة. نص لتتم إضافته إلى نهاية كل رابط بشكل مباشر (يمكن تمرير متحولات GET عن طريق هذا الخيار، بشكل يشبه خيار add_args لكن على شكل سلسلة نصية بدلاً من مصفوفة). before_page_number (القيمة اختيارية)، نوعها سلسلة نصيّة. القيمة الافتراضية: لا يوجد قيمة. نص ليتم إظهاره قبل كل رقم صفحة (النص وليس الرابط). after_page_number (القيمة اختيارية)، نوعها سلسلة نصيّة. القيمة الافتراضية: لا يوجد قيمة. نص لتتم إضافته بعد رقم الصفحة (النص وليس الرابط). أزرار التالي والسابق قد يفضّل البعض استخدام أزرار "التالي" و"السابق" بدلاً من أرقام الصفحات، أو ربما يتطلب القالب الذي يعملون عليه هذه الأزرار. تقدّم ووردبريس دالّة واحدة لعرض الرابطين معاً (التالي - السابق) هي: posts_nav_links. لنقم بوضع هذه الدالّة بدلاً من دالّة إظهار أرقام الصفحات التي تحدثنا عنها سابقاً: <?php posts_nav_link(); ?> يصبح القالب بهذا الشكل: يمكن أن تأخذ الدالّة ثلاثة محددات كلها اختيارية، هي: sep$: (سلسلة نصية)، يمثل النصّ المعروض بين الرابطين. القيمة الافتراضية: ' — ' prelabel$: (سلسلة نصية)، اسم رابط الصفحة السابقة. القيمة الافتراضية: '« Previous Page' nxtlabel$: (سلسلة نصية)، اسم رابط الصفحة التالية. القيمة الافتراضية: 'Next Page »' لنقم معاً بتعديل هذه الإعدادات لتصبح كالتالي: <?php posts_nav_link(' - ', '« السابق', 'التالي »'); ?> تظهر لنا التعديلات في القالب كما يلي: ما رأيكم لو نختم الدرس بخدعة بسيطة، نقوم من خلالها بجعل روابط التالي السابقة تظهر بشكل مشابه لأرقام الصفحات؟ سأخبركم بتلميح: تكمن الخدعة بالاستفادة من المحدد الأول sep$. لنضع في البداية وسم ul محيطاً بدالّة ()posts_nav_links يأخذ نفس صنف CSS الموجود في أرقام الصفحات كما يلي: <ul class="page-numbers"> <?php posts_nav_link(' - ', '« السابق', 'التالي »'); ?> </ul> الآن نريد إحاطة كِلا الرابطين بوسم li لكل رابط، يمكن أن نضع داخل وسم ul بداية وسم li ونضع قبل إغلاق وسم ul وسم إغلاق وسم li، فيصبح المصدر كالتالي: <ul class="page-numbers"> <li> <?php posts_nav_link(' - ', '« السابق', 'التالي »'); ?> <li> </ul> ما فعلناه حتى الآن أننا أحطنا كلا الرابطين بوسم li واحد، لكننا نريد أن نحيط كل واحد من الرابطين بوسم مستقلّ، سنقوم باستبدال المحدد الأول $sep بـ: </li><li>. بما أن محتوى هذا المحدد سيكون بين الرابطين بشكل دائم، فسنضع فيه إغلاق وسم li الأول يليه بداية وسم li الثاني. فيصبح المصدر: <ul class="page-numbers"> <li> <?php posts_nav_link('</li><li>', '« السابق', 'التالي »'); ?> <li> </ul> يصبح شكل الروابط كالصورة التالية: خلاصة تعرّفنا خلال الدرس على كيفية إضافة أرقام الصفحات أو روابط التالي-السابق بحيث يتم استخدامها للتنقل بين صفحات الموقع. كما تعرفنا بشكل بسيط على كيفية إضافة ملف CSS جديد باستخدام دالّة ()wp_enqueue_style.1 نقطة
-
تُعتبر خاصيّة الطوفان float property من مصادر القوّة لأي مطوّر أو مُصمّم يستخدم تِقنيّات HTML وCSS. ويُؤدّي عدم الفهم الصحيح لآلية عمل هذه الخاصيّة إلى بعض التِباس في كيفية التعامُل معها. ارتبطت هذه الخاصيّة في الماضي مع أخطاء المُتصفّحات ومشاكل التوافقية، أما الآن فالتعامُل مع خاصيّة الطوفان أصبح من الأمور الأساسيّة التي لا يستطيع المُطوّر تجاهلها. سنتناولُ الموضوع بجزئيّاته الصغيرة لفهم ما تُقدمه هذه الخاصيّة واستخدامها بالشكل الأمثل. عرفنا الطوفان سابقًا من عالم الطباعة والتصميم كما في المجلات، حيثُ الصورة على أحد الجهتين اليمين أو اليسار ويتوضع نَصّ بجانبها بشكل مُتناسق وجذّاب، وفي عالم الويب ومع تقنيّات HTML/CSS، يلتف النصّ حول الصورة باستخدام خاصيّة الطوفان float property كما هو الأمر في تصاميم المجلات. استخدام الصُور مع خاصيّة الطوفان هو أحد الأمور الّتي يُمكنك استخدامها مع هذه الخاصيّة، ولكن في الحقيقة يُمكن استخدام هذه الخاصيّة أيضًا مع أي عنصر من عناصر HTML، حتّى أنّه بالإمكان استخدامها في تقسيم الصفحة page layout. التعريفتُعرّف رابطة الشبكة العالمية W3C خاصيّة الطوفان بالشكل التالي: يُمكن تحديد أربعة قيم لخاصيّة الطوفان: left, right, inherit, none، حيثُ كل قيمة تُعبّر عن دلالتها فمثلًا، تحديد قيمة الطوفان إلى اليسار لعنصر ما (float: left) سينقل العنصر إلى أقصى حافة العنصر الأب الخاص به من جهة اليسار. كما هو الحال عندما تكون القيمة المُحددة للعنصر هي float: right، حيثُ أنّ العنصر سينتقل إلى أقصى اليمين لحواف العنصر الأب الخاص به، وتجعل القيمة inherit العنصر يرثُ قيمة الطوفان من العنصر الأب الخاص به، والقيمة none هي القيمة الافتراضيّة والتي تجعل من العنصر لا يستخدم الطوفان أبدًا. img { float: right; margin: 10px; } آلية عمل الطوفانيعمل الطوفان بطريقة غير مُعقدة وليس كما يعتقد البعض، لتوضيح ذلك يجب العودة إلى أساسيات HTML لمعرفة حقيقة ما يجري قبل الخوض في التفاصيل. في عالم الويب، تتقيّد تقنية HTML بجملة قواعد، ما يتقاطع مع خاصيّة الطوفان هو قاعدة التدفّق الطبيعيّ normal flow، حيثُ تصطف العناصر مِن نوع block فوق بعضها البعض، كما في العناصر div، p، h1 من الأعلى إلى الأسفل. تتوضع العناصر المُطوفة في بادئ الأمر حسب التدفّق الطبيعيّ وتبعًا إلى تسلسلها في مُستند HTML، ومن ثُمّ تُسحب العناصر المُطوفة من التدفّق الطبيعيّ، وتُنقل إلى أقصى يمين أو يسار (على حسب القيمة المُحددة) العنصر الأب الخاصّ بالعنصر المُطوف. بمعنى آخر، تغيّر العناصر المُطوفة من طريقة عملها وتُخالف التدفّق الطبيعيّ في اصطفاف العناصر بعضها فوق بعض إلى اصطفاف العناصر بجانب بعضها البعض، وذلك في حال توفر مساحة كافية للعناصر للتتوضع بجانب بعضها البعض. فَهم هذا التسلسل في عرض العناصر هو أهمّ ما في الطوفان، وهو ما يجعل البعض مرتبكًا في تطبيق هذه الخاصيّة وحلّ مشاكلها. في المثال التالي يوجد ثلاثة صناديق مُحددة الطول والارتفاع، ومن دون تطبيق خاصيّة الطوفان وتُعرض وفقًا لتسلسلها في مُستند HTML. <div class="block pink"></div> <div class="block blue"></div> <div class="block green"></div>.block { width: 200px; height: 200px; }من المُلاحظ في المثال السابق كيف أنّ العناصر تصطف فوق بعضها البعض، ويُمثل ذلك مفهوم "التدفق الطبيعيّ". في المثال التالي نفس الصناديق ولكنها مُطوّفة باستخدام خاصيّة الطوفان float: left. .block { float: left; width: 200px; height: 200px; }تصطفُ الصناديق في المثال السابق بجانب بعضها البعض، وهو أمرٌ مُتوقع بعد معرفة عمل خاصيّة الطوفان، ويتم ذلك فقط لوجود مساحة كافية للعناصر للتتوضع بجانب بعضها البعض. لتوضيح الجزئيّة السابقة تَمّ التعديل على المثال السابق بزيادة عدد الصناديق، مع الانتباه أنّ العنصر الأب لهذه الصناديق هو جِذْعُ الصفحة . من المُلاحظ كيف أنّ تسلسل عرض هذه الصناديق يختلف بناءً على حجم نافذة المُتصفّح -بالإضافة إلى جذع الصفحة - ولذلك ستستهلك هذه الصناديق مزيدًا من الصفوف عند عدم توفر مساحة كافية لعرض هذه الصناديق بجانب بعضها البعض، حيثُ كُلّما تَمّ تصغير حجم نافذة المُتصفّح كُلّما ازداد عدد الصفوف. تحرير الطوفانتعمل خاصيّة الطوفان float جنبًا إلى جنب مع الخاصيّة clear، حيثُ تُكمّل الخاصيّتان بعضُهما البعض لتُقدّم للمُطوّر أداة تطوير أفضل وأسهل. تمّت الإشارة سابقًا إلى أن العنصر المُطوف يتوضع في التدفّق الطبيعيّ في بادئ الأمر، ثم يُزال منه. هذا يعني أنّ كُلّ عنصر يتبع هذا العنصر سوف يعمل بطريقة مُغايرة لما هو مُتوقع، هذا السلوك هو ما يُربك البعض في خاصيّة الطوفان . يوجد في المثال التالي صندوقان مُطوّفان هما الورديّ والأزرق، ومِن ثُمّ صندوقان غير مُطوّفان هما الأخضر والبرتقالي. <!-- HTML --> <div class="block pink float"></div> <div class="block blue float"></div> <div class="block green"></div> <div class="block orange"></div> /* CSS */ .block { width: 200px; height: 200px; } .float { float: left; } .pink { background: #ee3e64; } .blue { background: #44accf; } .green { background: #b7d84b; } .orange { background: #E2A741; }كُلّ شيءٍ في المثال السابق واضح ماعدا عدم ظهور الصندوق الأخضر من العرض، وتوضعه أسفل الصندوق الورديّ، حيثُ أنّ الصندوق الورديّ والصندوق الأزرق هي عناصر مُطوّفة، وتتوافق طريقة عرضها في المُتصفّح بناءً على المعلومات التي توصلنا إليها حتّى الآن، حيثُ أنّها تُسحب من تسلسل عرض التتدفّق الطبيعيّ وتصطف بجانب بعضها البعض، وهذا ما أخفى الصندوق الأخضر، ولإظهاره يجبُ استخدام الخاصيّة clear. تملك الخاصيّة clear خمس قيم هي: يسار left، يمين right، الطرفين both، مَوروث inherit ولا شيء none. تجعل القيمة left العنصر أسفل أي عنصر مُطوف إلى جهة اليسار، وتجعل القيمة right العنصر أسفل أي عنصر مُطوف إلى جهة اليمين، واستخدام القيمة both تجعل من العنصر أسفل أي عنصر مُطوف على الجهتين اليُمنة واليسرى، أما القيمة inherit فتجعل من العنصر يرث قيمة العنصر الأب للخاصيّة clear. في المثال التالي تم استخدام الخاصيّة clear بالقيمة left مع الصندوق الأخضر. <!-- HTML --> <div class="block pink float"></div> <div class="block blue float"></div> <div class="block green clear"></div> <div class="block orange"></div> /* CSS */ .block { width: 200px; height: 200px; } .float { float: left; } .clear { clear: left; } .pink { background: #ee3e64; } .blue { background: #44accf; } .green { background: #b7d84b; } .orange { background: #E2A741; }يجعل التعديل الأخير على الصندوق الأخضر من الصندوق الورديّ وكأنّه في التدفّق الطبيعيّ لمُستند HTML، على الرَغم من أنّه ليس كذلك، وهذا ما يجعل من الخاصيّة clear خاصيّة رائعة والتي تُساعد على إرجاع عنصر غير مُطوف ليُعرض بشكل مُتوافق مع التدفّق الطبيعيّ ويَظهر على المُتصفّح كما هو مُتوقع له أن يظهر. بعد فهم عمل هاتان الخاصيّتان سيكون من السهلِ ابتكارُ أساليب جديدة للتعامل مع شيفرة HTML وCSS استخدام الطوفان لتقسيم الصفحاتتبرز أهمّيّة خاصيّة الطوفان عند استخدامها في إنشاء تقسيمات الصفحة ، حيثُ بإمكاننا إنشاء صفحة بعمودين بطرق عدّة، وأغلب هذه الطُرق تستخدم عنصرًا مُطوّفًا واحدًا أوعنصرين مطوّفين. لنأخذ مثالًا بسيطًا: يحتوي موقع على عمودين، حيثُ المُحتوى على الجانب الأيسر وشريط التنقل الجانبي على الجانب الأيمن، في أعلى الصفحة يوجد ترويسة header وأسفل الصفحة يوجد ذيل الصفحة footer. #container { width: 960px; margin: 0 auto; } #content { float: left; width: 660px; background: #fff; } #navigation { float: right; width: 300px; background: #eee; } #footer { clear: both; background: #aaa; padding: 10px; } تحليل ملف التنسيق السابق يُظهر أنّ الحاوية الرئيسة والتي تُدعى container تُقيّد عناصر الصفحة المُطوفة في موضعها الذي يجب أن تكون عليه، ولو لم يكن لدينا هذه الحاوية لكانت العناصر المُطوفة مُلتصقةً على حواف نافذة المُتصفّح، وأما العناصر المُطوفة داخل الحاوية فهي content و navigation. يُمكن الحصول على تقسيمٍ ذو عمودان وذلك بأنّ نُطوّف المُحتوى content إلى جهة اليسار، وشريط التنقّل الجانبي navigation إلى جهة اليمين، ولكلٍ منهما قيمة عرض مُحددة بـ 660px للمُحتوى و300px لشريط التنقّل الجانبي، وبذلك سيستحوذ هذان العنصران عرض الحاوية بالكامل (960px). أخيرًا تم تحديد الخاصيّة clear على ذيل الصفحة footer، والتي من شأنها أنّ تُعيد العناصر التي تلي أي عناصر مُطوفة إلى التدفّق الطبيعيّ، في هذه الحالة حُددت القيمة both لذيل الصفحة footer، لجعله يصطفُ أسفل المحتوى وشريط التنقّل الجانبي. يُظهر المثال التالي كيفية عرض ذيل الصفحة footer في حال عدم استخدام الخاصيّة clear، ويُلاحظ كيف أنّ ذيل الصفحة انتقل إلى أسفل شريط التنقّل الجانبي، وذلك يحدث بسبب وجود مساحة كافية له أسفل الشريط، وأيضًا هذا السلوك هو مُتوافق مع التدفّق الطبيعيّ الذي نعمل به، ولكن هذا بالطبع ليس ما نريده. يُفترض الآن أن يكون الأمر واضحًا كيف أنّ الخاصيّتين float وclear تعملان جنبًا إلى جنب وكُل منهما يُكمّل الآخر. الطوفان أولًاحتى الآن جميع الأمثلة السابقة كانت واضحة وبعيدةً عن المشاكل، حيثُ هناك حالات دقيقة يجبُ الإشارة إليها عند استخدام خاصيّة الطوفان. واحدةٌ من أهمّ هذه الحالات هي غير مُرتبطة بشكل مُباشر مع تقنيّة CSS بل مع تقنيّة HTML نفسها، حيثُ يختلف توضع العنصر المُطوف عن ما هو مُتوقع له أنّ يكون فيه، كما في المثال التالي حيثُ لدينا صندوق صغير نوعًا ما وبداخله صورة مُطوفة إلى جهة اليمين وبجانبها نصٌّ، ويملك العنصر الأب، وهو الحاوية، مساحة عرض مُحدودة (280px) ليُحيط بالعناصر المُطوفة بداخله. #container { width: 280px; margin: 0 auto; padding: 10px; background: #aaa; border: 1px solid #999; } img { float: right; } <div id="container"> <img src="image.gif" /> <p>This is some text contained within a small-ish box. I'm using it as an example of how placing your floated elements in different orders in your HTML can affect your layouts. For example, take a look at this great photo placeholder that should be sitting on the right.</p> </div> حتى الآن لا يوجد ما هو غريب في المثال السابق، ولكن ماذا لو كان ترتيب العناصر في صفحة HTML مُختلفٌ بعض الشيء، حيث الصورة بعد النَصّ <div id="container"> <p>...</p> <img src="image.gif" /> </div> النتيجة ليست مرضية أبدًا، حيث انتقلت الصورة من أعلى الزاوية اليُمنى إلى أسفل النصّ، ليس هذا فقط بل أصبحت الصورة خارج الحاوية الخاصّة بها. إذا ما المُشكلة؟ في الحقيقة سبب المُشكلة يحتاج إلى شرحٍ والذي سنتطرّق إليه لاحقًا، ولكن الجدير بالذكر الآن أنّه من المُمكن تطبيق قاعدة "التطويف أولًا"، أيّ أنّ العناصر المُطوفة تأتي قبل العناصر غير المُطوفة في مُستند HTML، قد لا تعطي هذه القاعدة النتيجة المطلوبة دائمًا ولكن من الجيد تذكرها. أما سبب ظهور الصورة خارج حدود الحاوية الخاصّة بها فهو يعود إلى ما يُسمى بالانْطِواء collapsing. الانْطِواء Collapsingالانْطِواء هو عندما لا يتوسّع العنصر الأب الذي يحتوي على أي عدد من العناصر المطوفة بشكلٍ كامل ليُحيط بها كما لو كان سيفعل لو كانت هذه العناصر غير مُطوفة. في المثال السابق لم تكن المُشكلة في المُتصفّح نفسه والترتيب الذي ظهر عليه المُحتوى في المثال السابق هو ترتيب منطقيٌّ، حيثُ أنّه تُسحب العناصر المُطوفة من التدفّق الطبيعيّ للعناصر على الصفحة، لذلك لا تَعتبر الحاوية container العناصر المُطوفة جزءًا منها وتتعامل معها وكأنّها غير موجودة. لمزيد من التفاصيل حول هذا الموضوع يُمكن الرجوع إلى مقالة بعنوان: احتواء الطوفان. يُوضّح المثال التالي حاوية بداخلها صندوقين <!-- HTML --> <div class="container"> <div class="block pink"></div> <div class="block blue"></div> </div> /* CSS */ .container { background: rgb(168, 207, 166); width: 600px; margin: auto; } .block { width: 200px; height: 200px; margin-left: 64px; }يُلاحظ بعد إضافة الطوفان إلى الصندوقين اختفاء الحاوية من المُتصفّح، هل أصبحت تحت الصندوق الأزرق؟ أم الورديّ؟ أم ربما الأخضر الذي هو تحت الورديّ؟ في الحقيقة ما حدث هو أنّ الحاوية انطوت على نفسها بسبب عدم وجود عناصر لاحتوائها بعد الطوفان، ويبدو ذلك جليًا بعد إضافة حدودٍ للحاوية. بعد أن توضّحت المُشكلة سوف نتطرّق إلى الحلول المُتوفرة، حيثُ يوجد طُرق عدّة لحل هذه المُشكلة، تعدّد الحلول يعود إلى المُرونة في اختيار الحلّ الأنْسَب، فالحلول المطروحة قد لا تُناسب جميع الحالات. تُعتبر الطريقة التالية أقدم الطُرق في حل مُشكلة الانطواء، وهي باستخدام الخاصيّة clear بعد العنصر المُطوف، وذلك بجعل العنصر الأب مُمتدًا إلى ما بعد العنصر المُطوف، حيثُ يتم إضافة div مع تنسيق مُضمّن clear: right، والذي يجعل من الصورة المُطوفة مأخوذةً بالحسبان. يعمل هذا الحل بشكل جيّد جدًا ومع جميع المُتصفحات ومن دون أي مشاكل في التوافقية، ولكن استخدام تنسيق مُضمّن يُخالف قاعدة الفصل بين مُستند HTML و ملف التنسيق CSS لذلك لا يُحبّذ العديد من المُطوّرين هذه الطريقة. <div id="container"> <p>...</p> <img src="image.gif" /> <div style="clear: right;"></div> </div> في المثال التالي لدينا عنصر أب يحتوي على ثلاثة صور مُطوفة، من المُلاحظ كيف أن الصور الثالثة خارج الحاوية. <div id="container"> <img src="image.gif" /> <img src="image.gif" /> <img src="image.gif" /> </div> لتصحيح طريقة العرض سنستخدم CSS بدلًا من التنسيق المُضمّن، تسمح الطريقة التالية للعنصر الأب بالتوسّع ليُحيط بالعناصر المُطوفة، حيثُ يتم إضافة الخاصيّة فيضان overflow للعنصر الأب مع القيمة hidden. الجدير بالذكر هنا أنّه لم تُنشئ هذه الخاصيّة بهدف حل مُشكلة الانطواء، لذلك قد يكون لها بعض المشاكل، فمثلًا قد يختفي المُحتوى من الظهور عندما يكون أكبر من أنّ يتسع داخل الحاوية، لذلك يجب الحذر عن استخدام هذه الطريقة. #container { overflow: hidden; width: 260px; margin: 0 auto; padding: 10px 0 10px 10px; background: #aaa; border: 1px solid #999; } يُوضح المثال التالي اختفاء المحتوى من الظهور عند استخدام خاصيّة overflow. يوجد طريقة أُخرى لحل مُشكلة الانطواء والّتي تعطي نتائج جيّدة كما في الحلول السابقة، وهي استخدام شبه العناصر pseudo-elements المُسمى "بعد" after. #container:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } تقوم أوراق الأنماط المُتتالية CSS بإضافة عنصر جديد بعد الحاوية container مع بعض المُحتوى، في المثال السابق هو النقطة (.)، وإخفائه من العرض وبدون ارتفاع. يُمكن القراءة عن هذه الطريقة بمزيد من التفصيل عبر موقع: التمركز أهمّ ما في الأمر. تقوم جميع الطرق السابقة بحل مُشكلة الانطواء، والطريقة الأخيرة هي الأكثر استخدامًا في الوقت الحالي بعد تطوّر المُتصفحات ودعمها لمعايير CSS3. يقدم الموقع التالي أفضل استخدام لهذه الطريقة ويُوضح تطوّر الشيفرة الخاصة بها عبر الوقت: إصلاح الانطواء. خاتمةأصبحت الخاصيّة float من الأدوات الأساسيّة في تصميم صفحات مُتجاوبة، لذلك فهم آليّة عمل هذه الأداة والمشاكل الخاصّة بها سيقدم للمطوّر أداة عمليّة لا يستطيع الاستغناء عنها. ترجمة -وبتصرّف- للمقال: CSS Floats 101 لصاحبه Noah Stokes1 نقطة