البحث في الموقع
المحتوى عن 'أساسيات'.
-
عندما نسمع كلمة برمجة؛ تخطر ببالنا أسئلة كثيرة، مثل: من أين وكيف نبدأ؟ وما أفضل لغة برمجة؟ هل يمكنني تعلم البرمجة دون الالتحاق بمعهد أو جامعة؟ سنجيب في هذا الفيديو عن الأسئلة التي تخطر في بال أي مبتدئ. سنستخدم لغة JavaScript لشرح المفاهيم الأساسية كالمتغيرات والجمل الشرطية وحلقات التكرار loops وأخيرا الدوال functions، وسنكتب أول برنامج لنا باستخدام لغة جافاسكريبت.
-
إذا أردت أن تصبح مطوّر ووردبريس فهذا يتطلب أيضًا تعلم لغة البرمجة الشهيرة PHP، والتي بنيت من خلالها منصة ووردبريس. طورت بشكل أساسي في عام 1994، PHP لغة برمجة قوية ومفتوحة المصدر لإنشاء مواقع ويب ديناميكية وتفاعلية. سوف تتعلم القواعد الأساسية للغة PHP وكيفية كتابتها، وكيفية عملها، والاطلاع على بعض الأمثلة. ما هي PHP؟ PHP هي لغة برمجة نصية من طرف الخادم (server). لفهم ما يعني هذا، لنقارنها مع Html. عندما تزور صفحة Html بسيطة، يقوم متصفحك بإرسال طلب للخادم الذي يحتوي هذه الصفحة التي تحاول الوصول إليها. الخادم يكتشف أي ملف تريد الوصول إليه ويقوم بإرساله لك. متصفحك يترجم شيفرة Html المرسلة ويعرضها لك. بالمقارنة، عندما تزور صفحة PHP هناك خطوة إضافية متصفحك يقوم بإرسال طلب والخادم يجد الملف الذي تريده. قبل إرساله لمتصفحك، الخادم يعالج الملف، منتجًا مخرجات Html نهائية (Html output) ثم يقوم بإرسال هذه المخرجات لمتصفحك الذي يقوم بعرضها كالمعتاد. لهذا السبب عندما تنظر إلى الشيفرة المصدرية لأي موقع لا ترى أبدًا أي شيفرات PHP، فقط Html، حتى لو كان الموقع مكتوبًا بلغة PHP. إذا لماذا يحتاج الخادم إلى عملية المعالجة؟ ما المغزى من ذلك؟ لأنه يمكننا من عمل مواقع ديناميكية وكتابة شيفرات بفعالية كبيرة. لنستعرض مثالين بسيطين. في Html كل شيء ثابت (static). يمكنك إنشاء صفحة تعرض كلمة “Good morning” أو “Good evening” لكنك لا تستطيع إظهار واحدة وإخفاء الأخرى اعتمادًا على التوقيت الحقيقي لليوم. في PHP تستطيع عمل ذلك لأن الخادم يمكنه معالجة التعليمات البرمجية آخذًا التوقيت الحقيقي لليوم بعين الاعتبار. والمنطق لهذا المثال يكون كالتالي: if it is before 10am { <h1>Good Morning</h1> } if it is after 6pm { <h1>Good Evening</h1> } otherwise { <h1>Good Day</h1> } طبعًا هذه ليست التعليمات البرمجية الحقيقية، لكنها تتبع منطق PHP. الخادم سيحدد أي حالة هي الحالة المحققة للشرط وسيعرض واحدة فقط من العناوين. مثال آخر هو موقع تويتر أو أي موقع آخر الذي يقدم المحتوى المكتوب من قبل المستخدمين. إذا كان تويتر يستخدم Html فقط، أحد ما يجب عليه أن يقوم بوضع تغريدتك في ملف Html في كل مرة تقوم بتغريدة جديدة وهذا طبعًا ليس استغلالاً جيدًا للوقت. يوجد حوالي 1 مليار حساب على موقع تويتر لذلك الشركة ستحتاج إلى 1 مليار ملف Html، ملف لكل مستخدم. مع PHP، مشكلة إعادة توليد ما ينشره المستخدم يمكن أن يحل بعدة ملفات. سنعود إلى هذا المثال لاحقًا في هذه المقالة. البداية قبل أن نبدأ، أود التنبيه على أنه في المراحل الأولى من تعلم PHP ربما لن تكون على قادرًا على إنشاء موقع ويب. هذه ردة فعل طبيعية وهذا أيضًا ما شعرت به عند بداية تعلم PHP. الخطوات الأولى تجريدية قليلاً، لكن في نهاية هذا المقال سترى النور. من أجل اختبار وممارسة ما سوف تتعلم في هذه المقالة، سوف تحتاج إلى خادم أباتشي (Apache server). يمكن أن يكون هذا موقع اختبار عبر الإنترنت ولكن يمكن أيضًا أن يكون خادم محلي. أوصي بإنشاء خادم محلي (local server). وإليك كيفية القيام بذلك: أولاً، عليك تحميل وتثبيت Virtualbox وVagrant. إنشاء مسار في أي مكان على كمبيوترك لتخزين ملفات المشروع. لدي مجلد “websites” في مسار المستخدم الخاص بي، قمت بإنشاء مسار “PHPtutorial”. وسوف أشير إلى هذا باسم “مجلد المشروع الرئيسي” طوال بقية هذا المقال. بمجرد إنشاء المسار، افتح terminal على linux أو osx، أو cmd على windows، وانتقل إلى المجلد. إذا قمت بإنشاء بنية المجلد نفسه كما لدي، على linux أو osx يمكنك كتابة cd ~/websites/PHPtutorial على windows cd %HOMEPATH%/websites/PHPtutorial عندما تكون في المسار الصحيح، ألصق الأمر التالي: curl -L -o 'install.sh' http://bit.ly/1hBfq57 && curl -L -o 'Vagrantfile' http://bit.ly/1mE3Qt9 && vagrant up وبمجرد تنفيذ الأمر، سوف تكون قادرًا على الوصول إلى الموقع الخاص بك على http://192.168.33.21. إذا قمت بإعادة تشغيل جهاز الكمبيوتر الخاص بك، سوف تحتاج أيضًا إلى إعادة تشغيل الخادم الخاص بك، والتي يمكنك القيام به عن طريق الانتقال إلى مجلد المشروع الرئيسي في سطر الأوامر وكتابة vagrant up. ملف المشروع الرئيسي هو الآن المجلد الجذر الخاص بك. قم بإنشاء ملف index.html هناك مع أي محتوى، وينبغي أن يتم عرضه بشكل صحيح عند زيارة موقع الويب الخاص بك على http://192.168.33.21. الخطوات الأولى في البداية، لنلقِ نظرة على الوسوم(tags)، المتغيرات(variables)، القيم (values)، والإظهار (echoing). أنشئ ملف اسمه index.php في ملف المشروع الرئيسي واكتب”Hello HTML” بداخله. للتأكد بأنه يعمل قم بزيارة http://192.168.33.21، ويجب رؤية النص الذي قمت بكتابته على شاشة المتصفح. قاعدة مهمة جدًا وهي أن ما يكتب داخل وسوم php يعتبر شيفرة PHP، وأي شيء آخر يعتبر Html. لذلك ظهر نص Hello HTML. وسوم php تبدأ ب<?php وتنتهي ب ?>. أي شيء بين هذين الوسمين يعتبر PHP. Hello HTML <?PHP echo "Hello PHP"; ?> التعليمات البرمجية السابقة أظهرت كيف يتم استخدام وسوم php وكيفية إظهار القيم على الشاشة. عندما تُظهر قيمة أنت تخبر PHP لعرض هذه القيمة على الشاشة. نتيجة تنفيذ التعليمات البرمجية السابقة سيكون ” Hello Html Hello PHP” . الجزء الأول يعتبر Html لأنه لم يكن داخل وسوم PHP بينما الجزء الثاني قد تم إظهاره بواسطة شيفرة PHP. لاحظ أنه يجب إحاطة النص بإشاراتي اقتباس. المتغيرات(variables) تسمح لك بتخزين القيم بدون عرضها. المتغيرات يتم استخدامها بكثرة لتخزين العديد من الأشياء. لنلقي نظرة على مثال بسيط: <?PHP $name = "Daniel"; echo $name; ?> في التعليمات البرمجية السابقة قمت بتخزين قيمة “Daniel” في متغير يدعى name$. بدلاً من إظهار “Daniel” بشكل مباشر، الآن أنا أظهر قيمة name$ مهما كانت. من الوهلة الأولى تبدو لك كزيادة في التعليمات البرمجية بدون فائدة لكن إذا كنا نستعمل هذا المتغير في أكثر من مكان يمكننا تغيير كل شيء بتغيير قيمة هذا المتغير في مكان واحد، بدلاً من تغيير تلك القيم في كل مكان وُضِعت فيه. لاحظ أن الفصل بين أسطر الشيفرات يكون بوضع فاصلة منقوطة (;). إذا أنتجت شيفرتك خطأ فهناك احتمال أنك نسيت وضع فاصلة منقوطة في مكان ما، خطأ شائع ومحبط لكثير من المبرمجين في كل مكان. القيم(values) يمكن أن تكون عدة أنواع. لحد الآن تعرفنا على واحد من هذه الآنواع وهو النوع النصي. النص هو سلسلة من المحارف ويجب إحاطته بإشارتيَ اقتباس (“). نوع آخر وهو النوع الرقمي. الرقم هو أي عدد كامل ولا يجب وضعه ضمن اشارتي اقتباس وإلا سيعتبر نصًا. واحدة من أهم أنواع القيم المصفوفات(array). المصفوفات تخزن عدة قيم، والتي من الممكن أن تكون قيمًا من أنواع مختلفة. <?PHP $name = 'Daniel'; $age = 30; $interests = array( 'guitar', 'singing', 'squash', 'running', 'board games' ); ?> كما ترى يمكن تعريف المصفوفة على الشكل التالي (array(value1 , value2 , value3. يجب كتابة القيم دائمًا في المصفوفة كما تكتب خارج المصفوفة. النص يجب أن يكون محاطًا بإشارتيَ اقتباس (“)، الرقم غير محاط بشيء وهكذا. مثال بسيط إذا بماذا يمكن استخدام ما تعلمناه للآن، ما تعلمناه للآن لا يمكنه إنشاء موقع بعد ولكن حتمًا نحتاج لمثال عملي الآن. لنلقِ نظرة على شيفرة لتطبيق توقعات الطقس: <?PHP $unit = "C"; $temp = 29; if( $unit == 'F' ) { $temp = $temp * 9 / 5 + 32; } $forecast = "The weather today will be great, a Sunny " . $temp . $unit; echo $forecast; ?> هناك بعض الأشياء الجديدة في هذه التعليمات البرمجية، لكن أعتقد أن المثال يشرح نفسه بوضوح. لنراجعه سطرًا بسطر. في البداية، نقوم بإنشاء متغيرين: أول متغير عبارة عن نص يحمل القيمة “C” للمئوية، والمتغير التالي هو عدد صحيح، 29، والذي يهدف إلى تخزين درجة الحرارة الفعلية. الأهداف هنا بسيطة: عرض النص الذي يخبرنا درجة الحرارة الحالية باستخدام القيمة من متغير درجة الحرارة لدينا في وحدة قياس حسب الاختيار، مئوية أو فهرنهايت. السطر التالي هو عبارة if، التي يتم تنفيذ ما بداخلها فقط إذا كانت القيمة داخل الأقواس صحيحة. الشرط هو: $unit == 'F' الذي يترجم منطقيًا كالتالي: إذا كانت قيمة واحدة القياس هي F و هي ليست كذلك و بالتالي سيتم تخطي كتلة هذا الشرط و ما بداخله بدون تنفيذ. في السطر الأخير متغير forecast$ الذي يحوي عبارة “The weather today will be great, a Sunny “ . اعتمادًا على قيمة متغيري unit$ و temp$ ستكون النهاية مختلفة، النقاط بين النصوص والمتغيرات تجمع المتغيرات مع النصوص أو تدمجها. لذا ببساطة سيتم استبدال قيمة temp$ بـ 29 و unit$ بـ C والمخرجات النهائية ستكون: The weather today will be great, a Sunny 29C الآن، ماذا يحدث إذا غيرنا قيمة unit$ إلى F، في البداية سوف يتم تنفيذ التعليمات البرمجية داخل if لأن شرطها تحقق وأصبحت صحيحة، وهذا يعني أن كل شيء بين الأقواس المجعدة سيتم تنفيذه أيضًا. في المثال، اسندت قيمة جديدة لمتغير temp$. أخذت القيمة الأصلية، وتم ضربها في 9، وتقسيمها من على 5 وإضافة 32 وهذه هي المعادلة لتحويل مئوية إلى فهرنهايت. يجب أن تكون القيمة الجديدة لـ temp$ هي 84.2، والقيمة الجديدة unit$ هي F الآن سيتم استبدال المتغيرات بقيمها في الجملة النهائية فتصبح: The weather today will be great, a Sunny 84.2F هذا المثال لا يزال غير مجدٍ بعض الشيء بالنسبة لنا، لكنه يبدأ في إظهار قوة PHP. لاحظ كيف وصلنا إلى الناتج النهائي عن طريق استبدال المتغيرات ببساطة مع القيم. فهو يساعد على الوصول إلى عقلية “replacing placeholder” لأنه هو أساسًا ما تدور حوله لغة PHP. في مثال حقيقي، سنقوم باستخدام القيم الجوية الحالية وبدلًا من كتابة جملة The weather today will be great, a Sunny سوف نستخدم الظروف الفعلية. وقد نرغب أيضًا في التنبؤ غدًا أو في اليوم التالي، مما سيؤدي إلى استبدال “today” بنص آخر. وبالإضافة إلى ذلك، من الواضح أن درجة الحرارة الحالية من الصعب أن تكون مكتوبة يدويًا في الشيفرة البرمجية، فإنه سيكون من الضروري أن يتم استرجاعها من مكان ما. على الرغم من أن هذا يضيف بضع طبقات من التعقيد، لكن المبدأ سيكون نفسه وهو أن نجلب البيانات من مكان ما ونضعها في مخرجاتنا. عبارة if والحلقات الشرطية loops لقد رأينا بالفعل عبارة if في مثال حقيقي. تقوم عبارة if بالتأكد من الشرط داخل الاقواس. إذا كانت النتيجة صحيحة تتم معالجة التعليمات البرمجية داخل الأقواس المجعدة وإلا فأنه لن يتم تنفيذ التعليمات. عبارة if أيضًا ذات صلة مع else if و else. عبارة else if تكتب دائمًا بعد عبارة if. إذا كانت عبارة if غير محققة سيتم التأكد تاليًا إذا كانت عبارة else if محققة، و يمكن أن يكون لدينا عدد غير محدد من عبارات else if بناءً على نفس المنطق. و أخيرًا لدينا عبارة else التي سيتم تنفيذها عندما تكون جميع الشروط التي تسبقها غير محققة، و ليس من الضروري أن يسبق عبارة else عبارة else if يمكنك فقط استعمال عبارة if و else مع بعضهما. لنلقِ نظرة على الأمثلة التالية للتوضيح: // Simple if Statement if( $speed > 50 ) { echo "You are over the speed limit"; } // If and else statement if( $age < 21 ) { echo "You may not buy alcohol"; } else { echo "You may buy alcohol"; } // If, else if and else statement if( $speed < 25 ) { echo "You are too slow"; } elseif( $speed > 120 ) { echo "You are too fast"; } else { echo "Your speed is just right!"; } شيء آخر هنا علينا أن نلاحظه وهو الأسطر التي تبدأ مع مائلة مزدوجة “//”. المائلة المزدوجة تسمح لك بإضافة تعليق سطر واحد في أي مكان في التعليمات البرمجية. يمكنك إضافة تعليقات متعددة الاسطر من خلال البدء مع / * writing whatever you’d like and ending it with * /. الحلقات (loops) تأتي بالعديد من الأشكال والأحجام، أربعة على وجه الدقة. تسمح لك الحلقات بتشغيل نفس التعليمات البرمجية عدة مرات بناءً على استمرار الشرط الذي بدأت به الحلقة. قد تكره الحلقات الآن، لكنها سوف تصبح أقرب حلفائك عندما تصبح أكثر احترافية في كتابة التعليمات البرمجية. لنبدأ مع حلقة foreach. حلقة foreach تمر من كل عناصر المصفوفة وتنفذ تعليمات برمجية معينة. فيما يلي مثال سريع يظهر قائمة Html: <?PHP $names = array( "Daniel Pataki", "Raelene Morey", "James Farmer" ); echo "<ul>"; foreach( $names as $name ) { echo "<li>" . $name . "</li>"; } echo "</ul>"; ?> المفتاح هنا هو فهم العبارة داخل الأقواس، وهي $names as $name، الجزء الأول هو اسم المصفوفة التي ترغب في المرور من خلالها. والثاني هو اسم المتغير الذي يمكن الرجوع إليه من أجل الحصول على قيمة عنصر في هذه المصفوفة الذي تمر عليه حاليًا من خلال الحلقة ولك الحرية في تسمية هذا المتغير أي أنه ليس من الضروري أن تسميه name$ هنا بل يمكن تسميته أي اسم تريده. في مثالنا، سيتم تنفيذ الحلقة ثلاث مرات. عندما تمر الحلقة بالمصفوفة للمرة الأولى ستكون قيمة المتغير name$ هي “Daniel Pataki”، وفي المرة الثانية ستكون “Raelene Morey,” وفي المرة الثالثة ستكون “James Farmer.” يعرض المثال التالي تفاصيل في قائمة، من مصفوفة مترابطة: <?PHP $details = array( "name" => "Daniel Pataki", "Age" => "30", "Twitter" => "http://twitter.com/danielpataki" ); echo "<ul>"; foreach( $details as $label => $value ) { echo "<li><strong>" . $label . "</strong>: " . $value . "</li>"; } echo "</ul>"; ?> الأقواس تحتوي الآن على ثلاثة متغيرات: $details as $label => $value ، ستمر الحلقة الآن من المصفوفة details$. عند كل مرور للحلقة على المصفوفة سيتم مناداة المفتاح label$ والقيمة المرتبطة بهذا المفتاح value$ ، عند المرور الثاني ستكون قيمة label$ هي Age و قيمة value$ هي 30 و ستكون نتيجة تنفيذ التعلمية هي: • Name: Daniel Pataki • Age: 30 • Twitter: http://twitter.com/danielpataki كيف تعمل قوائم مقالات ووردبريس: لنلقِ نظرة الآن على مثال أكثر ارتباطًا بووردبريس: كيف تعمل قوائم مقالات ووردبريس. لا تحاكي التعليمات البرمجية أدناه ووردبريس بالضبط، ولكن جوهر العملية موجود. تخيل أن المنشورات أو المقالات جزء من مصفوفة ارتباطية كبيرة. التعليمات البرمجية الخاصة بصفحتك الرئيسية ببساطة تمر على المصفوفة وتضع البيانات المناسبة في المكان المناسب في بعض وسوم Html: $posts = array( 0 => array( "post_title" => "My First Post", "post_excerpt" => "This is a short snippet of text from the first post", "post_date" => "2015 December 1", "post_author" => "Daniel Pataki" ), 1 => array( "post_title" => "Second Post", "post_excerpt" => "Short exceprt for post number 2", "post_date" => "2015 December 4", "post_author" => "Raelene Morey" ) ); foreach( $posts as $post ) { echo "<div class='post'>"; echo "<h1>" . $post['post_title'] . "</h1>"; echo "<p>" . $post['post_excerpt'] . "</p>"; echo "<div class='post-meta'>Published on " . $post['post_date'] . " by " . $post['post_author'] . "</div>"; echo "</div>"; } الدوال (Functions) بطريقة ما، الدوال تخدم نفس الغرض كما المتغيرات - وسيلة لاستبدال التعليمات البرمجية. يمكن أن تأخذ الدوال كتلة من التعليمات البرمجية وتخزّنها لوقت لاحق وتستخدمها عدة مرات. دعونا ننظر إلى مثال بسيط جدًا باستخدام حلقة المقالات بالمثال السابق. حيث أنه من المحتمل أن يتم استخدام الجزء الذي نظهر فيه عناصر المنشورات في عدة صفحات من موقع الويب - كالصفحة الرئيسية، وصفحات الأرشيف، وصفحات المؤلفين، وما إلى ذلك. سنستخدم نفس التعليمات البرمجية مرارًا وتكرارًا. هذا هو بالضبط الوقت الذي نحتاج فيه إلى الدوال. <?PHP function display_post( $postdata ) { echo "<div class='post'>"; echo "<h1>" . $postdata['post_title'] . "</h1>"; echo "<p>" . $postdata['post_excerpt'] . "</p>"; echo "<div class='post-meta'>Published on " . $postdata['post_date'] . " by " . $postdata['post_author'] . "</div>"; echo "</div>"; } $posts = array( 0 => array( "post_title" => "My First Post", "post_excerpt" => "This is a short snippet of text from the first post", "post_date" => "2015 December 1", "post_author" => "Daniel Pataki" ), 1 => array( "post_title" => "Second Post", "post_excerpt" => "Short exceprt for post number 2", "post_date" => "2015 December 4", "post_author" => "Raelene Morey" ) ); foreach( $posts as $post ) { display_post( $post ); } التعليمة البرمجية أعلاه ليست أقصر، ولكن في أي وقت نريد عرض منشورات في المستقبل يمكننا فقط أن نكتب display_post( $post ); مما يجعلها أكثر كفاءة في المستقبل. كيف يعمل كل هذا؟ دعونا نفهم ذلك من خلال النظر إلى الدالة في الجزء العلوي من التعليمات البرمجية. قمت بتسمية هذه الدالة بـ display_post(); و في القوسين نلاحظ أن هذه الدالة تتوقع وسيط واحد. و نحن نعلم أن هذا الوسيط يجب أن يحتوي معلومات المنشور لذا سيكون هذا الوسيط عبارة عن مصفوفة مترابطة تحتوي معلومات منشور واحد أسميته postdata$. ضمن الأقواس المجعدة ندرج كل التعليمات البرمجية التي نريد تنفيذها عند استدعاء الدالة. هذه هي نفس التعليمات البرمجية التي كانت لدينا من قبل، أنا فقط بحاجة إلى إعادة تسمية كافة المتغيرات إلى postdata$، اسم الوسيط الذي تتوقعه الدالة، والتي يمكننا استخدامها في أي مكان داخل الدالة. في الجزء السفلي من التعليمة البرمجية، يمكنك أن ترى أن عرض المقال الآن أصبح أكثر تنظيمًا للتعليمات البرمجية، لقد استخدمنا للتو display_post($post). أنا متأكد أنك تشعر ببعض الضياع الآن حول التسمية، لماذا استخدمنا post$ في مكان و postdata$ في مكان آخر؟ لنراجع التعليمات البرمجية يتم تشغيل الدوال فقط عندما يتم استدعاؤها، لذا أكثر ما يهمنا في تعليماتنا البرمجية هو مصفوفة $posts، بعد ذلك نقوم بإنشاء الحلقة، كما فعلنا سابقًا. بداخل الحلقة المتغير الذي يحوي بيانات المقال الواحد post$، لحد الآن لم يتغير شيء من مثال الدالة. الآن، بدلًا من وجود كتلة من التعليمات البرمجية هناك نحن ببساطة سنقوم بإسناد هذه التعليمات البرمجية لدالة. نستدعي دالة ()display_post، نعلم أننا نحتاج لتمرير بيانات لهذه الدالة و هذه البيانات هي بيانات مقال واحد. أي متغير يحوي هذه البيانات الآن؟ المتغير post$ ، هذا يأتي من تعريف الحلقة. بعد ذلك، انتقل للأعلى إلى الدالة. سيتم الآن تنفيذها. في هذه الدالة تم تسمية الوسيط postdata$ هذا يعني ببساطة أنه ضمن هذه الدالة سيتم الإشارة إلى البيانات التي يتم تمريرها إلى هذه الدالة كوسيط بـ.postdata$ إنشاء مقتطفات يمكن أن تحتوي الدوال على وسائط متعددة وقيم افتراضية لهذه الوسائط. دعونا ننشئ دالة يمكن أن تحول أي نص إلى مقتطف عن طريق قطعه إلى قطع نصية. نريد دالة لتكون مرنة قدر الإمكان، وقادرة على السيطرة على طول المقتطف، وإلحاق السلسلة إلى النهاية. سنجعل الوسيط الأول النص الذي نريد تقصيره، الوسيط الثاني سيكون لتحديد مقدار المحارف التي نريد اقتطاعها، والثالث النص المُلحق. دعونا نبدأ بإعطاء الدالة إطار للعمل ضمنه: function make_excerpt( $text, $length = 200, $append = '...' ) { } لاحظ أنني أعطيت قيمًا افتراضية لهذه الوسائط. هذا يعني أنه يمكنك استدعاء الدالة دون تمرير الوسيطين الثاني والثالث. إذا قمت بذلك سوف تفترض الدالة أنك تريد إنشاء مقتطف طويل من 200 حرف وإلحاق ثلاث نقاط بعد ذلك. دعونا نكتب محتوى هذه الدالة: function get_excerpt( $text, $length = 200, $append = '...' ) { if( strlen( $text ) < $length ) { return $text; } else { $excerpt = substr( $text, 0, $length ); $excerpt .= $append; return $excerpt; } } لقد أضفت الكثير من الأشياء الجديدة في هذه الدالة، لذلك دعونا نشرح كل إضافة جديدة بالتفصيل. يبدأ كل هذا بعبارة if، الذي تتحقق مما إذا كان النص المعطى أطول من طول معين. وذلك باستخدام دالة مبنية مسبقًا في لغة PHP تدعى ()substr. تأخذ هذه الدالة سلسلة حرفية كوسيط وتعيد طولها. إذا كان طول text$ أقل من length$ يتم إرجاع النص ببساطة - سنتحدث عما يعني الإرجاع خلال لحظات. وإلا، فإننا ننشئ مقتطفًا باستخدام الدالة ()substr. هذه الدالة تقطع سلسلة حرفية وتتطلب ثلاثة وسائط: النص الذي سنقتطع منه، ومن أين تبدأ بالاقتطاع، وطول النص الذي نرد اقتطاعه. نريد أن نبدأ من بداية النص وقطع أحرف length$، وهذا هو السبب لإضافتي رقم 0 كي يقتطع من بداية السلسلة الحرفية. وأخيرًا، نضيف النص الملحق إلى النهاية. لقد استخدمت .= للقيام بذلك. هذه هي نفس كتابة $excerpt = $excerpt. $append في السطر الأخير، قمت بإعادة متغير excerpt$. ما هو الإرجاع؟ حتى الآن كنا في معظم الأحيان نظهر المخرجات، ولكن في كثير من الحالات نحن لا نريد عرض نتيجة حساباتنا. الدالة ()strlen هي مثال جيد على ذلك. أنت لا تريد فعلاً عرض طول متغير text$ أنت ترغب فقط في استخدامه في التعليمات البرمجية لتحقيق شيء ما. ()strlenترجع هذه القيمة، مما يسمح لك باستخدامها في مكان آخر. عند إرجاع قيمة باستخدام دالة، يمكنك إما استخدامها مباشرة مثل دالة ()strlen، أو تعيينها لمتغير $short_text = get_excerpt( $content ) يمكنك بعد ذلك إظهار short_text$ في وقت لاحق عند الحاجة. لمزيد من القراءة والدراسة PHP هي الأساس لجميع قوالب و إضافات WordPress لذلك سوف تحتاج إلى الاعتماد بشكل كبير جدًا على هذه اللغة. عند العمل في بيئة ووردبريس، ستستخدم دوال PHP (مثل strlen و substr)، ولكن هناك أيضًا مئات من الدوال التي تم إنشاؤها خصيصًا لووردبريس من قبل فريق التطوير الأساسي لمساعدتك. ستكتشف بعض هذه الوظائف في الدروس القادمة من هذه السلسلة. لقد غطينا الأساسيات التي تحتاج إلى معرفتها للبدء بتطوير ووردبريس، ولكن الحقيقة هي أننا فقط خدشنا السطح! من المهم أن تقرأ وتستكشف كل المواضيع المتعلقة بووردبرس وPHP لمزيد من العمق والممارسة. ترجمة -وبتصرّف- للمقال WordPress Development for Beginners: Learning PHP لصاحبه Daniel Pataki
-
AngularJS هي إطار عمل لتطبيقات الويب من طرف المستخدم يقوم بتفسير نصوص HTML مرة ثانية، ولو كنت خبيرا في تطوير الويب فمن الطبيعي أن تحاول مقارنة AngularJS مع منصات ومكتبات JavaScript التي تألفها مثل jQuery ،Knockout ،Backbone ،Ember وربّما مع React أيضا، وربما حاولت بناءً على معارفك السابقة ببرمجة واجهة المستخدم الرسومية GUI أن تربط AngularJS بـMVC أو MVVM، إلّا أنّ هذه المقارنات ستجعل معرفتك بـAngularJS أكثر ضبابية، لذا سأطلب منك في هذا الفصل فقط أن تتوقف عن النظر إلى AngularJS على أنها إطار عمل للغة JavaScript، كما أرجو منك أن تتخلّى في البداية عن رغبتك في فهم آلية عمل Angular وأن تحاول أخذها كما هي دون تفاصيل، فلتعتبرها مجموعة قوية من التطويرات لـHTML. سنبدأ دروسنا مع البنى الثّلاث الأساسيّة في AngularJS : العبارات expressions، التّوجيهات directives والمجالات scopes ولكننا سنبدأ قبل ذلك بالتعرف على كيفية تشغيل Angular في صفحة ويب. التثبيتيمكنك جلب Angular من الموقع الرسمي ثم تحميلها إلى صفحتك عن طريق المكاتب المستضافة عند Google (كـCDN) وهي طريقة ملائمة وتعمل جيدا، وقد قمنا بتشغيل شيفرات Angular عن طريق إضافة الاستدعاء التّالي في رأس ملف HTML: index.html <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js"></script>والآن بإمكاننا البدء معًا. بعد تضمينك لملف المكتبة في رأس الصفحة ستكون الخطوة الأولى تحديد الجزء الذي ستعالجه Angular داخل مستند HTML، تذكر دومًا أن Angular موجّهة نحو HTML أكثر من توجهها نحو JavaScript، فمبدؤها العام هو: بدلا من كتابة شيفرة JavaScript ثم تنفيذها، نقوم بكتابة خصائص HTML غير معياريّة تفهمها Angular وتقوم بمعالجتها. وهنا سنتعرّف على الخاصّية الأولى ng-app التي يمكن إضافتها إلى أي عنصر من عناصر مستند HTML، وقد اخترنا وضعها كخاصية للعنصر body في مثالنا هذا، فعند وضعها في body أو في html ستقوم Angular بمعالجة المستند كاملًا بحثًا عن تعليماتها لتقوم بتنفيذها، وبالطّبع يمكنك تحديد مجال أضيق كفقرة أو عنوان فقط، إن أردت أن تستعمل بيئة عمل أخرى إلى جانب Angular أو تحميل عدّة تطبيقات لـAngular في نفس المستند. إذًا لنكتب في المستند الذي نعمل عليه الشيفرة التالية: index.html <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js"></script> </head> <body ng-app> <!-- كل الأمثلة توضع هنا --> </body> </html> بهذه الخاصية السحرية سنتمكن من جعل Angular تعالج تعليماتها الموجودة داخل الصفحة، والآن لنتعرف على إمكانيات هذه المكتبة وما الذي يمكنها فعله. العبارات Expressionsتحذير: إذا كنت تتبنّى فكرة إخفاء شفرات جافا سكريبت فالمثال التالي سيثير حفيظتك حول Angular فهي تعتمد على كتابة عبارات شبيهة بعبارات JavaScript داخل نصوص HTML. تشمل عبارات Angular أي عبارة بسيطة وصحيحة في JavaScript إلّا أنّها لا تسمح بتعليمات التّحكم بسير البرنامج مثل الحلقات وغيرها، وأرجو منك تأجيل أحكامك المسبقة بينما نستكشف الأمور المسموحة (والتي يمكن ألا تكون مستحسنة) في Angular بطرق التّجريب التّقليدية. لنبدأ بجمع عددين إلى بعضهما: <p>The number {{11 + 12}}.</p>الناتج The number 23.هيا انطلق، قم بتغيير 12+11 في المثال السابق إلى أي عبارة رياضيّة أخرى، جرب إن كان بإمكانك إيجاد شيء لا يمكن لـAngular معالجته (عندما تفشل Angular في معالجة عبارة ما، فإنّها تعرض السلسلة الأصلية دون تغيير، أو لا تعرض شيئا في بعض الحالات الأخرى). الأقواس المتعرجة المزدوجة هي التي تحدد قالب Angular، وقد تكون قد شاهدتها من قبل لو تعاملت مع Mustache أو مع Handlebars، أحيانًا يمكنك التّفكير في Angular بانها مكتبة قوالب شديدة التعقيد، فهي تتعامل مع كل شيءٍ داخل العنصر الذي قمت بإضافة الخاصية ng-app إليه على أنه قالب وتقوم بترجمته عند تحميل الصّفحة، ثم تقوم بإعادة عملية الإخراج كلما حدث تغيير على البيانات (لا تقلق إن لم يكن مفهوم القوالب مألوفًا لك فسوف نتطرّق إلى مبادئه لاحقًا). ماذا عن اختبار المساواة لقيمتين؟ بالطّبع يمكننا القيام بهذا أيضًا. <p>Are strings and numbers equal? {{'2' == 2}}</p>الناتج Are strings and numbers equal? trueالنّتيجة موافقةٌ لما هي عليه في JavaScript، إذا كنت متفاجئًا بناتج عمليّة المقارنة السّابقة فقم بمراجعةٍ سريعة لعملية المقارنة ثم قم بتغيير == إلى === في المثال السّابق، لترى اختلاف النّتيجة. فيما يلي مثال لدمج سلسلتين نصيتين، ويوضح قدرتنا على الوصول إلى توابع مكتبة JavaScript المعيارية مثل توابع السلاسل النصية كالتابع toUpperCase. <code><p>{{"Angular" + "js".toUpperCase()}}</p></code>الناتج AngularJSهل تشعر الآن بأنّه بإمكانك القيام بأي شيء داخل عبارات Angular؟ لا تكن متسرّعًا يا شريك، وانظر إلى المثال التّالي: <!-- كود خاطئ! هذه الدالة ليست مسموح بها داخل عبارة --> <p>{{alert("Hello world")}}</p>لا يمكنك استخدام التّابع alert كما لا يمكنك الوصول إلى معظم الكائنات العامة مثل Math، Number و Date وهلم جرا. حاول استبدال ("alert("Hello world في المثال السّابق بـ ("parseInt("1 أو ()Date.now أو Number.Nan أو ()Math.random، إن لم تنتج أي مخرجات فهذا يعني أن Angular قد رفضت معالجة العبارة. لا بد من أن التساهل في مسألة دمج الشيفرة التنفيذية مع نصوص HTML قد أتعبك، وزاد عليه محدوديّة ما يمكنك القيام به داخل عبارات Angular، ولكن لا تتوقّف هنا فهناك الكثير بانتظارك، لنحاول الوصول إلى حدود إمكانيات العبارات في Angular، هل تظن بأنها تسمج بإسناد المتغيرات؟ <p>{{a = 1; a + a}}</p>الناتج 2إنها تعمل، ولكن حاول إضافة الكلمة المفتاحية var إلى اسم المتغير، فلن تقوم Angular بمعالجة العبارة وستصدر خطأ، فعندما ترى العبارة كما هي مع الأقواس المتعرجة فهذا يعني حدوث خطأ في الترجمة، لا تشعر بالاستياء، فتخريب الأشياء يكون أحيانًا وسيلة ممتازة للتعلم. هكذا تكون التجربة، لا أدري إن كان بالإمكان تعريف متغيّر في مجموعة من الأقواس المتعرّجة ثمّ استخدامه داخل مجموعة أخرى، لم لا نجرّب ذلك؟ <p>{{a = 1}} remains {{a}}</p>الناتج 1 remains 1إنّها تعمل أيضًا، ولكن ماذا لو نقلنا تهيئة المتغيّر إلى العبارة الثّانية؟ هيّا جرّبها، هل عملت؟ هل يمكنك معرفة السبب المحتمل وراء ذلك؟ حسنًا، العبارات تدعم عمليّة إسناد المتغيّرات، ما رأيك بتجربة معامل الشّرط الثلاثي؟ <p>There {{count = 1; (count == 1 ? "is " : "are ") + count}} of them.</p>الناتج There is 1 of them.من حسن حظّنا أنها تعمل أيضًا، فهذه العمليّة الثلاثية توفّر لنا تركيبًا مختصرا عمليًا داخل القوالب، والآن ماذا عن عملية الزّيادة "++"، هل يمكننا استخدامها؟ <p>{{a = 1; ++a}}</p>الناتج 1من الواضح أنّها لم تعمل، فهل هذا يعني بأنّ حلقة for غير موجودة في Angular، لم لا نستغني عن الكلمة var ونستبدل عملية الزّيادة "++" بجمع عادي. <p>{{for (i = 0; i < 10; i = i + 1) {i}}}</p>الناتج {{for (i = 0; i < 10; i = i + 1) {i}}}لم يتمّ تشغيل شيفرة الحلقة، كما أنّها سبّبت إصدار خطأ نحوي يمكن رؤيته من نافذة المتصفح console، رغم أنّ الحلقة ليس فيها أي خطأ ويمكن نسخها ولصقها في النافذة ليتم تشغيلها وستصل إلى العدد 9، جرّبها لتتأكّد بنفسك. إذًا لقد وصلنا إلى بعض الحدود، عبارات Angular ليست JavaScript، فـلغة العبارات لا تدعم الشروط، الحلقات ولا رمي الأخطاء واستلامها. يبدو أنّنا وصلنا إلى حدود العبارات، بالنّسبة لي فأنا أتقبّل وجود بعض شيفرات JavaScript داخل نص HTML إن كانت شيفرات مختصرة ومتعلقة بالعرض، لذا فأنا أقدّر الطبيعة المتساهلة لـAngular مع هذا الأمر، ولكن هذا لا يعني أنّني أشجع على كتابة شيفرات JavaScript أكبر من ذلك، فذلك سيتحوّل سريعًا إلى خربشات مربكة وغير مقروءة. من الجيّد أنّ العبارات لا تلعب إلّا دورًا بسيطًا في Angular، ويجب ألّا يكون هناك داع لكتابة الكثير من الشيفرات داخل العبارة الواحدة، فالمفتاح الحقيقي للإنتاجيّة المذهلة لـAngular هو التوجيه directive. التوجيهات Directivesالتّوجيهات هي روح Angular وقلبها النّابض، وأنصحك بأن تنظر إليها على أنها HTML معدلة، ففي كثير من الأحيان ترى أنها تشابه إلى حد كبير خصائص HTML التي يمكن استخدامها مع عناصر عاديّة ومألوفة. تبدأ التوجيهات المدمجة مع Angular عادة بالسابقة ng- التي تدل على الحرفين الثاني والثالث من كلمة A**ng**ular، كما أنّك ستجد عددًا هائلًا من التّوجيهات التي برمجها طرف ثالث متاحة للاستخدام. أول ما عليك التفكير به عندما تواجه شيفرة JavaScript مطولة داخل أحد التعبيرات في Angular هو أنه لا بد من وجود توجيه يقوم بذلك. لقد قمنا باستخدام أحد التّوجيهات مسبقًا بالفعل، هل تذكر التّوجيه الذي يجعل Angular تعالج محتويات العنصر body، إنه التوجيه ng-app، ففي هذه الحالة استخدمنا التوجيه دون تمرير أي وسطاء إليه، ولتمرير الوسطاء إلى التوجيهات ما عليك سوى استخدام "=" كما تقوم بإسناد القيم إلى خصائص HTML تمامًا. يمكنك على سبيل المثال تمرير اسم التّطبيق كوسيط "ng-app="myApp. (اسم التطبيق يشكل فعليا اسم وحدة وهي جزء هام من بنية Angular، وسنقوم بتغطيته في فصل الوحدات) ng-bindتقبل بعض التوجيهات تمرير سلاسل نصية تحوي عبارات لتقوم بتفيذها، (يمكنك التعرف على محددات كل توجيه من التوجيهات بزيارة توثيق API الخاصّبه)، فمثلًا يقوم التوجيه ng-bind بمعالجة العبارات وإخراجها، تمامًا كالأقواس المتعرّجة المزدوجة التي رأيناها في الفقرة السابقة، والمثال التالي يوضح استخدامه: <p>The number <span ng-bind="11 + 12"></span>.</p>الناتج The number 23.قد تجد أنّ المثال السابق مطابق لأول مثال تطرّقنا إليه، إلا أنّ هناك فرقًا هاما هو أن ng-bind تسبب إخفاء العبارة ريثما تقوم Angular بالترجمة وعملية الإخراج، ولذلك فهي الطريقة الأكثر تفضيلًا لاستخدام العبارات في Angular، فأثناء فتح الصّفحة وترجمتها ثمّ إخراجها لن تظهر العبارات والأقواس المتعرّجة، ولك أن تتخيّل شكل صفحة مليئةٍ بالعبارات قبل أن تنتهي عمليّة الإخراج خصوصًا إن كان هناك تأخير كبير بسبب كِبَرِ حجم الصّفحة وكثرة عباراتها. ربما ترغب في إخفاء كامل المحتوى أو جزءًا كبيرًا منه ريثما تنتهي عمليّة الإخراج بشكل كامل، وهذا ما تتيحه لك ng-cloak، لا بد من وجود توجيه يقوم بذلك. ng-initهل تذكر قيامنا بتهيئة المتغيّر في العبارة لنرى هل يعمل أم لا، حسنًا لا بدّ أن تحزر الآن، هناك توجيهٌ للقيام بهذا أيضًا، فالتّوجيه ng-init يسمح لك بتهيئة المتغيّرات لاستخدامها في أي مكان داخل العنصر الذي طبقت هذا التوجيه عليه. <div ng-init="sum = 3 + 2"> <p> {{sum + 1}} is more than <span ng-bind='sum - 1'></span> </p> </div>الناتج 6 is more than 4كما يمكنك استخدام الفاصلة المنقوطة لتعريف عدّة متغيّرات داخل توجيه ng-init كما يوضّح المثال التّالي: <div ng-init="count = 7; units = 'days'; collection = 'week'"> <p> There are {{count}} {{units}} in a {{collection}}. </p> </div>الناتج There are 7 days in a week.وقد تجد عند مرحلة ما أنه من الضروري تنظيم متغيّراتك داخل كائنات. <div ng-init="time = {count: 12, units: 'months', collection: 'year'}"> <p> There are {{time.count}} {{time.units}} in a {{time.collection}}. </p> </div>الناتج There are 12 months in a year.والمصفوفات مفيدة أيضًا. <div ng-init="months = ['January','February','March','April']"> <p> {{months[3]}} follows {{months[2]}} in {{months}}. </p> </div>الناتج April follows March in ["January","February","March","April"].انتبه، فلا مجال للخطأ في أسماء العناصر داخل الكائن، فـAngular لا تساعدك في تحديد هذا الخطأ وكلّ ما تقوم به هو عدم ترجمة العبارة وتجاهلها، وكذلك الحال في أخطاءِ الوصول إلى عناصر كائنٍ غير موجود أصلًا والوصول إلى عناصر خارج حدود المصفوفة. <div ng-init="paragraph = {sentence: {words: ['first','second','third']}}"> <p> "{{typo.sentence.words[0]}}", "{{paragraph.typo.words[1]}}", "{{paragraph.sentence.typo[2]}}", "{{paragraph.sentence.words[3]}}". </p> </div>الناتج "", "", "", "".كنت أتمنّى لو أن Angular تحتوي على عملية اختبار الوجود كالموجودة في CoffeeScript لجعل التّساهل مع هذه الأخطاء خيارًا وليس القاعدة. والآن بعد أن رأينا سماحيّات Angular هل تتوقع بأنها تسمح بتعريف التوابع داخل ng-init؟ ما الذي تتوقThere are months in a year.عه؟ <div ng-init="count = function() { return 12; }"> <p> There are {{count()}} months in a year. </p> </div>الناتج There are months in a year.لا، لا تسمح Angular بعبارات تعريف التوابع، كما أنها تقوم برمي خطأ parse:syntax$ أثناء معالجة الوسيط الممرّر للتوجيه ng-init، ويمكنك رؤيته في نافذة المتصفح console، فالمتحكم هو المكان الصحيح لتعريف التوابع لاستخدامها في عبارات Angular، وسنتعرف عليها في فصل المتحكمات وهي في الحقيقة المكان المناسب لتحضير جميع بيانات التطبيق للعرض، أمّا التّوجيه ng-init فوظيفته الأساسية هي تغيير أسماء المتغيرات لسبب سنراه لاحقًا في فصل المجموعات. ng-non-bindableيمكن استخدام التوجيه ng-non-bindable لمنع Angular من معالجة جزء من المستند، كما يوضح المثال التالي: <p ng-non-bindable> {{2 * 2}} is the same as <span ng-bind='2 + 2'>?</span> </p>الناتج {{2 * 2}} is the same as ?جرب إزالة التوجيه السابق لترى ما سيحدث. ng-showحان الوقت للتّعرف على أمور أكبر من مجرّد معالجة وإخراج ناتج عبارة، سؤالٌ للمبتدئين: كيف يمكننا إظهار وإخفاء عنصر HTML حسب شرطٍ ما؟ احتجت مرة لإخفاء نموذج استمارةٍ بعد أن يقوم المستخدم بملئها بنجاح، فقمت بإضافة استدعاء للتابع jQuery.hide داخل متحكّم قمت بإنشائه في Angular، لقد عمل بشكل صحيح رغم أن تلك الطريقة ليست هي الأفضل للقيام بذلك، ولكن الرغبة في إنهاء المشروع سريعًا دفعتني لتجنب البحث عن التّوجيه الّذي يقوم بذلك في Angular، وبالفعل وجدت توجيهين للقيام بذلك لا واحدًا فقط، ng-hide وng-show وسيبيّن المثال التالي استخدامهما معًا: <p ng-init="authorized = true"> The secret code is <span ng-show="authorized">0123</span> <span ng-hide="authorized">not for you to see</span> </p>الناتج The secret code is 0123جرّب تغيير true إلى false في المثال السابق لترى ما سيحدث، إنّ Angular تراقب التحديثات الّتي تطرأ على المتغيرات طوال الوقت، ولذلك فسيؤدّي تغيير المتغير authorized في أي مكان إلى تغيير نتيجة المثال السابق في العرض. أرى أنه يمكننا التعمق الآن في الحديث عن المتغيرات لنعرف ماهيّتها الحقيقيّة. المجالات Scopesتُعدّ المجالات مصدر البيانات الوحيد داخل تطبيقك، والفكرة من ورائها هي أنّه مهما كان عدد الأماكن الّتي تسخدم فيها المتغيّر في طبقة العرض، يجب عليك الالتزام بموضع واحدٍ لتغيير قيمته ويجب أن ينتشر هذا التغيير تلقائيًا إلى أماكن استخدام هذا المتغيّر في العرض. بما أنّ عملية الإخراج وإعادة الإخراج تحتاج بنيةً تحتيّة، فأكثر ما ستلاحظه في كائنات JavaScript الّتي تضعها في مجالات Angular هو كم هي مألوفة واعتياديّة بالنسبة لك. قد تكون ملمًّا بمفهوم كائنات نموذج المجال القديمة البسيطة، والذي أصله كائنات Java القديمة البسيطة أو ما يُعرف اختصارًا لـPOJO، فعندما قام Martin Fowler بشرح مفهوم POJO للمرّة الأولى، كان يعني الكائنات الأساسيّة الاعتياديّة التي يقدّمها قلب اللغة في وقت التشغيل runtime، على عكس كائنات نموذج المجال domain model المعقّدة الّتي ترث قدرات خاصّة من فئة متفوّقة superclass في إطار العمل. لقد تمّ توسيع هذا المصطلح ليشمل الكائنات التي تبدو بأنّها بسيطة إلّا أنّ إطار العمل يحسّنها بإضافة قدرات خاصّة بشكل خفي في وقت التشغيل بشكل مستمر عادة. الكائنات المرتبطة بمجالات Angular هي POJOs خاصة بـJavaScript، ويبدو أن Angular ستصبح حقا إطار عمل جافا سكربت البسيطة القديمة عندما سينتشر استخدام الميزة الجديدة Object.observe بين أوساط المبرمجين، وذلك لأنّها تقوم بعمليات معقدة للتّعرف على التّغييرات أثناء وقت التشغيل لتسمح بانتشار تأثير هذه التّغييرات. لقد مررنا مسبقاً على العديد من خصائص المجالات scope properties في هذا الفصل، هل تذكر المتغيّر الّذي قمنا بتهيئته داخل العبارات واستخدمنا ng-init في المثال أعلاه، كلّ هذه كانت من خصائص المجالات، هل تذكر محاولة إضافة الكلمة المفتاحية var إلى إحدى العبارات؟ إنّ استخدامها ممنوعٌ لأنّ ما كنت أقول بأنه متغيّرٌ لم يكن كذلك في الحقيقة(وأعتذر لأنّني كذبت بشأنه) فهو في الحقيقة أحد الخصائص في كائن المجال، يتمّ إنشاؤه تلقائياً خلف الكواليس وسنغطّي في الدّرس القادم المجالات بتفاصيل أعمق، وسنكتفي هنا ببعض الأمثلة الّتي تبين كيفيّة استخدام خصائص المجالات. الربط ثنائي الاتجاهكل الأمثلة السّابقة كانت تستخدم ربطًا أحادي الاتجاه، حيث يتم تحديث بيانات المجال باستمرار في العرض view، وسيزداد الأمر إثارةً عندما نستخدم HTML للتّحكم بهذه البيانات وتغييرها، ومعًا ستشكّل هاتان الطّريقتان في تغيير البيانات الربط ثنائيّ الاتّجاه كمثال مبدئي أوّل، سنستخدم التّوجيه ng-click للتعديل على خاصّية بوليانية boolean. <p ng-init="authorized = true"> The secret code is <span ng-show="authorized">0123</span> <span ng-hide="authorized">not for you to see</span> <br> <input type="button" value="toggle" ng-click="authorized = !authorized"> </p> يمكن أن يكون الوسيط الممرّر للتوجيه ng-click أي عبارة، ورغم أنّ هذا التّوجيه غير محدود بالعمل ضمن خصائص المجالات، إلا أن الشّيفرة الّتي كتبناها لقلب القيمة البوليانية تعمل بشكل صحيح لأنها بسيطةٌ جدًّا، ولكن كيف يمكننا ربط أدوات الدّخل الأخرى والتّعامل مع أنواع متغيّرات أكثر تعقيدًا؟ ng-modelيبدو أنّ جميع شروحات Angular لربط البيانات تسخدم مثالًا لربط دخلٍ نصّيّ بخاصّيةٍ من نوع سلسلةٍ نصّيّة، وها قد حان دورنا لكتابة هذا المثال. <input type="text" ng-model="title"> is bound to "<strong ng-bind="title"></strong>". Type something in the box!هذا المثال هو الطّريقة الأمثل لتوضيح مسألة الربط ثنائيّ الاتجاه، فعندما نضيف التّوجيه ng-model إلى عنصر input الخاصّ بـHTML، فإنّ Angular تقوم بتغليف تحكّم HTML به عن طريق توجيه input الخاصّ بها. ما الذي يمكننا القيام به أكثر من هذا؟ بإمكاننا دومًا استخدام ng-init لتهيئة قيمة ابتدائية للخاصية. <input type="text" ng-init="title = 'Angular'" ng-model="title"> is bound to "<strong ng-bind="title"></strong>". Change it!لنجرّب الآن بعض أدوات الإدخال الأخرى، لنبدأ بـcheckbox. <input type='checkbox' ng-init='optIn = true' ng-model='optIn'> is bound to <strong ng-bind="optIn"></strong>. Change it!القيمة المرتبطة بصندوق checkbox يمكن أن تكون سلسلةً نصّيّةً بدلًا من كونها قيمة بوليانيّة، وذلك بتأهيل قيمة كلٍ من التّوجيهين ng-true-value وng-false-value. <input type='checkbox' ng-init='feeling = "love it"' ng-model='feeling' ng-true-value='"love it"' ng-false-value='"hate it"'> is bound to "<strong ng-bind="feeling"></strong>". Change it!هل يمكنك توقّع وظيفة التّوجيه select في Angular؟ لاحظ أنّ Angular تتجاهل تمامًا وجود الخاصّية selected في الخيارات المقدّمة، وحتّى لو قمت بإزالة التّوجيه ng-init فستبقى بلا تأثير. <select ng-init='answer = "maybe"' ng-model='answer'> <option value='yes' selected>Yes</option> <option value='no'>No</option> <option value='maybe'>Maybe</option> </select> is bound to "<strong ng-bind="answer"></strong>". Change it!يبدو أنّ المثال السّابق يناسبه وجود radio buttons أكثر من قائمة الخيارات، هيّا نغيّره إذًا. <div ng-init='answer = "maybe"'> <input type='radio' ng-model='answer' value='yes'> Yes <input type='radio' ng-model='answer' value='no'> No <input type='radio' ng-model='answer' value='maybe'> Maybe is bound to "<strong ng-bind="answer"></strong>". Change it! </div>لديك الآن بعض خبرات الواقع العمليّ في التّعامل مع بيانات المجالات باستخدام توجيهات Angular، ولا يزال هناك الكثير من التّوجيهات المدمجة في Angular، وسنتعرف على العديد منها في الفصول القادمة. خلاصةلقد طلبت منك في مطلع هذا الفصل ألا تنظر إلى Angular على أنها إطار عمل لـJavaScript، بل كامتداد لـHTML، فكما أخبَرَنا Miško Hevery مخترع Angular في هذه المقابلة الرائعة فإن الهدف الأساسي من Angular هو أن تكون طريقة لزيادة إنتاجية مطوري الـ front-end لتحسين صفحات الويب، وقد صارت لاحقًا إطار عمل لـJavaScript. لقد تم الانطلاق من فكرة كون نمط البرمجة التصريحية هو أفضل الخيارات لتسريع عملية تطوير واجهات المستخدم الرسومية GUI، وقد اختار مطوروها ألا تكون لغة محصورة في مجال محدد مثل ما كانت MXML وXUL بل أرادوا جعلها تعتمد على تشابهها الكبير مع نصوص HTML. لقد رأينا بما يكفي أن Angular لا تستخدم دون JavaScript معدلة، كما أن التطبيقات في الواقع العملي في Angular تستخدم دومًا المتحكمات والخدمات والمسرات كما تدعم الوحدات وحقن التابعية إضافة إلى اعتمادها على البنية التحتية لـAjax، وسنغطي في هذه السلسلة جميع هذه الأمور، وعلى أي حال فإن وعد الإنتاجية الذي تقدمه Angular يمكن تحقيقه في فضاء تصريحي، مع درجة من الاعتماد على لا بد من وجود توجيه يقوم بذلك، كما أنّ كتابة توجيهات مخصصة لملء الفجوات هو الأمر الأكثر تحدّيًا في Angular، وهذا ما سيحاول الفصل الأخير إيصاله ليستقرّ في ذهن القارئ. والآن بعد أن استوعبت أن الهدف الأسمى لـAngular هو إيجاد امتدادات لـHTML لزيادة الإنتاجيّة وليس كتابة شيفرات JavaScript داخل إطار عمل، فأنت الآن جاهز لتبحر في تفاصيلها مع الفصول القادمة. ترجمة وبتصرّف للفصل الثاني من كتاب: Angular Basics لصاحبه: Chris Smith.
-
حول لينكسغنو لينكس GNU/Linux هو نظام تشغيل حرّ ومفتوح المصدر يدمج بين مشروعين مختلفين، الأول هو مشروع GNU لكتابة نظام تشغيل حرّ من الصفر والذي كاد يجهز مع بداية التسعينات باستثناء الجزء المسمّى بنواة النظام، في هذه الأثناء كان لينوس تورفالدز قد طوّر نواة نظام تشغيل كهواية، فجاءت الفكرة لاختصار الجهد بدمج المشروعين وتقديمهما تحت اسم غنو لينكس، والذي سيشيع لاحقًا باسم لينكس. ورغم أن لينكس سهل الاستخدام إلا أن القادمين الجدد من Windows يجدون صعوبة في فهم بنيته والتعامل معها، لذا سنستعرض في هذا الدرس بعض المفاهيم والأدوات الأساسيّة حول لينكس. الطرفيّةقبل أواخر التسعينيات زُوّد نظام التشغيل غنو لينكس بواجهات رسوميّة لتسهيل التعامل معه، إلا أنّ الطرفيّة (والتي يمكن تشبيهها مبدئيًا بموجّه الأوامر في Windows) لا تزال أداة قويّة وفعّالة في كثيرٍ من الحالات، لا سيما عند إدارتك لخادوم يعمل تحت نظام لينكس، حيث يتمّ ذلك عبر سطر الأوامر فقط، إذ تنفّذ جميع المهام الإدارية من خلال كتابة الأوامر والضغط على زرّ الإدخال Enter لتنفيذها، يشمل ذلك التعديل على الملفات، تركيب الحزم، وإدارة المستخدمين. الطرفية ببساطة هي تلك النافذة السوداء التفاعلية، حيث نكتب الأوامر لتنفيذها، بينما تعيد هي الخرج لنا طباعةً على الشاشة نفسها. التعامل مع المجلدات ضمن الطرفيةيُؤسّس نظام الملفات في لينكس على شكل شجرة من الأدّلة، بحيث يمكنك إنشاء المجلدات داخل بعضها البعض، وإنشاء الملفات في أيٍ مجلدٍ منها. لمعرفة ما هو الدليل الذي تقف عنده حاليًا، نفّذ الأمر: pwdيمثّل الأمر السابق اختصارًا لعبارة "print working directory" أو "اطبع مجلد العمل الحالي"، وسوف يعيد لنا على الشاشة مسار المجلد النشط حاليًا، وهو غالبًا ما سيكون شيء مشابه لما يلي: /home/foo/ وهذا يعني بأن المجلّد النشط حاليًا هو "foo" والموجود داخل المجلد "home" والمضمّن بدوره داخل الدليل الجذر "/"، يُقصد بالمجلّد النشط ذاك الذي ستنفّذ عنده الأوامر المُدخلة، لتوضيح هذه الفكرة سنطبّق الأمر "ls" والذي يعرض الملفات والمجلدات الموجودة في الدليل النشط: ls يعرض خرج الأمر السابق أسماء الملفات والمجلدات الموجودة ضمن الدليل "foo"، ولتغيير المجلد النشط نستخدم الأمر cd، وهو اختصار لعبارة "change directory" أو غيّر الدليل/المجلد: cd <name of directory>للدخول إلى مجلد مضّمن بالدليل النشط يُكتفى بكتابة اسمه مباشرةً، بينما للانتقال إلى دليل آخر خارج "foo" فيجب كتابة مساره كاملًا، تحقّق دومًا من المسار النشط بالأمر pwd. إضافةً لذلك يمكن استخدام اللاحقة .. للانتقال مجلد واحد إلى الأعلى ضمن المسار نفسه: cd .. لإنشاء مجلد جديد نستخدم الأمر mkdir (لا تنس أن الأمر سينفذ ضمن المجلد النشط حاليًا وسيُنشأ المجلد هناك): mkdir bar يتيح لنا الأمر rm حذف المجلدات والملفات التي لم نعد بحاجة إليها، وعن طريق إضافة اللاحقة -d سينفذ الأمر فقط في حال كان المجلد فارغًا: rm -d barبينما نستخدم اللاحقة R- تعني Recursive أي تكرارية وهي لحذف المجلد ومحتوياته. التعامل مع الملفات ضمن الطرفيةلاستعراض محتويات ملف ما نستخدم الأمر cat؛ لنقل أنه لدينا الملف baz ضمن الدليل الحالي، يَطبع الأمر التالي محتويات هذا الملف على شاشة الطرفية: cat bazمع الملفات الطويلة لن يكون الأمر السابق مجديًا، حيث سَيَعرض لنا الصفحة الأخيرة فقط من الملف على شاشة الطرفية، وسنحتاج إلى الصعود يدويًا للوصول إلى الصفحة الأولى ومن ثم تقليب الصفحات نزولًا! للتعامل مع مثل هذه الملفات نستخدم الأمر less والذي يعرض الصفحة الأولى من الملف، ومن خلال الضغط على زر المسافة Space يمكننا تقليب الصفحات وصولًا إلى نهاية الملف: less bazيمكننا أيضا استخدام زر السهم السفلي للنزول سطر واحد إلى الأسفل، والضغط على زر "q" لإنهاء العرض. لإنشاء ملفات جديدة سوف نستخدم الأداة touch: touch foobarيُنشئ الأمر السابق ملفًا فارغًا باسم foobar داخل الدليل النشط لديك. إذا لم يعجبك الاسم السابق فيمكنك استخدام الأمر mv لإعادة تسميته: mv foobar fizzbuzz الأمر mv هو اختصار للكلمة move أو "حرّك"، ويمكن استخدامه لنقل ملف أو مجلد من مكانٍ لآخر، أو لإعادة التسمية مع النقل: mv foobar Docs/fizzbuzz ينقل الأمر السابق الملف foobar إلى المجلد Docs الموجود ضمن الدليل الحالي، ويُعيد تسميته إلى fizzbuzz. كما يمكننا استخدام الأمر cp لنسخ الملف foobar إلى الدليل المطلوب باسم جديد، بحيث يبقى الملف الأصليّ دون تعديل: cp foobar Docs/fizzbuzz الأمر cp هو اختصار للكلمة "copy" أو "انسخ"، ويمكننا استخدامها بالشكل التالي أيضًا: cp foobar fizzbuzz وهكذا نحصل على نسختين من الملف باسمين مختلفين ضمن المجلد نفسه. لكن ما هي قيمة ملف فارغ؟ للتعديل على ملف ضمن الطرفية نحتاج إلى محرّر نصيّ، ولدينا بالتأكيد العديد من الخيارات، مثل محرري vim و emacs الشهيرين، أو محرر nano الأكثر بساطة وشبيهه pico. للمبتدئين فإن المحرر nano هو خيار ممتاز، نظرًا لسهولة التعامل معه وبساطة تعلمه، دون الحاجة إلى كتب أو دورات تعليمية! ببساطة؛ للتعديل على الملف foobar نستخدم الأمر: nano foobar والذي سينقلنا إلى واجهة المحرّر البسيطة ومساحة فارغة للكتابة، بعد الانتهاء من الكتابة ولحفظ العمل نضغط على Ctrl-X ، حيث يسألنا المحرر عن رغبتنا بحفظ التعديلات، نضغط y للموافقة ثم Enter لنعود مجددًا إلى الطرفية. ملفنا الآن يضم بعض النصوص التي أدخلناها للتوّ، ويمكن التحقق من ذلك بعرض محتوياته باستخدام إحدى الأداتين cat أو less. أخيرًا، يمكنك حذف الملف بواسطة الأمر rm: rm fizzbuzz وخلافًا للمجلدات، تُحذف الملفات بغض النظر عن وجود محتوى ضمنها من عدمه. التسلسل الهرمي القياسي لنظام الملفاتتتوافق جميع توزيعات لينكس تقريبًا مع ما يسمى بالتسلسل الهرمي القياسي لنظام الملفات أو FHS، والذي يحدّد الأدلة الرئيسية؛ أغراضها ومحتوياتها في نظام التشغيل. ووفق هذا النظام يشار بالرمز "/" إلى المجلد الأساسي أو جذر النظام، والذي تتفرع منه جميع الملفات والأدلة الأخرى. الدليل "/home/" يحتوى على المجلدات الخاصة بمستخدمي النظام، والتي تضم ملفاتهم وإعدادات برامجهم، فمثلًا يمكنك مشاهدة مجلد يحمل اسم مستخدمك الحالي ضمنه، أما المستخدم الجذر فله دليل آخر وهو "/root/". بشكل عام غالبًا ما يمكنك الاعتماد على بديهتك في فهم أغراض الأدلة الرئيسيّة، فحالما تجد الدليل boot ستتوقع أنه مخصّص لملفات الإقلاع، والدليل dev متعلّق بالأجهزة، وهكذا.. ندعوك لمراجعة مقالة كيف تفهم هيكلية نظام الملفات في لنكس على أكاديمية حسوب. الأذوناتيُعتبر لينكس نظام متعدّد المستخدمين بشكل حقيقي، إذ يتيح إمكانية تحديد أيّ الملفات يمكن للآخرين مشاهدتها أو التعديل عليها وأيّها تُحفظ بحيث يتمكن مالكها فقط من التعامل معها. تُسمّى القواعد التي تُنظّم وتدير هذه الإمكانية بالأذونات أو الصلاحيات Permissions. وعلى غرار يونكس، يقسّم لينكس المستخدمين إلى ثلاث فئات؛ المالك، المجموعة المالكة، والآخرين، كما يقسّم الصلاحيات إلى ثلاثة أنواع؛ القراءة، الكتابة، والتنفيذ. للمزيد حول موضوع الأذونات يمكنكم قراءة مقالنا السابق عنها من هنا. تعلّم ذاتيًالم نقدّم في درسنا هذا سوى بعض المفردات الأساسيّة في التعامل مع بيئة أنظمة لينكس، إلا أنك بالتأكيد تحتاج إلى ما هو أبعد من ذلك لتممكن من فهم واستخدام لينكس بشكل مثالي. يمكنك قراءة المزيد حول كيفيّة إنجاز مختلف المهام في لينكس ضمن الأكاديميّة هنا، كما يمكنك استخدام محركات البحث لاستطلاع المزيد وإيجاد حلول لمشكلاتك، تذكّر أنّ السؤال الذي يدور ببالك قد سأله آخرون من قبل وتمّت إجابتهم بشكل شافٍ، لذا ابحث أولًا ودومًا عن كل ما يعترض طريقك، كُن فضوليًا حيال ذلك. يأتي لينكس أيضًا مع مجموعة ضخمة من الدلائل التعليميّة المتعلّقة بكافة الأوامر التي يمكن استخدامها ضمن الطرفية، للقراءة حول أي أمر استخدم التعليمة التالية: man <command> فعلى سبيل المثال للقراءة حول الأمر rm نكتب: man rm حيث يعرض لنا دليل مفصّل يشمل الغرض من الأمر، الخيارات المتاحة له، أمثلة عن الاستخدام، والمزيد من المعلومات القيّمة. البحث عن المعلومات مهارة أساسية في عصرنا اليوم، وهي ستخدمك كثيرًا بتعزيز مهاراتك وإمكانياتك المهنيّة في التعامل مع نظام التشغيل لينكس، طالما تحلّيت بالصبر والفضول.
-
- 3
-
- نظام الملفات
- جنو
- (و 6 أكثر)