لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 03/08/23 في كل الموقع
-
في بداية كل تطبيق أو موقع إلكتروني تظهر إشكالية متكررة دومًا بغض النظر عن المشروع وهي نوع التكنولوجيا المناسبة لبناء الموقع (سواء لغة البرمجة أو إطار العمل) لأن الاختيار المناسب سيلعبُ دورًا مهمًا في نجاح المشروع فإذا اتُخذ قرار خاطئ فيمكن أن يفشل كل شيء في بداية المشروع أو في مراحل متقدمة منه، ولذلك يكون اختيار التكنولوجيا مهمة شاقة للشركات الصغيرة والناشئة التي تعمل عادةً بخبرات وموارد مالية محدودة، وكلما كانت الشركة أصغر كان تأثير القرار السيئ أكثر مأساوية لموارد الشركة. يتضمن أي موقع إلكتروني جانبين أساسيين وهما جانب العميل Front-end وهو الجانب المرئي من الموقع ويتضمن شيفرة برمجية من اللغة الهيكلية HTML و CSS لتنسيق الصفحات والعرض ولغة جافاسكربت، وجانب الخادم Back-end وهو غير مرئي للمستخدمين ويتضمن لغة برمجية لبرمجة منطلق الموقع وقاعدة بيانات لاستيراد البيانات وخادم وهو حاسوب لتشغيل الموقع أو التطبيق. تشغّل مواقع الويب عبر الكثير من لغات البرمجة ومن بينها Node.js و PHP وهما من أكثر التقنيات المستخدمة من جانب الخادم، ويمكن لكليهما تشغيل تطبيقات الويب بغض النظر عن تعقيد المشروع، وفي الوقت نفسه فإن الاختلافات بينها كبيرة لأن كل واحدة منها مبنية على مفاهيم وبنيات مختلفة. لنستكشف معًا من الأقوى في هذه المعركة المحتدمة بين لغة PHP مقابل Node.js. سنفترض في هذا المقال بأن لديك معرفة أساسية بتقنيات تطوير الويب وكيفية عمل المواقع. نبذة موجزة عن لغة PHP و Node.js قبل الغوص في التفاصيل وذكر الميزات والعيوب والمقارنة بينها لا بدّ لنا من التوقف قليلًا والتأمل في نقطة مهمة عند المقارنة بين PHP و Node.js إذ أنه لا يخفى على الجميع بأن PHP هي لغة برمجة ولكن ما هي Node.js هل هي لغة؟ أم مكتبة؟ أم إطار عمل؟ أم ماذا؟ في الحقيقة جميع تخميناتنا خاطئة لأن Node.js ما هي إلا بيئة تشغيل تسمح بتشغيل الشيفرة البرمجية للغة جافاسكربت، ومع ذلك بعض المبتدئين يسمونها لغة Node.js، وعمومًا يمكننا النظر إلى هذه المقارنة على أنها مقارنة بين مزايا لغة جافاسكربت ولغة PHP ولكن بطريقة غير مباشرة. ما هي Node.js تعتمد بيئة تشغيل جافاسكربت Node.js بصورة أساسية على محرك Chrome V8، وهو محرك جافاسكربت و WebAssembly عالي الأداء ومفتوح المصدر طورته شركة غوغل (اسمها حاليًا ألفابت)، والشيفرة البرمجية لهذا المحرك مكتوبٌ بلغة C++، ويُستخدم لتشغيل لغة جافاسكربت على متصفح الإنترنت كروم Chrome. توفر بيئة Node.js تطبيقات ذات أداء واستقرار عاليين. كما أنها تتيح إمكانية إنشاء خوادم قابلة للتطوير دون استخدام الخيوط Thread، باستخدام نموذج مبسط من البرمجة القائمة على الأحداث Event-driven Programming، والتي تستخدم عمليات رد النداء callback للإشارة إلى اكتمال المهمة، كما تبسط بيئة Node.js عملية التطوير لآلاف المبرمجين إذ jمكّنهم من إنشاء موقع أو تطبيق ويب من خلال لغة جافاسكربت سواء من جانب الخادم أو العميل. تسمح بيئة Node.js للمطورين بناء تطبيقات بسرعة بفضل مشاركة اللغة بين الواجهات الأمامية والخلفية الأمر الذي يزيد من الكفاءة والإنتاجية للمطورين. كما يساعد هذا المزيج على بناء تطبيق قوي ومكتمل الميزات بأقل استثمار من وقت وجهد، بالإضافة إلى ذلك تنخفض تكاليف الصيانة وتزداد سهولة اكتشاف الأخطاء والقدرة على استخدام لغة TypeScript مع التي تتيح المزيد من القوة وقابلية الاستخدام للشيفرة البرمجية. كما أن لغة جافاسكربت هي الأساس للعديد من أطر العمل للواجهات الأمامية الشائعة مثل React أو Vue وهذه الأطر أساسية لمعظم تطبيقات الويب الحديثة. تتيح أيضًا بيئة Node.js بناء تطبيقات بالزمن الحقيقي Real-time بفضل تجربة تدفق البيانات في الوقت الفعلي باستخدام لغة جافاسكربت المقادة بالأحداث، إذ يمكنك بسهولة إنشاء حلول برمجية عالية الأداء مع ميزات متقدمة مثل الدردشات وخدمات البث الحي للفيديوهات أو الصوت والمعاملات وما إلى ذلك. في الحقيقة هذه المرونة العالية للتغييرات وقابلية التوسع جعلت بيئة Node.js قوية في سوق تطبيقات الويب ذات الطبيعة السريعة والمتقلبة لأن الوجود في الأسواق يفرض على الشركات تظل مرنًة وأن تكون قادرةً على تغيير تطبيقاتها لتلبية متطلبات العملاء المتغيرة وزيادة إمكانية الوصول إلى سقف توقعات المستخدمين. كما أن لغة جافاسكربت تعدّ من اللغات الأساسية في تطوير الويب ولذلك فإن المبرمجين سيتعلمونها حتمًا خلال رحلتهم في تطوير الويب، وسيصبح من الأسهل عليهم اختيار بيئة Node.js للواجهة الخلفية بدلًا من تعلم لغة PHP مما يسرع رحلة التعلم للمبتدئين. ولكن من عيوب بيئة Node.js أيضًا النقص في الأدوات والأطر المعقدة لبناء مشاريع الكبيرة كما أن السرعة الكبيرة في تطوير بنية اللغة جعلها في تغيّر مستمر وهذا الأمر يمكن أن يؤخذ بمنحى إيجابي أو سلبي بحسب كل شركة، بالإضافة إلى ذلك تقدم Node.js أداءً ضعيفًا عند إجراء عمليات حسابية مكثفة أو الاستخدام العالي لوحدة المعالجة المركزية. كما أن بنية Node.js المقادة بالأحداث جعل عليها بعضًا من القيود، ولكن بعد الإصدار 10.5 أضيفت وِحدة برمجية للتعامل مع الخيوط Threads في بيئة Node.js هذه الوحدة مفيدة جدًا في إجراء عمليات جافاسكربت كثيفة الاستخدام لوحدة المعالجة المركزية. لغة PHP لغة PHP وهي اختصار لعبارة Hypertext Preprocessor أنشأها راسموس ليردورف Rasmus Lerdorf في عام 1994. وهي لغة برمجة نصية مفتوحة المصدر من جانب الخادم مصممة خصيصًا لتطوير تطبيقات ومواقع الويب، كما أنها تستخدم أيضًا كلغة برمجة نصية للأغراض العامة، وتكون ملفات PHP لها امتداد .php ويمكن أن تحتوي على شيفرة جافاسكربت و HTML و CSS وحتى نصوص عادية أيضًا. وتعد لغة PHP واحدة من أفضل لغات الخادم في العالم. أظهر استطلاع أجراه موقع W3Tech جاء فيه أن 78.1% من مواقع الويب في العالم تستخدم لغة PHP للواجهات الخلفية بالمقارنة مع 1.8٪ من المواقع التي تستخدم جافاسكربت وبيئة Node.js. تحتوي لغة PHP أيضًا على دعم كبير لأطر العمل مثل Laravel و Symfony و Codeigniter و CakePHP، وجميع هذه الأطر مفتوحة المصدر ويمكن لأي شخص استخدامها أو تعديلها وتطويرها. كما أن لغة PHP بحد ذاتها قابلة جدًا للتخصيص وبمجرد أن يزدهر تطبيق الويب ويتوسع ستجد أن اللغة تلبي جميع احتياجاتك والتغييرات التي تتطلع لها. يعد الحصول على درجة عالية من التخصيص في تحسين وظائف موقع الويب الخاص بك ميزة تنافسية كبيرة وهذه الميزة توفرها لغة PHP لأنها تحتوي على جميع الوظائف اللازمة للعمل مع HTML والخوادم وقواعد البيانات، كما تتميز اللغة بمستوى عال من الأمان والمرونة وخصيصًا في النسخ الحديثة منها ومع مشاهدتنا لشركات تخسر مبالغ كبيرة من المال بسبب هجمات القراصنة، تزداد الحاجة لحلول مستقرة وقوية بل لإجراءات وقائية أيضًا وهذا ما توفره لغة PHP. تعد شيفرتها البرمجية آمنة نسبيًا وذات كما توفر أدوات لحماية البيانات المرسلة إلى قواعد البيانات. بالإضافة إلى ذلك، تشتهر لغة PHP بمرونتها وتوافقها عبر أنظمة التشغيل الأساسية مثل ويندوز ولينكس Linux وماك MacOS وما إلى ذلك. علاوة على ذلك تمنحك لغة PHP توافق مع مجموعة واسعة من الخوادم مثل Apache و iPlanet و Netscape وما إلى ذلك، بالإضافة إلى التكامل مع قواعد البيانات مثل MongoDB و MySQL وغيرها. ولكن كما أن لها مزايا لها عيوب أيضًا فمثلًا تكون عملية كتابة وحدات الاختبار البرمجي Unit Testing طويلة نسبيًا بسبب سوء معالجتها للأخطاء كما أن بعض المبرمجين ينظرون إلى أن نموذج خادم العميل الذي تتبعه لغة PHP عفا عليه الزمن لأن طريقة عمله التي تطلبُ الصفحة أولًا ومن ثم الاتصال بقاعدة البيانات وتعالج البيانات وتعرض النتائج في صفحة HTML. الأمر الذي يؤدي خسائر في السرعة والفعالية، ولكن من الجدير بالذكر أنه يمكن التغلب على عيب PHP بمساعدة Memcached هو نظام ذاكرة تخزين مؤقت موزع للأغراض العامة، ويستخدم لتسريع مواقع الويب الديناميكية التي تعتمد على قواعد البيانات عن طريق تخزين البيانات والكائنات في ذاكرة الوصول العشوائي مؤقتًا لتقليل عدد المرات التي يتطلب فيها الموقع قراءة البيانات من مصادر خارجية مثل قواعد البيانات، وبالرغم من ذلك هذا الأمر سيخلق تبعية إضافية لتطبيق الويب وهذه مشكلة أيضًا. دورة تطوير تطبيقات الويب باستخدام لغة PHP احترف تطوير النظم الخلفية وتطبيقات الويب من الألف إلى الياء دون الحاجة لخبرة برمجية مسبقة اشترك الآن مقارنة بين PHP vs NodeJS والآن بعد أن تعرفنا على كل لغة لنتعمق أكثر في فهم الاختلافات الدقيقة ولنستطيع بعدها تحديد ما هو مناسب لكل مشروع. المجتمع والتطوير تحدد قوة المجتمع وخبرته نوع التحديثات التي تأتي إلى مختلف الأطر والمكتبات والمشاريع التي ستطلق في لغة معينة، كما أن المجتمع الكبير يعني الدعم الكبير لأنه في بداية طريقك لتعلم البرمجة لا يمكنك الاعتماد على معرفتك فقط دون دراسة أي دورات وممارسات حديثة، ولتصبح محترفًا شاملًا ستحتاج حتمًا لطرح أسئلة على منتديات أجنبية مثل StackOverflow أو منتديات عربية مثل الأسئلة والأجوبة في موقع أكاديمية حسوب، كما أنه من مسلمات العمل في وقتنا الحالي أن فريقك لن يكون قادرًا على كتابة الشيفرة البرمجية لكل ميزة من الصفر، ولذلك فإنه سيستخدم حتمًا المكتبات الشعبية والمُختبرة الأمر الذي يقلل من وقت التطوير ويزيد من الإنتاجية، ويزيد من جودة المشروع الفردي أو المكتبة أو إطار العمل. تفهرس معظم مكتبات Node.js في سجل موقع npmjs.com، وبالرغم من أن بيئة Node.js جديدة نسبيًا إلا أن مجتمعها كبير ولديها العديد من المشاريع التي طورها المجتمع والتي تميل نحو الاحتياجات العصرية والحديثة لتطبيقات الويب. في الواقع تركز العديد من المشاريع على إضافة وظائف فريدة إلى بيئة Node.js بدلًا من مجرد استنساخ ونقل ميزات من لغات أخرى. بالرغم من قدم وعراقة لغة PHP إلا أنها ليست مرغوبة مثل لغة جافاسكربت وبالرغم من مجتمعها الكبير ومشاريعها المتنوعة، ولكن إحدى مشكلاتها الرئيسية أن مشاريعها الحديثة التي يطورها المجتمع تبدو قديمة بعض الشيء وغير مثيرة للاهتمام عند مقارنتها مع مشاريع Node.js، ومع أن مجتمع مبرمجي لغة PHP برمجوا بعض المميزات وأضافوها إلى ميزات اللغة الأساسية الموجودة بالفعل في لغات برمجية أخرى لكن يشعر بعض المطورين بالحاجة إلى مشاريع أكثر حداثة تتناسب مع متطلبات المستخدمين في العصر الحالي. أما من ناحية عدد المطورين فوفقًا لاستطلاع أجراه موقع Slashdata في عام 2020 جاء فيه أنه يوجد أكثر 12.4 مليون مطور للغة جافاسكربت (اللغة الأساسية لبيئة Node.js) حول العالم بالمقابل 6 ملايين مطور للغة PHP. مما يظهر تفوق واضح للغة جافاسكربت ويجعلها خيارًا جيدًا للشركات الناشئة لأن هنالك عدد كبير من المرشحين لوظيفة مطور لغة جافاسكربت. الشيفرة البرمجية إذا كانت الشيفرة البرمجية سهلة ومصممة بطريقة جيدة ستتمكن من إنجاز الكثير باستخدام شيفرة برمجية أقل. تتطلب بيئة Node.js المزيد من أسطر الشيفرات البرمجية لتنفيذ نفس وظائف PHP لأن بنية اللغة مختلفة وهذا يظهر أثناء البرمجة والسبب هو كون البيئة تطورت بأكملها باستخدام جافاسكربت. لذلك تتطلب Node.js أحيانًا سطورًا أطول نسبيًا لكن لا ننسَ أيضًا إمكانية العمل بلغة واحدة للواجهات الأمامية والخلفية. بالإضافة إلى ذلك تمكننا بيئة Node.js استيراد كل منطق الشيفرة البرمجية للواجهة الخلفية الأمر الذي يجعل من السهل بعد ذلك الوصول إلى الميزات التي خصصت على كلا الجانبين. كما تنقلُ بيئة Node.js الكثير من عبء العمل إلى جانب العميل. لذلك إذا كان لدى جمهورك المستهدف هواتف ذكية ذات قوة معالجة جيدة فإن Node.js مثالية لهذه الحالة. بالمقابل صممت لغة PHP لبناء ومعالجة صفحات الويب وجعلها ديناميكية كما تعتمد لغة PHP على شيفرة HTML لجعل كل الصفحات ثابتة في طرف المخدم بعد توليدها وتجهيزها ثم إرسالها إلى متصفح المستخدم أي لن يكون هنالك أي عمليات برمجية تُنفذ في طرف العميل (المتصفح غالبًا)، وبناءً على ذلك فإن تحميل صفحات الويب ستكون أخف على أجهزة المستخدمين ولن تحتاج لقوة معالجة أجهزتهم. كما أن اللغة تتطلب سطورًا أقل من التعليمات البرمجية لأداء وظيفة ما وبالتالي فهي أسهل، وعمومًا من السهولة فهم الشيفرة البرمجية سواء للغة PHP أو Node.js ولن يستغرق المطور المبتدئ وقتًا كبيرًا لإتقان أيًا من اللغتين. السرعة والأداء نقصد بالسرعة بأنها سرعة تنفيذ الشيفرة البرمجية بحسب كل لغة والسرعة العالية تؤدي لعملية تطوير أسرع ومشاريع أكثر فعالية من حيث التكلفة. تتنوع اللغات البرمجية في طريقة تنفيذها للشيفرة البرمجية فبعضها تكون متزامنة وأخرى غير متزامنة. تنفذُ اللغات البرمجية المتزامنة التعليمات سطرًا سطرًا ولا يُنفذ السطر التالي من التعليمات البرمجية حتى تنفذُ السطر الحالي. أما اللغات البرمجية غير المتزامنة تنفذُ جميع التعليمات البرمجية في نفس الوقت هذا الاختلاف في طريقة التنفيذ يؤثر تأثيرًا كبيرًا على سرعة كل لغة، ونقصد بالأداء كيفية تنفيذ التعليمات البرمجية بلغة PHP أو Node.js وأدائها على مؤشرات الأداء الرئيسية مثل تحميل الصفحات والسلاسة. واللغة عالية الأداء تؤدي لنتائج أفضل لأداء تطبيق الويب والتي تؤثر تأثيرًا عميقًا على تجربة المستخدم. تعد بيئة Node.js من بيئات التطوير غير المتزامنة، وهذه الميزة الرئيسية لها وكونها غير متزامنة يعني أنها تعمل على تنفيذ الشفرة بأكملها دفعة واحدة ولا تنتظر عودة نتيجة دالة أو تابع معين. تقلل هذه الطريقة التأخر في تنفيذ الشيفرة البرمجية لتطبيق الويب بصورة كبيرة وتوفر تجربة استخدام سلسة (في بعض الأحيان يجب أن تكون قدرة الحوسبة والمعالجة لجهاز المستخدم مقبولة للحصول على تجربة استخدام سلسلة). بالرغم من أن لغة PHP متزامنة ولكن هناك بعض واجهات برمجة التطبيقات API تعمل بصورة غير متزامنة. هذا ما يجعل استجابة الموقع أبطأ وانتظار المستخدم في نهاية المطاف. في الحقيقة هذه المشكلة موجودة في معظم اللغات والتقنيات القديمة. والخوف الدائم في هكذا نوع من اللغات يكمن في تعطل البرنامج في انتظار الرد والذي يسمى "جحيم رد الاتصال Callback Hell" فإذا كانت هناك حاجة إلى ربط الكثير من الدوال ببعضها بعضًا ويتطلب التطبيق نقل البيانات من دالّة إلى أخرى فيجب الحذر عندها من الوقوع في هذه المشكلة. أطر العمل تساعدُ أطر العمل Framework المبرمج على التركيز على التفاصيل الدقيقة للمشروع وتزيح عن كاهله كتابة الشيفرات البرمجية المكررة والأكثر استخدامًا موفرةً الدوال الأساسية والمكتبات وواجهات برمجة التطبيقات من خلال إطار العمل. كلما كان إطار العمل أكثر شمولًا قل مقدار الشيفرة البرمجية الزائدة التي سيحتاجُ المبرمج لكتابتها. شهدت Node.js توسعًا كبيرًا في أطر العمل الخاصة بها في فترة قصيرة نسبيًا ومن بعض أطر العمل المشهورة نذكر Meteor و Total و Express و Sails وغيرها. بالرغم من حداثة هذه الأطر إلا أنها واعدة ومتطورة باستمرار وبالتأكيد تعزز الإنتاجية وتُقلل وقت التطوير واستهلاك الموارد ولكن أطر عمل لغة PHP تفوقها عددًا بهامش ضخم نظرًا لأقدمية لغة PHP وعمرها الذي يزيد عن 27 عامًا فهي تمتلك أطر عمل غنية جدًا وعادة ما تركز شركات تطوير تطبيقات الويب الحديثة على استخدام واعتماد على هذه الأطر في عملها ومشاريعها أي أنها أصبحت من مُسلمات تطوير البرمجيات في الوقت الحالي ومن بعض أطر العمل المشهورة نذكر Laravel و CodeIgniter و CakePHP و Phalcon. بالرغم من الفرق الكمي بين أطر عمل لغة PHP و Node.js إلا أنه يصعب تحديد أي إطار يعمل بطريقة أفضل من الآخر في اللغتين. وتجدر الإشارة إلى العديد من أطر PHP صممت لاستيراد ميزات مثل التنفيذ غير المتزامن المتأصلة في بيئة Node.js. بالإضافة إلى ذلك، فإن العديد من أطر PHP لديها مشكلة واحدة مشتركة محتوى وشيفرة برمجية مختلطة ولكنها بالمقابل أطر عمل شاملة. التعامل مع قواعد البيانات الأمر المهم عند النظر لأي لغة سواء جديدة أو قديمة هي طريقة فحص مدى ملاءمتها مع قواعد البيانات الحديثة أو القديمة والعلائقية منها أو التقليدية. اشتهرت قواعد البيانات العلائقية والتي تُخزن البيانات على شكل جداول؛ الأمر الذي يسهل فهم العلاقات والتبعيات بين نقاط البيانات المختلفة. ولكن في السنوات السابقة ظهرت نوع جديد من قواعد البيانات وهي NoSQL والتي تسمح بتخزين البيانات بتنسيقات مثل المستندات وأزواج المفاتيح والرسوم البيانية وحتى قواعد البيانات غير المهيكلة وشبه المهيكلة والمنظمة، بالإضافة إلى أنها سهلة الاستخدام للمطورين. يمكن لبيئة Node.js العمل بسهولة مع قواعد بيانات المختلفة مثل NoSQL و MongoDB و CouchDB وغيرها كما أن لديها مكتبات كبيرة للوصول إلى قواعد بيانات SQL. نظرًا لقدم لغة PHP فهي مصممة للعمل مع قواعد البيانات العلائقية والتقليدية مثل MySQL و MariaDB بقوة في حين أنه من الممكن استيراد مكتبات للعمل مع قواعد بيانات NoSQL ولكن عملية التكامل مع هذه المكتبات طويلة وتستهلك جزءًا كبيرًا من وقت المعالجة. معالجة الطلبات هذا هو مقياس مدى سرعة معالجة اللغة للطلبات من جانب العميل. لا شك أن تنفيذ الطلب بدقة أمر بالغ الأهمية لتجربة المستخدم، ولكن يجب أيضًا القيام به باستخدام الحد الأدنى من الموارد والوقت. كما يساعدنا التعامل اللغة مع الأخطاء على فهم الصورة الشمولية وذلك لتحسين تجربة المستخدم. بفضل المعالجة غير المتزامنة للطلبات المتعددة، لا تنتظر بيئة Node.js انتهاء إحدى الأحداث قبل أن تبدأ العملية التالية. لا تضيع أوقات وحدة المعالجة المركزية وذاكرة الوصول العشوائي في انتظار مجهول لمعالجة مخرجات دالة معينة، والمشكلة الوحيدة هو أنه إذا لم يُعالج حدث مرتبط بأحد الأحداث التالية في الوقت المناسب، فيمكن يتداخل سير عمل التطبيق ويؤدي ذلك لحدوث خطأ في عموم التطبيق، ولكن لحسن الحظ توفر اللغة آليات معالجة الأخطاء فعالة تمكن المبرمج من حماية النظام من التعثر الناتج عن التنفيذ الخاطئ. تتعامل لغة PHP مع طلب واحد وبالتسلسل وهذا الأمر يزيد من مدة استهلاك الموارد سواء وحدة المعالجة المركزية أو ذاكرة الوصول العشوائي في الواجهات الخلفية، ويخلق تأخرًا في النظام من خلال نهج الطلب الواحد، ولكن نظرًا لأن المعالجة تكون من جانب المخدم لن يتأثر تطبيق الويب بنوعية جاهز المستخدم فيمكن أن يعمل على الأجهزة الضعيفة أو القوية (لأن بعض تطبيقات Node.js تحتاج لمعالجة قوية) كما يمكن استخدام مكتبات خارجية للحصول على الوظائف غير المتزامنة. ولكن لن تكون بقوة الميزات الأصلية في بيئة Node.js. التعامل مع الوحدات Modules تعمل الوِحدات كتطبيقات فرعية داخل تطبيق الويب الأساسي، وهي تعالج مجموعة معينة من الوظائف وغالبًا ما تكون قابلة للتبديل أو التحديث مما يمنح البرنامج مرونة وقوة في العمل. غالبًا ما يشتكي بعض المطورين من أن مشاريع Node.js ليست مستقرة مثل المشاريع المطوّرة بلغة PHP نظرًا لأن اللغة والمجتمع لا يزالان ينموان ويتطوران بسرعة كبيرة فإن أنظمة مراقبة الجودة بالكاد موجودة. مع تقديم بعض الحلول الواعدة مثل مبادرة مراقبة الحزم والوِحدات npm-Audit الأمر الذي ساعد في التحقق من كل حزمة بحثًا عن تعليمات برمجية ضارة. بالمقابل تتمتع لغة PHP بميزة في هذا المجال منذ سنوات حتى الآن. في وقتنا الحالي تحتوي لغة PHP على مكتبة ثرية من الوِحدات النمطية وهي مستقرة نوعًا ما، ومع ذلك لا تزال Node.js تخطو خطوات كبيرة في هذا المجال. النظام البيئي Ecosystem النظام البيئي هو عدد المكتبات مفتوحة المصدر وواجهات برمجة التطبيقات والوحدات النمطية وأطر العمل والمشاريع التي ينشرها المجتمع والمطورون …إلخ. فيحتوي النظام البيئي Node.js على مجموعة واسعة من المكتبات وأطر العمل، لكنها متخلفة عن أرقام PHP. بالرغم من ذلك إلا أنها تعوضها بمشاريعها المتنوعة. نظرًا لأن Node.js تستخدم نفس اللغة للبرمجة من جانب الخادم والخلفية، فإن أنواع المشاريع المتاحة تتناسب بحرية مع عدد أكبر من حالات الاستخدام. بالمقابل يوجد العديد من الأنظمة المعتمدة على لغة PHP وهذه الأنظمة لها سيطرة كبيرة على مواقع الويب حول العالم مثل ووردبريس WordPress وجوملا وماجنتو وغيرها الأمر الذي انعكس على قوة النظام البيئي. وبما أن نسبة كبيرة من إجمالي مواقع الويب على الإنترنت تعمل بهذه اللغة فحتمًا سيكون هنالك مجتمع كبير والكثير من من المواد التدريبية والتكنولوجيا الداعمة على مر السنين لجذب مطورين جدد. أيهما أفضل PHP أم Node.js؟ بمجرد أن تفهم لغة جافاسكربت ستصبح اللغات الأخرى غير فعالة بالمقارنة معها لأنك تعلمت لغة واحدة وركزت كل مجهودك عليها فستكون النتائج أسرع وسيتعمقُ فهمك لكيفية سير العمل. يمكن لمطوري الويب الشاملين full stack web developers كتابة شيفرة مشروع كامل من جانب العميل والخادم بلغة جافاسكربت ولم تعد هنالك حاجة إلى التبديل بين اللغات أو التقنيات. كلما تعلمت لغة جافاسكربت زادت استمتاعك بها، وهذا الأمر لا ينطبق على لغة PHP. من الأفضل اختيار بيئة Node.js عند إنشاء تطبيقات ديناميكية أحادية الصفحة SPA أو Single Page Application باستخدام إطارات جافاسكربت للواجهة الأمامية مثل Angular أو React أو Vue.js. أما من جهة الخادم Node.js. يمكن لبيئة Node.js دعم أجهزة إنترنت الأشياء IoT بمفردها مثل أجهزة تتبع اللياقة البدنية والطائرات بدون طيار وحتى الروبوتات بالإضافة إلى منصات تدفق البيانات الثقيلة كونها قادرة على إدارة العديد من العمليات المتزامنة. بعض التوجهات في المشاريع في السوق تعتمد على مطوري MERN وهي اختصارًا (Node.js و React و Express.js و MongoDB) وبعض المشاريع تستخدم إطار Angular بدلًا من إطار React فتصبح MEAN ويمكن استعمال Vue.js ليصبح الاختصار MEVN. بالمقابل تعدُ لغة PHP اختيارًا جيدًا لمدونة أو مشروع تجارة إلكترونية وخصيصًا عندما يتطلب المشروع العديد من عمليات الدمج. الخاتمة تعرفنا في هذا المقال على الفرق بين لغة PHP وبيئة Node.js لتشغيل شيفرات جافاسكربت في الواجهة الخلفية للمواقع وتطبيقات الويب، وتعرفنا في البداية على نبذة مختصرة لكل منها وتعمقنا لاحقًا في المقارنة وفي إقبال المجتمع التقني عليها وحماسه لتطويرها ومدى تعقيد الشيفرة البرمجية وسرعة وأداء كل لغة كما اطلعنا على أطر العمل الخاصة بكل لغة وطريقة تعامل كل لغة مع قواعد البيانات وكيفية معالجة الطلبات وطريقة التعامل مع الوِحدات وختمنا المقارنة بالاطلاع على النظام البيئي الشامل لكل منها. ولنتذكر دومًا بأن كل من لغة PHP وبيئة Node.js تستمد قيمتها من حالة الاستخدام والمشروع الذي نعمل عليه فإذا كان المشروع موقع ويب ثابت يتطلب عددًا قليلًا من الطلبات من قاعدة البيانات، وكان جمهور التطبيق المستهدف يستخدم أجهزة منخفضة وبطيئة فستكون لغة PHP هي بالضبط ما تبحث عنه. وإذا كانت حالة الاستخدام الخاصة بك تتضمن مواقع ويب ديناميكية ترسل العديد الطلبات إلى خادم ولها واجهة مستخدم ديناميكية فأنت تريد استخدام Node.js. وختامًا تبرز أهمية اختيار اللغة المناسبة لإنشاء موقع أو تطبيق مستقر وموثوق في مشاريع الناشئة، وهذا هو السبب في لجوء بعض الشركات إلى استشارة المختصين في هذه الأمور للتأكد من تلبية جميع احتياجات المشروع المستقبلية ولا ننسَ بأنه مهما اختلفت اللغة تبقى مهارات فريق التطوير الويب هي الحكم في هذه النقطة. يمكنك الإطلاع على توثيق لغة PHP وتوثيق بيئة Node.js على موسوعة حسوب لمزيد من التفصيل حولهما. المصادر مقال Node.js vs PHP: In-depth Comparison With Pros & Cons [2021] لكاتبه Serhii Osadchuk. مقال Node.js vs PHP: Which One is Better for Backend Development لكاتبته Anastasia Kushnir. مقال Node.js vs PHP: A Honest Comparative Study With All The Answers لكاتبه Tejas Kaneriya. مقال PHP vs. Node.js - GeeksforGeeks لكاتبه Parikshit Hooda. اقرأ أيضًا الدليل السريع إلى لغة البرمجة PHP مقدمة إلى Node.js1 نقطة
-
index.htmlstyle.css هذا يومي الخامس في css هل هذا المشروع جيد وهل استخدامي لbox-shadw حسن ام خرب التصميم1 نقطة
-
اريد العمل مع صديق لي علي مشروع بحيث استطيع التعديل انا و هو علي نفس المشروع عن بعد و كل شخص منا يعمل علي حاسوبه الشخصي كيف يمكنني ذلك ؟1 نقطة
-
1 نقطة
-
في ملف UserProvider يجب عليك كتابة children بحرف صغير وليس Children وإذا كنت تستخدم react 17 أو أقل فقم باستيراد react import React, { createContext } from "react";1 نقطة
-
1 نقطة
-
ازاى اعمل قائمة فى الاكسيل اول اما اختار حاجة من القايمة تظهر داتا انا حاططها فى جدول تانى1 نقطة
-
السؤال غير واضح، هل تقصد تريد إضافة لفعل ذلك، أم تريد برمجة خاصة باستخدام الوورد بريس؟ إذا كان الأمر يتعلق بإضافات ووردبريس، يمكنك استخدام إضافات تساعدك في إنشاء نموذج طلب وتحديد الخيارات المختلفة للتوصيل والمناطق المراد الإرسال لها، ثم حساب التكلفة بناءً على الخيارات المحددة. من الإضافات التي يمكن استخدامها لهذا الغرض: WPForms: إضافة تسمح بإنشاء نماذج تفاعلية بسهولة وإضافة خيارات متعددة، وتحديد السعر بناءً على المنطقة وطريقة التوصيل المحددة. WooCommerce: إضافة تستخدم بشكل رئيسي لإنشاء متاجر إلكترونية ولكنها تتضمن أيضًا خيارات لإنشاء نماذج الطلبات، وتحديد الطرق المختلفة للتوصيل وتحديد الأسعار بناءً على المنطقة والطريقة المختارة. إما إذا كنت تريد التصميم والبرمجة بنفسك: بخصوص التصميم فيمكنك استخدام مكتبات جاهزة مثل Bootstrap لإنشاء الـ Form و قائمة التنقل. أما بخصوص التوصيل والسعر، فيمكنك استخدام الكود التالي كمثال: //تحديد سعر الشحن حسب المنطقة function calculate_shipping_cost($shipping_method, $shipping_address){ $shipping_cost = 0; $city = $shipping_address['city']; $state = $shipping_address['state']; if ($shipping_method == 'method1') { if ($city == 'City1' && $state == 'State1') { $shipping_cost = 10; } elseif ($city == 'City2' && $state == 'State1') { $shipping_cost = 15; } elseif ($city == 'City3' && $state == 'State2') { $shipping_cost = 20; } } elseif ($shipping_method == 'method2') { if ($city == 'City1' && $state == 'State1') { $shipping_cost = 20; } elseif ($city == 'City2' && $state == 'State1') { $shipping_cost = 25; } elseif ($city == 'City3' && $state == 'State2') { $shipping_cost = 30; } } return $shipping_cost; } في هذا الكود، يتم استخدام دالة calculate_shipping_cost لحساب تكلفة الشحن بناءً على الطريقة المختارة والعنوان الذي تم تقديمه. يتم تحديد سعر الشحن حسب المنطقة، مع تحديد أسعار مختلفة لكل طريقة من طرق الشحن.1 نقطة
-
من الجيد أنك تستخدم المتغيرات vriables في CSS من خلال :root ، لكنك استخدمتها فقط من أجل الخط، عود نفسك على استخدامها فيمكنك كمثال إنشاء متغير للون الرئيسي وكمثال: :root { font-family: Arial, Helvetica, sans-serif; --bg-clr: #eee } .parent { background-color: var(--bg-clr) } حيث يستخدم :root لتعريف الخصائص العامة المتعلقة بالمستند، والتي يمكن الوصول إليها من جميع العناصر في المستند. عند تعريف خصائص في :root، يمكن الاستفادة منها في جميع أنحاء المستند، مما يوفر الوقت والجهد في الكتابة والصيانة. بالإضافة أيضًا إلى ما ذكره أسامة، يمكن تحسين تباعد العناصر في عنصر الـ parent بحيث تبدو العناصر أكثر اتساقًا وتتناسب بشكل أفضل. علاوة على ذلك ، يمكنك تحسين مظهر خطوط الأوسط في العناصر النصية ، مثل الـ or ، لجعلها أكثر وضوحًا. بالنسبة للألوان أنصحك باستخدام https://www.happyhues.co/ فستتعلم منها الكثير بالنسبة لاستخدام ألوان متناسقة ومريحة للعين، وستجد بالموقع لوحات ألوان جاهزة مع شرح كيف يتم استخدام كل لون داخل موقعك.1 نقطة
-
مستواك في تطوير و هذا شئ جيد. لدي تعليق واحد هو يخص الخاصية border-radius يجب أن تضع جميع البدائات حتي تعمل الخاصية في جميع المتصفحات. بدلاً من: border-radius: 50%; قم بوضعها هكذا. -webkit-border-radius: 50%; -moz-border-radius: 50%; -ms-border-radius: 50%; -o-border-radius: 50%;1 نقطة
-
كنت اريد فقط تحديد الحصه الحالية كمقروء ولم اكن اعلم انه سوف يحدد الموقع كامل كمقروء فهل يمكن التراجع عن هذا الامر1 نقطة
-
للأسف لا يمكن التراجع عن هذا الأمر حيث تظهر لك رسالة تأكيدية بأنك تريد جعل الموقع بالكامل كمقروء من أجل تنبيهك قبل التأكيد. ومن خلال تبويب الأنشطة الخاصة بي والذي يمكنك رؤيته عند الإشارة بالماوس على كلمة الرئيسية، من متابعة ما تريده أو رؤية كافة الأنشطة الخاصة بك. أيضًا من خانة البحث يمكنك تخصيص البحث داخل أي قسم تريده بالموقع أو يمكنك البحث في كامل الموقع، وإذا أردت شيء معين ولم تجده استخدم جوجل مثال، كيفية تعلم البرمجة وبجانبها كلمة حسوب، وستظهر لك كافة النتائج على موقع حسوب.1 نقطة
-
لا يمكن التراجع عن تحديد الموقع كمقروء ، ولكن لا تقلق يمكنك الإطلاع على كامل الدروس كما هي ولا يوجد إختلاف ، كما أن المحتوى الجديد في الأكاديمية سوف يظهر لك كمحتوى غير مقروء ، مثل الأسئلة التي ترفق في قسم أسئلة وأجوبة أو المقالات الجديدة ، ويمكنك متابعة المحتوى الغير مقروء من هنا .1 نقطة
-
يبدو أنك تقوم بتطبيق بعض التمارين المهمة باستخدام CSS ، وبعد إطلاعي على المشروع الخاص بك يبدو أنك قمت بتنفيذ التمرين بشكل جيد بحيث لا يظهر أخطاء ، لكن بالفعل إستخدامك للخاصية box-shadw قد أظهر التصميم بشكل غير جميل ، كما أن الخاصية box-shadw ليست كثيرة الإستخدام في التصميم وفي حال تم استخدامها تكون الألوان المستخدمة درجة من درجات اللون الأسود أو الرمادي وشفافية shadw خفيفة جداً بحيث يظهر بشكل ضئيل ، وهكذا سوف يظهر التصميم بشكل جميل ، لكن لا مشكلة من تعلم الخاصية وكيف يمكن استخدامها في التصميم . أما بخصوص الأكواد البرمجية فهي مرتبة ومفهومة بشكل جيد ويمكن لأي مبرمج فهم الأكواد والتعديل عليها .1 نقطة
-
يمكنك استخدام إضافة خاصة تسمى "Arabic WooCommerce" والتي تم تصميمها خصيصًا لتحويل الأرقام في WooCommerce إلى الأرقام العربية الهندية. يمكنك تثبيت الإضافة من خلال لوحة التحكم الخاصة بـ WooCommerce عن طريق الذهاب إلى "الإضافات" ثم "إضافة جديدة" والبحث عن "Arabic WooCommerce". بعد تثبيت الإضافة، يمكنك تنشيطها وتكوينها وفقًا لاحتياجاتك. ويجب أن يقوم الإضافة بتحويل الأرقام في الأسعار إلى الأرقام العربية الهندية تلقائيًا بعد التكوين الصحيح.1 نقطة
-
بالإضافة إلى ما تم ذكره. يجب التفرقة بين React Native و Ionic عبارة عن إطارات عمل (Frameworks) لتطوير تطبيقات الهاتف. حيث تستخدم React Native لتطوير تطبيقات iOS و Android، في حين تستخدم Ionic لتطوير تطبيقات متعددة المنصات باستخدام HTML و CSS و JavaScript. الفرق الرئيسي بين React Native و Ionic هو أن React Native يستخدم لغة البرمجة JavaScript، في حين يستخدم Ionic HTML و CSS و JavaScript. كما يتطلب React Native مستوى عالٍ من المعرفة بـ JavaScript، بينما يمكن لأي شخص يعرف HTML و CSS و JavaScript استخدام Ionic. React Native مبني على مكتبة ReactJS، ويستخدم تقنيات Native لتحسين أداء التطبيق وتحسين التفاعل مع المستخدم. ويتيح للمطورين إعادة استخدام الشفرة بين تطبيقات iOS و Android، مما يوفر الوقت والجهد في عملية التطوير. كما يتيح للمطورين أيضًا بناء واجهات مستخدم (UI) ذات مظهر جميل ومتطور. Ionic على الجانب الآخر يستخدم مكتبة AngularJS ويتميز بأنه يعمل بشكل ممتاز على مختلف المنصات. ويوفر Ionic أيضًا واجهة مستخدم تفاعلية وتطبيقات بسيطة وخفيفة الوزن. متى استخدم React Native و Ionic فيما يتعلق باختيار الإطار المناسب، يعتمد ذلك على الاحتياجات والمتطلبات للتطبيق الذي تريد تطويره. إذا كنت تبحث عن تطبيق أكثر تعقيدًا وتفاعليًا، فقد يكون React Native الخيار الأفضل. وإذا كنت تريد تطبيقًا بسيطًا وخفيف الوزن، فإن Ionic قد يكون الأفضل. ومع ذلك، إذا كان لديك فريق مطورين يعرفون AngularJS، فقد يكون من الأفضل استخدام Ionic بدلاً من React Native. كما يمكن أن يلعب الاعتماد على تقنيات Native لتحسين أداء التطبيق دورًا في اختيار الإطار المناسب. يعمل React Native بشكل أسرع من Ionic ويتيح توفير تجربة مستخدم أكثر سلاسة وتفاعلية، نظرًا لأنه يعتمد على تقنيات Native. ولكن في حالة تطبيقات Ionic، يمكن أن يتم استخدام تقنيات Cordova لتشغيل التطبيقات على المنصات المختلفة، مما يمكن من تحسين أدائها. بشكل عام، يمكن استخدام React Native لتطوير تطبيقات الموبايل عندما يكون التركيز على توفير تجربة مستخدم عالية الجودة وتطبيقات متطورة ومعقدة. ويمكن استخدام Ionic لتطوير تطبيقات متوسطة الحجم والتعامل مع المشاكل المختلفة بسرعة وكفاءة. إذا كنت ترغب في تطوير تطبيقات متعددة المنصات باستخدام الويب تقريبًا في المرتبة الأولى، فإن Ionic يمكن أن يكون الإطار الأفضل، في حين يمكن استخدام React Native لتطوير تطبيقات الجوال الأكثر تطوراً والمتقدمة.1 نقطة
-
التطبيقات الأصيلة (Native Applications) هي التطبيقات التي تم تصميمها وتطويرها بشكل كامل لتعمل على منصة محددة مثل نظام التشغيل iOS أو Android. تستخدم هذه التطبيقات لغات البرمجة والأدوات المختلفة التي يدعمها كل نظام تشغيل. وعادة ما يتم تثبيت هذه التطبيقات مباشرة على الجهاز المستخدم ويمكن الوصول إليها من خلال الشاشة الرئيسية أو القائمة. من ناحية أخرى، التطبيقات الهجينة (Hybrid Applications) هي التطبيقات التي تم تطويرها باستخدام تقنيات وأدوات عامة يمكن استخدامها لتصميم تطبيقات لعدة منصات مختلفة. وتستخدم هذه التطبيقات عادة لغات برمجة الويب مثل HTML و CSS و JavaScript. وعادة ما تعتمد هذه التطبيقات على محركات تطبيقات كـ Cordova أو PhoneGap وغيرها من المنصات لتمكين وصول التطبيق لخصائص النظام الأساسي. الفرق الرئيسي بين التطبيقات الأصيلة والتطبيقات الهجينة هو في الأداء وتجربة المستخدم. حيث تعمل التطبيقات الأصيلة بشكل أسرع وأكثر سلاسة وتوفر تجربة مستخدم أكثر تفصيلاً وشاملية. بينما التطبيقات الهجينة يمكن تصميمها بشكل أسرع وأرخص، وتسمح بنشر التطبيقات لعدة منصات، ويمكن تحديثها بشكل أسرع وأسهل. ومع ذلك، فإنها قد توفر تجربة مستخدم أقل دقة وتوافق أقل مع الموبايل. أما بالنسبة ل React Native و Ionic كلاهما أطر تطوير تطبيقات الجوال المتنقلة الهجينة، ولكن يختلفان في بعض النواحي: لغة البرمجة: React Native يستخدم لغة الجافاسكريبت (JavaScript)، ويعتمد على مكتبة React. Ionic يستخدم لغة الجافاسكريبت (JavaScript) أيضًا، ويعتمد على مكتبة Angular. الأداء: React Native يستخدم تقنية الـNative Modules للوصول إلى الميزات الخاصة بالجهاز والتفاعل معها، مما يسمح بتحسين أداء التطبيق. Ionic يستخدم تقنية WebView التي تعمل بناءً على تقنية HTML و CSS، مما يؤدي إلى بعض التأخير في الأداء. التعلم والتطوير: React Native يتطلب مهارات في الجافاسكريبت و React، ولكنه يوفر وثائق تفصيلية ودعمًا قويًا من المجتمع. Ionic يتطلب مهارات في Angular و HTML و CSS، ولكنه يوفر أيضًا وثائق تفصيلية ودعمًا من المجتمع. توافق الأنظمة الأساسية: React Native يعمل على أنظمة iOS و Android ويدعم أيضًا تطوير تطبيقات ويب. Ionic يعمل على أنظمة iOS و Android و Windows و Blackberry. بشكل عام، إذا كنت ترغب في تطوير تطبيقات جوال متطورة وسريعة الأداء، فإن React Native هو الخيار الأفضل. وإذا كنت تفضل أدوات التطوير الخاصة بويب، فإن Ionic هو الخيار الأفضل.1 نقطة
-
التطيقات الاصلية هي تطبيقات مكتوبة بالغة الاصلية لنظام التشغيل مثلا للاندرويد اللغة الاصلية هي Java وبالنسبة لنظام ال IOS فهي لغة سويفت Swift. وهذا تعرف مفصل أكثر. التطبيقات الأصلية Native Apps التطبيقات الهجينة Hybrid Apps ولتفصيل أكثر أنصحك بتصفح هذه المقالات. كل ما تحتاج إلى معرفته عن برمجة تطبيقات الجوال - مدونة مستقل (mostaql.com) دليلك لبناء التطبيقات الهجينة Hybrid Mobile Apps - مدونة مستقل (mostaql.com) وهذه بعض النقاشات التي تتكلم عن نفس الموضع. https://io.hsoub.com/programming/79886-هل-تفضل-ان-تكون-مطور-تطبيقات-اصلية-او-هجينة-و-لماذا https://io.hsoub.com/webdev/147-تطبيقات-الهواتف-الذكية-الطبيعي-native-أم-الهجين-hybrid1 نقطة
-
الفرق بين تطبيقات الموبايل الأصيلة والهجينة. هو كالتالي - التطبيقات الأصيلة Native Apps هي تطبيقات تم تطويرها لأداء مهمة معينة على نظام تشغيل معين باستخدام لغات برمجة متوافقة معه، مثل Swift مع iOS و Java مع أندرويد. تتميز التطبيقات الأصيلة بسرعة الأداء، المرونة، الحماية والقدرة على الوصول إلى جميع ميزات النظام الأساسي. - التطبيقات الهجينة Hybrid Apps هي تطبيقات تم تطويرها لتعمل على أكثر من نظام تشغيل باستخدام تقنيات الويب نفسها (HTML – CSS – JavaScript). تتميز التطبيقات الهجينة بسهولة البناء، التكلفة المنخفضة، التحديث السريع والقدرة على الوصول إلى بعض ميزات النظام الأساسي. - الفرق الرئيسي بين التطبيقات الأصيلة والهجينة هو كيفية استضافة النظام التشغيل المستهدف للتطبيق. فالتطبيقات الأصيلة تعمل كجزء من النظام التشغيل، بينما التطبيقات الهجينة تعمل من خلال تقنية مساعدة تسمى Webview في أندرويد و UIWebView في iOS⁵. كما يمكنك مشاهدة الفيديو التالي1 نقطة
-
الخطأ يحدث بسبب استخدام نوع البيانات الخاطئ للمعامل الثاني في دالة "getTranslations" في الصف "Product" من النموذجات (Models) في Laravel. يتوقع أن يكون المعامل الثاني من نوع "Zarray"، ولكن تم تمرير نص (string) بدلاً من ذلك، الأمر الذي يؤدي إلى حدوث هذا الخطأ. يجب تحديد قيمة المعامل الثاني باستخدام النوع الصحيح "Zarray"، وذلك بتمرير مصفوفة اللغات المسموح بها في النظام كمصفوفة من الأعراف الأساسية: $allowedLocales = ['en', 'fr', 'ar']; // مثال لمصفوفة اللغات المسموح بها $translations = $product->getTranslations($attribute, $allowedLocales); وبهذه الطريقة، يتم تمرير مصفوفة اللغات المسموح بها بشكل صحيح إلى دالة "getTranslations"، ويمكن تجنب حدوث هذا الخطأ. يجب تعديل الكود ليتوافق مع هذا التنسيق.1 نقطة
-
بمكان ما في ملف العرض المعني تقومين باستدعاء التابع getTranslations وتعطينه سلسلة نصية كمعامل ثان عوض مصفوفة، أظنك تقصدين استعمال التابع getTranslation وليس getTranslations. ابحثي عن موضع الخطأ وأصلحيه.1 نقطة
-
ربما السبب يعود إلى استخدامك إضافة لعمل كاش للموقع، حيث يجب ضبطها لإعادة بناء الكاش عند عمل تغييرات على الموقع أو يمكنك تعطيلها لحين الإنتهاء، أو حذف الكاش من خلال الإضافة من خلال عمل purge او delete كاش. وأيضًا ربما أنت تستخدم Cloudflare كـ CDN لذلك يجب حذف الكاش منه من خلال عمل purge. وأيضًا يجب تصفح الموقع الخاص من خلال نافذة Incognito mode أو وضع التخفي لتجنب رؤية النسخة التي تم عمل كاش لها في المتصفح، أو يمكنك تعطيل الكاش في المتصفح من خلال disable cache في نافذة network التي ستظهر لك عند الضغط على F12.1 نقطة
-
الامر بسيط بتوحيد لون ال text بلون الخلفية او نستخدم خاصية text-indent #تكليفات الزيرو اولا كود ال HTML <div class="two" style=" background-color: red; color: white; padding: 20px; border: 1px solid blue; font-size: 80px;"> Hello Div </div> لاحظ لا يمكن الوصول او التعديل علي كود ال html .two{ width: 400px !important; margin: 30px auto !important; color: #eee !important; /* or تم توحيد اللون هنا بلون لون النص الخلفية */ >>>/* text-indent: -2000px; */ /* ونطلعها برا الصفحة خالص text-indent او نستخدم خاصية*/ font-size: 20px !important; background-color: #eee !important; /* بلون الخلفية هنا */ border: none !important; text-align: center; position: relative; } .two::after{ content: "Elzero"; position: absolute; top: 18px; left: 196px; font-family: Arial, Helvetica, sans-serif; font-weight: bold; color: black; text-align: center; } الرد متاخر بس عشان لو حد بيتعلم وسال نفس السوال بالتوفيق1 نقطة
-
يُعد فلاسك إطار عمل للويب مبني بلغة بايثون، ويتميز بكونه صغير الحجم وسهل المعالجة، ويوفّر أيضًا عدة أدوات وميزات من شأنها جعل إنشاء تطبيقات الويب في لغة بايثون أسهل. عند تطوير تطبيق ويب ما، من الضروري الفصل بين ما يدعى "منطق العمل business logic" و"منطق العرض presentation logic"؛ إذ يكون منطق العمل مسؤولاً عن التعامل مع طلبات المستخدمين، مُخاطبًا قاعدة البيانات لإنشاء الاستجابة المناسبة؛ في حين يُحدّد منطق العرض كيفيّة عرض البيانات للمستخدم، وذلك غالبًا باستخدام ملفات HTML لإنشاء الهيكل الأساسي لصفحة الويب التي تستجيب لطلبات المستخدمين، مع استخدام تنسيقات CSS لتنسيق مظهر تلك المكونات المبنية باستخدام HTML. فمثلًا في حال كان لدينا تطبيق للتواصل الاجتماعي، فيوجد عادةً حقلٌ لإدراج اسم المستخدم وحقل لإدراج كلمة المرور بحيث لا يظهران إلّا في حال كون المستخدم لم يسجل دخوله إلى التطبيق بعد، ولدى كتابة المستخدم اسم المستخدم وكلمة المرور يعمل فلاسك على تطبيق منطق العمل، إذ تُستخرج البيانات (اسم المستخدم وكلمة المرور) من الطلب ليُسجَّل دخول المستخدم إذا كانت هذه البيانات صحيحة، وإلّا ستظهر رسالة خطأ، ويجري التعامل مع كيفية ظهور رسالة الخطأ بالاعتماد على منطق العرض. يستخدم فلاسك محرّك القوالب جينجا jinja لبناء صفحات HTML ديناميكيًا باستخدام مفاهيم بايثون المألوفة، من متغيراتٍ وحلقاتٍ تكرارية وقوائم وغيرها، وبالتالي ستُستخدم هذه القوالب على أنها جزءٌ من هذا المشروع، إذ يُعرّف القالب بأنه ملف يحتوي على مكونات ثابتة وأُخرى ديناميكية، وعندما يطلب المستخدم عنصرًا من التطبيق، مثل الصفحة الرئيسية، أو صفحة تسجيل الدخول، يُمكنّنا جينجا من الاستجابة باستخدام قالب HTML، وبذلك يصبح من الممكن استخدام عددٍ كبيرٍ من الميزات غير المتوفرة أصلًا في لغة HTML المعيارية، مثل المتغيرات والعبارة الشرطية "if" والحلقات التكرارية مثل حلقة "for"، والمُرشّحات filters ومفهوم وراثة القوالب، إذ تسمح لنا هذه الخواص بكتابة صفحات HTML سهلة الإصلاح، كما تعزل جينجا شيفرات HTML تلقائيًا بهدف منع هجمات البرمجة العابرة للمواقع Cross-Site Scripting -أو اختصارًا XSS-. سنبني في هذا المقال تطبيق ويب صغير يعمل على تصييّر عدّة ملفات HTML ضمن المتصفح معًا، إذ سنستخدم المتغيرات لتمرير البيانات من الخادم إلى القوالب، كما سنطبّق مفهوم وراثة القوالب لتجنُّب التكرار في الشيفرات البرمجية. وسنستخدم كذلك التعابير المنطقية في بناء شيفرات القوالب من عبارات شرطية وحلقات، وسنطبّق المُرشّحات اللازمة لتعديل النصوص، وسنعمل من خلال إطار العمل بوتستراب bootstrap على إضافة التنسيقات على التطبيق ليبدو أكثر جاذبية بصريًا. مستلزمات العمل قبل المتابعة في هذا المقال لا بُدّ من: توفُّر بيئة برمجة بايثون 3 محلية، مثبّتة على حاسوبك، وسنفترض في مقالنا أن اسم مجلد المشروع هو "flask_app". توفّر إطار العمل فلاسك مُثبّت ضمن البيئة البرمجبة كما هو مُبيّن في الخطوة الأولى من المقال كيفية بناء موقعك الإلكتروني الأول باستخدام إطار عمل فلاسك Flask والإصدار الثالث من لغة بايثون. الفهم الجيد لأساسيات فلاسك، مثل مفهوم الوجهات routes ودوال العرض view في فلاسك، ويمكنك في هذا الصدد الاطلاع على المقال كيفية بناء موقعك الإلكتروني الأول باستخدام إطار عمل فلاسك Flask والإصدار الثالث من لغة بايثون المشار إليه أعلاه لفهم مبادئ فلاسك. فهم أساسيات لغة HTML. الخطوة الأولى - تصيير القوالب واستخدام المتغيرات بعد التأكّد من تفعيل بيئة البرمجة وتثبيت فلاسك، سنبدأ ببناء التطبيق، إذ تتمثّل الخطوة الأولى بعرض رسالة ترحيب بالزوار في الصفحة الرئيسية، وسنستخدم لهذا الغرض دالة فلاسك المساعدة ()render_template لتوفير قوالب HTML مثل استجابة ضمن الصفحة، وسنتعلّم في هذا الصدد كيفيّة تمرير المتغيرات من التطبيق إلى القوالب. بدايةً نفتح الملف "app.py" الموجود في المجلد "flask_app" لتعديله وذلك باستخدام محرّر النصوص نانو "nano" أو أي محرر آخر تفضّله: (env) user@localhost:$ nano app.py ونضيف الشيفرة التالية ضمنه: from flask import Flask, render_template app = Flask(__name__) @app.route('/') def hello(): return render_template('index.html') نحفظ الملف ونغلقه. استوردنا في الشيفرة السابقة الصنف Flask الذي سنستخدمه لإنشاء نسخة من تطبيق باسم "app"، كما استوردنا الدالة ()render_template من حزمة flask، ثمّ عرفنا دالة العرض ()hello (وهي في الواقع دالة بايثون اعتيادية تعيد استجابةً من النمط HTTP) باستخدام المُزخرف ()app.route، الذي يحوّل دوال بايثون الاعتيادية إلى دوال عرض في فلاسك، تستخدم دالة العرض هذه الدالة ()render_template لتصييّر ملف قالب HTML المُسمّى "index.html". الآن، سننشئ القالب "index.html" ضمن المجلد الفرعي "templates" من المجلد الرئيسي "flask_app"، إذ سيبحث فلاسك عن القوالب في المجلد المسمّى "templates" تحديدًا، لذا يُعدُّ الاسم مهمًا. لإنشاء هذا المجلد، نتأكد من وجودنا ضمن المجلد "flask_app" وننفذ الأمر التالي: (env) user@localhost:$ mkdir templates بعد ذلك، ننشئ ملفًا باسم "index.html" ضمن مجلد القوالب "templates" لنكتب ضمنه لاحقًا الشيفرات اللازمة، ومن الجدير بالملاحظة أنّه من غير الضروري التقيُّد باسم "index.html" على عكس اسم المجلد الرئيسي، فمن الممكن تغييّر اسم الملف ليصبح مثلًا "home.html"، أو "homepage.html"، أو أي اسم آخر تفضّله: (env) user@localhost:$ nano templates/index.html ثمّ نضيف شيفرة HTML التالية داخل الملف "index.html": <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>FlaskApp</title> </head> <body> <h1>Hello World!</h1> <h2>Welcome to FlaskApp!</h2> </body> </html> اخترنا في الشيفرة السابقة عنوانًا للصفحة، كما أضفنا الرسالة "!Hello World" لتظهر ضمن تنسيق عنوان من المستوى الأوّل H1، والرسالة "!Welcome to FlasApp" لتظهر ضمن تنسيق عنوان من المستوى الثاني H2. نحفظ الملف ونغلقه. ولتشغيل تطبيق الويب الذي أنشأناه، وبعد التأكّد من وجودنا ضمن المجلد "flask_app" مع تفعيل البيئة الافتراضية، لا بُدّ من إرشاد فلاسك إلى موقع التطبيق (في حالتنا الملف ذو الاسم app.py) باستخدام متغير بيئة فلاسك FLASK_APP، ولتشغيله بوضع التطوير، نضبط متغير بيئة فلاسك Flask_ENV على الوضع development على النحو التالي (مع ملاحظة أنّنا نستخدم الأمر set في بيئة ويندوز عوضًا عن الأمر export): (env) user@localhost:$ export FLASK_APP=app (env) user@localhost:$ export FLASK_ENV=development بعدها سنشغل التطبيق باستخدام الأمر flask run: (env) user@localhost:$ flask run بعد التأكد من كون خادم التطوير ما يزال قيد التشغيل، نذهب إلى الرابط التالي باستخدام المتصفح: http://127.0.0.1:5000/ فتظهر العبارة "FlasApp" عنوانًا للصفحة، ويجري تصييّر الرسالتين المكتوبتين في HTML لتظهرا بالتنسيق المطلوب. تُمرّر البيانات عادةً في تطبيقات الويب من ملفات بايثون الخاصة بالتطبيق إلى قوالب HTML، ولنوضّح كيفية فعل ذلك في تطبيقنا هذا، سنمرّر متغيرًا يحتوي على التاريخ والوقت وفق التوقيت العالمي UTC إلى القالب الرئيسي، وبعدها سنعرض قيمة هذا المتغير في القالب. سنترك خادم التطوير قيد التشغيل وسنفتح الملف app.py في نافذة أسطر أوامر جديدة للتعديل عليه: (env) user@localhost:$ nano app.py سنستورد الوحدة الخاصّة بالتعامل مع الوقت والتاريخ datetime من مكتبة بايثون المعيارية وسنعدّل الدالة ()index ليبدو الملف كما يلي: import datetime from flask import Flask, render_template app = Flask(__name__) @app.route('/') def hello(): return render_template('index.html', utc_dt=datetime.datetime.utcnow()) نحفظ الملف ونغلقه. استوردنا في الشيفرة السابقة الوحدة datetime ومرّرنا المتغير المُسمّى utc_dt مع قيمة ()datetime.datetime.utcnow التي تمثّل الوقت والتاريخ الحالي وفق التوقيت العالمي إلى القالب "index.html". ولعرض قيمة هذا المتغير في الصفحة الرئيسية، سنفتح الملف index.html من أجل التعديل عليه: (env) user@localhost:$ nano templates/index.html وسنعدّل الملف كما يلي: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>FlaskApp</title> </head> <body> <h1>Hello World!</h1> <h2>Welcome to FlaskApp!</h2> <h3>{{ utc_dt }}</h3> </body> </html> نحفظ الملف ونغلقه. أضفنا موضعًا لنص منسّق مثل عنوان من المستوى الثالث H3 مع استخدام المُحدّد الخاص "{{ … }}" لطباعة قيمة المتغيّر utc_dt ضمنه. الآن، بالذهاب إلى صفحة التطبيق الرئيسية ضمن المتصفح: http://127.0.0.1:5000/ ستظهر صفحة مشابهة للصورة التالية: ومع نهاية هذه الخطوة نكون قد أنشأنا صفحةً رئيسيةً ذات قالب HTML داخل تطبيق فلاسك، وصيّرنا محتويات قالب آخر، ومرّرنا وأظهرنا قيمة مُتغير، وفيما يلي سنتجنّب تكرار الشيفرات البرمجية باستخدام مفهوم وراثة القوالب. الخطوة الثانية – استخدام مفهوم وراثة القوالب سننشئ في هذه الخطوة قالبًا أساسيًا ذا محتوًى قابل للمشاركة مع القوالب الأُخرى، وسنعدّل قالب الصفحة الرئيسية index template للتطبيق ليرث من القالب الأساسي هذا، ثمّ سننشئ صفحةً جديدةً مسؤولةً عن عرض معلومات التطبيق للمستخدمين. يحتوي القالب الأساسي على أهم مكونات HTML المُستخدمة عادةً في أي قالب، مثل عنوان التطبيق وأشرطة التنقّل والتذييلات. بدايةً، سننشئ ملفًا جديدًا باسم "base.html" ضمن مجلد القوالب templates: (env) user@localhost:$ nano templates/base.html وسنكتب ضمنه الشيفرات التالية: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %} {% endblock %} - FlaskApp</title> <style> nav a { color: #d64161; font-size: 3em; margin-left: 50px; text-decoration: none; } </style> </head> <body> <nav> <a href="#">FlaskApp</a> <a href="#">About</a> </nav> <hr> <div class="content"> {% block content %} {% endblock %} </div> </body> </html> نحفظ الملف ونغلقه. الجزء الأكبر من الشيفرة السابقة هو تعليمات HTML معيارية تشمل عنوانًا وبعض التنسيقات لروابط التنقل، إضافةً إلى شريط تنقّل مع رابطين، أحدهما للوصول إلى الصفحة الرئيسية للتطبيق والآخر للوصول إلى صفحة المعلومات التي لم ننشئها بعد، إضافةً إلى عنصر الحافظة <div> ليتضمّن محتويات الصفحة. لا تعمل هذه الروابط بعد لكننا سنوضح في الخطوة التالية كيفية إنشاء الربط بين الصفحات. أمّا الأجزاء من الشيفرة الموضحّة فيما يلي فهي خاصةٌ بمحرك القوالب جينجا: {% block title %} {% endblock %}: كتلة برمجية تحجز مكانًا لعنوان الصفحة، الذي سنستخدمه لاحقًا في تحديد العنوان الخاص بكل صفحة في التطبيق دون الحاجة إلى إعادة كتابة قسم الترويسة <head> كاملًا في كل مرةٍ من أجل كل صفحة. {% block content %} {% endblock %}: كتلة برمجية أخرى ستُستبدل لاحقًا بالمحتوى الفعلي بالاعتماد على القالب الابن، أي القالب الذي يرث شيفرات القالب الرئيسي "base.html". والآن، بعد أن أصبح لديك قالبٌ رئيسي، يمكنك الاستفادة من ميزاته باستخدام فكرة الوراثة، لذلك افتح الملف "index.html": (env) user@localhost:$ nano templates/index.html ثمّ استبدل محتوياته بما يلي: {% extends 'base.html' %} {% block content %} <h1>{% block title %} Index {% endblock %}</h1> <h1>Hello World!</h1> <h2>Welcome to FlaskApp!</h2> <h3>{{ utc_dt }}</h3> {% endblock %} استخدمنا في هذه النسخة الجديدة من القالب template.html الوسم {% extends %} للوراثة من القالب الرئيسي base.html، وذلك عن طريق استبدال الشيفرة السابقة بكتلة المحتوى content في القالب الرئيسي. تحوي كتلة المحتوى هذه على وسم <h1> وبداخله كتلة عنوان title تحتوي على العبارة "Index"، والتي بدورها تستبدل كتلة العنوان title الموجودة أصلًا في القالب الرئيسي base.html لتحتوي على العبارة "Index" وبذلك يصبح العنوان كاملًا "Index - FlaskApp"، وبهذه الطريقة نتفادى تكرار نفس النص مرتين، ذلك لأنّ هذا النص سيظهر في عنوان الصفحة وضمن الوسم <h1> أسفل شريط التصفح الموروث من القالب الرئيسي. وبذلك يصبح لدينا عدة عناوين، الأوّل بتنسيق من المستوى الأوّل <h1> يتضمّن النص "!Hello World"، والثاني بتنسيق من المستوى الثاني <h2>، والثالث بتنسيق من المستوى الثالث <h3> والذي يحتوي على قيمة متغير الوقت والتاريخ utc_dt. تمكنّنا وراثة القوالب من إعادة استخدام شيفرة HTML الموجودة في القوالب الأخرى (القالب الرئيسي base.html في حالتنا) دون الحاجة لتكراره في كل مرة. اِحفظ الملف وأغلقه، ثم حدِّث الصفحة الرئيسية index في المتصفح، فستظهر الصفحة بشريط تصفح وعنوانٍ منسقٍ كما يلي: أمّا الآن فسننشئ صفحة معلومات التطبيق، لذا سنفتح الملف "app.py" ولنضيف ضمنه وجهةً جديدةً: (env) user@localhost:$ nano app.py ونضيف الوجهة التالية إلى نهايته: # ... @app.route('/about/') def about(): return render_template('about.html') استخدمنا المزخرف ()app.route لإنشاء دالة فلاسك باسم "()about"، إذ ترجع ضمنها نتيجة استدعاء الدالة ()render_template لدى تمرير اسم ملف القالب "about.html" وسيطًا لها. نحفظ الملف ونغلقه. الآن سننشئ ملف قالب باسم "about.html" كما يلي: (env) user@localhost:$ nano templates/about.html ونضيف ضمنه الشيفرة التالية: {% extends 'base.html' %} {% block content %} <h1>{% block title %} About {% endblock %}</h1> <h3>FlaskApp is a Flask web application written in Python.</h3> {% endblock %} استخدمنا في الشيفرة السابقة الوسم extend لوراثة الشيفرات من القالب الرئيسي، كما استبدلنا كتلة المحتوى content في القالب الرئيسي بوسم من النوع <h1> الذي يعمل أيضًا بمثابة عنوان للصفحة، وأضفنا بعض المعلومات حول التطبيق ضمن وسم من النوع <h3>. نحفظ الملف ونغلقه. بعد التأكد من أنّ خادم التطوير ما يزال قيد التشغيل، ننتقل إلى الرابط التالي باستخدام المتصفح: http://127.0.0.1:5000/about فتظهر صفحةٌ مشابهة للصورة التالية: نلاحظ وراثة شريط التنقل وجزءٍ من العنوان من القالب الأساسي. ومع نهاية هذه الخطوة نكون قد أنشأنا قالبًا أساسيًا واستخدمناه في بناء صفحة التطبيق الرئيسية وصفحة معلومات التطبيق لتجنُّب تكرار الشيفرات، إلّا أنّ الروابط في شريط التنقل ما تزال غير مُفعّلة ولا تؤدي أية مهمة حتى الآن، لذا سنربط في الخطوة سنربط بين الوجهات في القوالب من خلال تعديل الروابط في شريط التنقل. الخطوة الثالثة – الربط بين الصفحات سنتعلّم في هذه الخطوة كيفيّة الربط بين الصفحات باستخدام الدالة المساعدة ()url_for، إذ سنضيف رابطين إلى شريط التنقل في القالب الأساسي، أحدهما للوصول إلى الصفحة الرئيسية والآخر للوصول إلى صفحة معلومات التطبيق. بدايةً سنفتح القالب الأساسي لتعديله: (env) user@localhost:$ nano templates/base.html ونعدّل الملف كما يلي: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %} {% endblock %} - FlaskApp</title> <style> nav a { color: #d64161; font-size: 3em; margin-left: 50px; text-decoration: none; } </style> </head> <body> <nav> <a href="{{ url_for('hello') }}">FlaskApp</a> <a href="{{ url_for('about') }}">About</a> </nav> <hr> <div class="content"> {% block content %} {% endblock %} </div> </body> </html> استخدمنا في الشيفرة السابقة دالة ()url_for خاصّة، والتي ستُعيد الرابط الموافق لدالة فلاسك المُمرّرة لها، إذ أنّ الرابط الأول مرتبط بالوجهة الخاصة بدالة فلاسك ()hello (وهي الصفحة الرئيسية للتطبيق)، في حين يرتبط الرابط الثاني بالوجهة الخاصة بدالة فلاسك ()about، مع ملاحظة أنّنا مرّرنا اسم دالة فلاسك وسيطًا وليس اسم الوجهة (/ أو about/). يساعد استخدام الدالة ()url_for لبناء الروابط على إدارتها على نحوٍ أفضل، فلو كتبنا الروابط بصورةٍمحددة وبتعليمات برمجية ثابتة فإنها ستفشل مع أول تعديل على الوجهات، في حين أنّه ومع استخدام الدالة ()url_for فمن الممكن التعديل على الوجهات مع ضمان محافظة الروابط على عملها الطبيعي المتوقع، ناهيك عن كون دالة ()url_for مسؤولة أيضًا عن أمور أُخرى مثل عزل المحارف الخاصة. نحفظ الملف ونغلقه. سنعود الآن إلى الصفحة الرئيسية ونجرّب الروابط الموجودة في شريط التنقل، فنجد أنها تعمل كما هو مطلوب. ومع نهاية هذه الخطوة نكون قد تعلمنا كيفية استخدام الدالة ()url_for للربط بين الوجهات في القوالب، وفيما يلي سنضيف بعض العبارات الشرطية للتحكم بما يُعرض في القوالب بناءً على الشروط التي نضعها، كما سنستخدم حلقات "for" التكرارية في قوالبنا لعرض عناصر القائمة. الخطوة الرابعة - استخدام العبارات الشرطية والحلقات التكرارية سنستخدم في هذه الخطوة العبارة الشرطية "if" في القوالب للتحكم بما سيُعرض بناءً على شروط محدّدة، كما سنستخدم حلقات "for" التكرارية للتنقّل بين عناصر قوائم بايثون وعرضها، ثمّ سنضيف صفحةً جديدةً إلى التطبيق مهمتها عرض التعليقات ضمن قائمة، بحيث تكون التعليقات ذات رقم الدليل الزوجي بخلفية زرقاء والتعليقات ذات رقم الدليل الفردي بخلفية رمادية. سننشئ بدايةً وجهةً جديدةً لصفحة التعليقات، لذا سنفتح الملف app.py للتعديل عليه: (env) user@localhost:$ nano app.py ونضيف الوجهة التالية إلى نهاية الملف: # ... @app.route('/comments/') def comments(): comments = ['This is the first comment.', 'This is the second comment.', 'This is the third comment.', 'This is the fourth comment.' ] return render_template('comments.html', comments=comments) لدينا في الوجهة السابقة قائمة مبنية في بايثون باسم comments تحتوي على أربعة عناصر (في التطبيق العملي يمكن الحصول على هذه التعليقات من قاعدة البيانات بدلاً من كتابتها يدويًا وتثبيتها ضمن الشيفرة)، لتكون القيمة المعادة هي تصيّير لملف قالب باسم "comments.html" وذلك في السطر الأخير من الشيفرة، ممررين المتغير comments الذي يحتوي القائمة مثل وسيط إلى ملف القالب. نحفظ الملف ونغلقه. بعدها ننشئ ملف جديد باسم comments.html ضمن مجلد القوالب templates للتعديل عليه: (env) user@localhost:$ nano templates/comments.html ونضيف ضمنه الشيفرة التالية: {% extends 'base.html' %} {% block content %} <h1>{% block title %} Comments {% endblock %}</h1> <div style="width: 50%; margin: auto"> {% for comment in comments %} <div style="padding: 10px; background-color: #EEE; margin: 20px"> <p style="font-size: 24px">{{ comment }}</p> </div> {% endfor %} </div> {% endblock %} وفيه توسعنا بالقالب الأساسي base.html واستبدلنا محتويات كتلة المحتوى content. واستخدمنا تنسيق عنوان من النمط <h1> الذي سيعمل أيضًا بمثابة عنوانٍ للصفحة. كما استخدما حلقة for التكرارية وهي من ضمن تعليمات محرّك القوالب جينجا وذلك في السطر البرمجي {% for comment in comments %} بهدف التنقل بين التعليقات في القائمة comments المُخزنة ضمن المتغير المسمّى comment، إذ سنعرض التعليقات باستخدام الوسم <p style="font-size: 24px">{{ comment }}</p>، أي بنفس الآلية التي يُعرض فيها أي متغير في جينجا، مع ملاحظة أنّ نهاية حلقة for هنا تكون باستخدام الكلمة المفتاحية {% endfor %} الأمر المختلف عن طريقة بناء حلقات for في بايثون. نحفظ الملف ونغلقه. الآن وبعد التأكد من كون خادم التطوير ما يزال قيد التشغيل، نفتح المتصفح وننتقل إلى صفحة التعليقات باستخدام الرابط: http://127.0.0.1:5000/comments فتظهر الصفحة بما يشبه التالي: الآن سنستخدم عبارة if الشرطية في القوالب لعرض التعليقات ذات رقم الدليل الفردي بخلفية رمادية والتعليقات ذات رقم الدليل الزوجي بخلفية زرقاء. لذا سنفتح ملف القالب comments.html: (env) user@localhost:$ nano templates/comments.html ثمّ سنعدله ليصبح كما يلي: {% extends 'base.html' %} {% block content %} <h1>{% block title %} Comments {% endblock %}</h1> <div style="width: 50%; margin: auto"> {% for comment in comments %} {% if loop.index % 2 == 0 %} {% set bg_color = '#e6f9ff' %} {% else %} {% set bg_color = '#eee' %} {% endif %} <div style="padding: 10px; background-color: {{ bg_color }}; margin: 20px"> <p>#{{ loop.index }}</p> <p style="font-size: 24px">{{ comment }}</p> </div> {% endfor %} </div> {% endblock %} وفي هذا التعديل أضفنا عبارة if الشرطية في السطر {% if loop.index % 2 == 0 %}، إذ أنّ المتغير loop هو متغير خاص في جينجا يمكنّنا من الوصول إلى معلومات حول الحلقة الحالية، واستخدمنا loop.index للحصول على دليل العنصر الحالي، الذي يبدأ من "1" وليس من "0" كما هو الحال في قوائم بايثون. تتحقق عبارة if ما إذا كان الدليل زوجياً باستخدام عملية باقي القسمة %، إذ تُفحص قيمة باقي قسمة الدليل على الرقم "2"، فإذا كان الباقي يساوي "0"، فهذا يعني أن الدليل زوجي، وإلّا فيكون الدليل فرديًا. استخدمنا الوسم {% set %} للتعريف عن متغير باسم bg_color ليتضمّن لون الخلفية المطلوب، فإذا كان الدليل زوجيًا، نضبط قيمة هذا المتغير إلى اللون الأزرق، وإلّا وفي حال كون الدليل فرديًا نضبطها إلى اللون الرمادي، ثم نخصّص المتغير bg_color لضبط لون الخلفية للوسم <div> الحاوي على التعليق. نستخدم loop.index في أعلى النص الخاص بالتعليق لعرض رقم الدليل الحالي ضمن وسمٍ من النوع <p>. نحفظ الملف ونغلقه. الآن بفتح المتصفح والانتقال إلى صفحة التعليقات كما يلي: http://127.0.0.1:5000/comments ستظهر صفحة التعليقات الجديدة كما في الصورة: وضّحنا فيما سبق كيفية استخدام العبارة الشرطية if، ولكن من الممكن الحصول على نفس النتيجة باستخدام الدالة الخاصّة المساعدة ()loop.cycle في جينجا، ولتوضيح هذه النقطة سنفتح الملف "comments.html": (env) user@localhost:$ nano templates/comments.html ونعدله ليصبح كما يلي: {% extends 'base.html' %} {% block content %} <h1>{% block title %} Comments {% endblock %}</h1> <div style="width: 50%; margin: auto"> {% for comment in comments %} <div style="padding: 10px; background-color: {{ loop.cycle('#EEE', '#e6f9ff') }}; margin: 20px"> <p>#{{ loop.index }}</p> <p style="font-size: 24px">{{ comment }}</p> </div> {% endfor %} </div> {% endblock %} حذفنا في هذه الشيفرة العبارة الشرطية "if/else" واستخدمنا عوضًا عنها الدالة المساعدة ('loop.cycle('#EEE', '#e6f9ff للتنقل بين اللونين، إذ ستكون قيمة المتغيّر background-color مساويةً للقيمة "#EEE" للون الرمادي مرّةً، ثمّ تتحول إلى القيمة "#e6f9ff" للون الأزرق مرةً أُخرى، وهكذا بالتناوب. نحفظ الملف ونغلقه. لدى فتح صفحة التعليقات في المتصفح وتحديثها، ستظهر صفحةٌ مشابهةٌ لتلك التي ظهرت مع استخدام عبارة "if" الشرطية. يمكن استخدام عبارات "if" الشرطية لأغراض مختلفة، بما في ذلك التحكم بما يُعرض على الصفحة، فعلى سبيل المثال لعرض جميع التعليقات باستثناء التعليق الثاني، يمكننا استخدام عبارة if بالشرط loop.index != 2 لترشيح التعليق الثاني. لذا سنفتح قالب التعليقات: (env) user@localhost:$ nano templates/comments.html ونعدله ليصبح كما يلي: {% extends 'base.html' %} {% block content %} <h1>{% block title %} Comments {% endblock %}</h1> <div style="width: 50%; margin: auto"> {% for comment in comments %} {% if loop.index != 2 %} <div style="padding: 10px; background-color: #EEE; margin: 20px"> <p>#{{ loop.index }}</p> <p style="font-size: 24px">{{ comment }}</p> </div> {% endif %} {% endfor %} </div> {% endblock %} استخدمنا العبارة الشرطية {% if loop.index != 2 %} لعرض التعليقات ذات رقم الدليل غير المساوي للرقم "2"، ما يشمل جميع التعليقات باستثناء التعليق الثاني، كما استخدمنا شيفرةً ثابتةً لتغيير لون الخلفية بدلًا من استخدام الدالة المساعدة ()loop.cycle لتسهيل الأمور، أمّا بالنسبة لبقية أجزاء الشيفرة، فلم نجري عليها أي تغييرات، وأيضًا هنا تُنهى عبارة if الشرطية باستخدام الأمر {% endif %}. نحفظ الملف ونغلقه. سنلاحظ بتحديث صفحة التعليقات عدم ظهور التعليق الثاني. سنضيف الآن رابط يسمح للمستخدم بالانتقال إلى صفحة التعليقات مباشرةً من شريط التنقل، لذا سنفتح القالب الأساسي للتعديل عليه: (env) user@localhost:$ nano templates/base.html وسنعدّل محتويات الوسم <nav> بإضافة رابط جديد <a> إليه كما يلي: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %} {% endblock %} - FlaskApp</title> <style> nav a { color: #d64161; font-size: 3em; margin-left: 50px; text-decoration: none; } </style> </head> <body> <nav> <a href="{{ url_for('hello') }}">FlaskApp</a> <a href="{{ url_for('comments') }}">Comments</a> <a href="{{ url_for('about') }}">About</a> </nav> <hr> <div class="content"> {% block content %} {% endblock %} </div> </body> </html> استخدمنا الدالة المساعدة ()url_for للوصول إلى دالة فلاسك ()comments نحفظ الملف ونغلقه. وبذلك أصبح شريط التنقل يحتوي على رابط جديد ينقل المستخدم إلى صفحة التعليقات مباشرةً. وبذلك نكون قد تعلمنا كيفية استخدام العبارة الشرطية "if" في القوالب للتحكّم بما يُعرَض وفقًا لشروط معينة، كما استخدمنا حلقات "for" التكرارية للتنقل بين عناصر قوائم بايثون وعرض كل منها، وتعلمنا كيفية استخدام المتغير "loop" الخاص في جينجا، وسنستخدم في الخطوة التالية مرشّحات جينجا للتحكّم بكيفية عرض بيانات المتغير. الخطوة 5 – استخدام المرشحات سنتعلّم في هذه الخطوة كيفيّة استخدام مُرشحات جينجا في القوالب، إذ سنستخدم المُرشّح upper لتحويل كامل نصوص التعليقات التي أضفناها في الخطوة السابقة (أو الواردة من قاعدة البيانات في الواقع العملي) إلى حالة أحرف كبيرة، في حين سنستخدم المرشح join لربط عدّة سلاسل نصيّة لتصبح سلسلةً واحدة، كما سنتعرّف على كيفيّة تصيّير شيفرة HTML موثوقة وآمنة دون الحاجة لعزلها باستخدام المرشح safe. بدايةً سنعمل على تحويل التعليقات في صفحة التعليقات إلى حالة الأحرف الكبيرة، لذا سنفتح القالب "comments.html" للتعديل عليه: (env) user@localhost:$ nano templates/comments.html ثمّ سنعدله ليصبح كما يلي: {% extends 'base.html' %} {% block content %} <h1>{% block title %} Comments {% endblock %}</h1> <div style="width: 50%; margin: auto"> {% for comment in comments %} {% if loop.index != 2 %} <div style="padding: 10px; background-color: #EEE; margin: 20px"> <p>#{{ loop.index }}</p> <p style="font-size: 24px">{{ comment | upper }}</p> </div> {% endif %} {% endfor %} </div> {% endblock %} أضفنا مرشح upper باستخدام رمز | الذي يمثل أنبوبًا pipe، والذي سيعمل على تعديل قيمة متغير comment إلى حالة الأحرف الكبيرة. نحفظ الملف ونغلقه. وبعد التأكد من كون خادم التطوير ما يزال قيد التشغيل، ننتقل إلى صفحة التعليقات باستخدام المتصفح: http://127.0.0.1:5000/comments ونلاحظ أنّ جميع التعليقات أصبحت في حالة الأحرف الكبيرة بعد تطبيق المرشح، كما من الممكن تمرير وسطاء للمُرشّحات بين أقواسها. لتوضيح هذه النقطة: سنستخدم المُرشّح join لدمج جميع التعليقات الموجودة في القائمة comments ضمن سلسلة واحدة. لذا سنفتح قالب التعليقات: (env) user@localhost:$ nano templates/comments.html ونعدله كما يلي: {% extends 'base.html' %} {% block content %} <h1>{% block title %} Comments {% endblock %}</h1> <div style="width: 50%; margin: auto"> {% for comment in comments %} {% if loop.index != 2 %} <div style="padding: 10px; background-color: #EEE; margin: 20px"> <p>#{{ loop.index }}</p> <p style="font-size: 24px">{{ comment | upper }}</p> </div> {% endif %} {% endfor %} <hr> <div> <p>{{ comments | join(" | ") }}</p> </div> </div> {% endblock %} أضفنا في الشيفرة السابقة الوسم <hr> (الذي يُصيّر مثل فاصل أفقي)، والوسم <div> (الذي يُستخدم لأغراض التنسيق وتجميع العناصر)، إذ دمجنا جميع التعليقات الموجودة في القائمة comments باستخدام المُرشّح ()join. نحفظ الملف ونغلقه. وبتحديث صفحة التعليقات ستظهر كما يلي: نلاحظ عرض كافّة محتويات القائمة comments بحيث تكون التعليقات مفصولة عن بعضها برمز الشريط العمودي pipe وهي القيمة المُمررة وسيطًا إلى المُرشّح ()join. ومن المُرشّحات المهمّة الأُخرى المُرشّح safe الذي يساعد في تصيّير شيفرة HTML موثوقة في المتصفح، ولتوضيح ذلك سنضيف نصًا يحتوي على وسم HTML ما إلى قالب التعليقات (لنرى هل سيُصيّر في المُتصفّح أم سيُعامل على أنه نص عادي) باستخدام مُحدّد جينجا "{{ }}". نحصل في التطبيق العملي على هذا النص (التعليق) مثل متغير آتٍ من الخادم، ومن ثمّ سنعدّل وسيط المُرشّح ()join ليكون وسم <hr> (أي الفصل بين التعليقات بشريط أفقي) بدلًا من الشريط العمودي pipe. لذا سنفتح قالب التعليقات: (env) user@localhost:$ nano templates/comments.html ونعدّله ليصبح كما يلي: {% extends 'base.html' %} {% block content %} <h1>{% block title %} Comments {% endblock %}</h1> <div style="width: 50%; margin: auto"> {% for comment in comments %} {% if loop.index != 2 %} <div style="padding: 10px; background-color: #EEE; margin: 20px"> <p>#{{ loop.index }}</p> <p style="font-size: 24px">{{ comment | upper }}</p> </div> {% endif %} {% endfor %} <hr> <div> {{ "<h1>COMMENTS</h1>" }} <p>{{ comments | join(" <hr> ") }}</p> </div> </div> {% endblock %} أضفنا القيمة <h1>COMMENTS</h1> وغيرنا وسيط مُرشّح الدمج ليصبح وسم <hr>. نحفظ الملف ونغلقه. وبتحديث صفحة التعليقات تظهر صفحةٌ مشابهةٌ لما يلي: نلاحظ أنّ وسوم HTML التي أضفناها ضمن التعليقات لم تُصيَّر، وهي ميزة أمان مهمّة في جينجا، لأنّ وسوم HTML قد تكون ضارة أو خبيثة، ويمكن أن تؤدي إلى هجمات البرمجة العابرة للمواقع XSS. أمّا لتصيير وسوم HTML المُضافة السابقة نفتح ملف قالب التعليقات: (env) user@localhost:$ nano templates/comments.html ونعدله بإضافة المُرشّح safe، للدلالة على أنّ هذه الوسوم آمنة ونريد تصييّرها: {% extends 'base.html' %} {% block content %} <h1>{% block title %} Comments {% endblock %}</h1> <div style="width: 50%; margin: auto"> {% for comment in comments %} {% if loop.index != 2 %} <div style="padding: 10px; background-color: #EEE; margin: 20px"> <p>#{{ loop.index }}</p> <p style="font-size: 24px">{{ comment | upper }}</p> </div> {% endif %} {% endfor %} <hr> <div> {{ "<h1>COMMENTS</h1>" | safe }} <p>{{ comments | join(" <hr> ") | safe }}</p> </div> </div> {% endblock %} نلاحظ أنّه من الممكن ربط المُرشّحات كما هو ظاهر في السطر: <p>{{ comments | join(" <hr> ") | safe }}</p> إذ يُطبَّق كل مُرشّح على نتيجة خرج المُرشّح السابق له. نحفظ الملف ونغلقه. وبتحديث صفحة التعليقات نجد أن وسوم HTML قد جرى تصييّرها كما هو مُتوقّع مع استخدام المُرشّح "safe": تنبيه: قد يجعل تطبيق المُرشّح "safe" لشيفرة HTML غير موثوقة المصدر تطبيقنا عرضةً لهجمات البرمجة عابرة المواقع، لذا لا يُفضّل استخدامه إلّا إذا كانت شيفرات HTML المُراد تصييّرها موثوقة المصدر. تعرّفنا في هذه الخطوة على كيفيّة استخدام المُرشّحات في قوالب جينجا لتعديل قيم المتغيرات، وفيما يلي سنستخدم حزمة بوتستراب Bootstrap لتنسيق مظهر التطبيق وجعله أكثر جاذبية بصريًا. الخطوة السادسة – استخدام بوتستراب سنتعرّف في هذه الخطوة على كيفيّة استخدام حزمة بوتستراب لتنسيق مظهر التطبيق، إذ سنضيف شريط تنقّل في القالب الأساسي بحيث يظهر في كافّة الصفحات التي ترث شيفراتها منه. يساعد إطار العمل بوتستراب bootstrap على إضافة التنسيقات على التطبيق ليبدو أكثر جاذبية بصريًا، كما سيساعدنا على تمكين ميزة الصفحات المتوافقة مع المتصفحات في تطبيق الويب، ما يضمن عمله بصورةٍ جيدة في المتصفحات الخاصة بالجوال، دون كتابة شيفرات HTML و CSS وجافا سكربت JavaScript لتحقيق هذه الغاية. وحتّى نستخدم بوتستراب سنضيفه إلى القالب الأساسي بحيث يسهل استخدامه في جميع القوالب الأُخرى. لذا سنفتح القالب الأساسي "base.html" للتعديل عليه: (env) user@localhost:$ nano templates/base.html ونعدله كما يلي: <!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous"> <title>{% block title %} {% endblock %} - FlaskApp</title> </head> <body> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <div class="container-fluid"> <a class="navbar-brand" href="{{ url_for('hello') }}">FlaskApp</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item"> <a class="nav-link" href="{{ url_for('comments') }}">Comments</a> </li> <li class="nav-item"> <a class="nav-link" href="{{ url_for('about') }}">About</a> </li> </ul> </div> </div> </nav> <div class="container"> {% block content %} {% endblock %} </div> <!-- Optional JavaScript --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script> </body> </html> الجزء الأكبر من الشيفرة السابقة هو تعليمات لازمة لعمل بوتستراب، إذ تزوّد الوسوم <meta> متصفح الويب بالمعلومات، في حين ينشئ الوسم <link> ضمن القسم <head> ارتباطًا إلى ملفات CSS الخاصة ببوتستراب، وفي الجزء الأخير منه يُضمِّن الوسم <script> ارتباطًا إلى شيفرة جافا سكربت اختيارية. كما تتضمّن الشيفرة أجزاءً خاصةً بمحرك القوالب جينجا والتي قد وضّحناها فيما سبق، وكذلك استخدامًا لوسوم مُحدّدة وأصناف من CSS لتحديد كيفيّة عرض كل عنصر في بوتستراب. وقد استخدمنا في الشيفرة أعلاه وسم رابط <a> من الصنف navbar-brand الخاص بإضافة رابط العلامة المميزة (شعار الشركة مثلًا) إلى شريط التصفّح وذلك ضمن الوسم <nav> (الخاص بشريط التصفّح)، وفيه نحدّد رابط العلامة المطلوب، أمّا عن الروابط الاعتيادية مثل الروابط المؤدية إلى صفحات أُخرى من التطبيق، فمن الممكن تضمينها في الوسم <"ul class="navbar-nav> الحاوي على عنصر قائمة <li> ضمن عنصر روابط <a> وبالتالي من الممكن إضافة عدّة روابط. نحفظ الملف ونغلقه. وبعد التأكد من كون خادم التطوير ما يزال قيد التشغيل، ننتقل إلى الصفحة الرئيسية من التطبيق في المتصفح: http://127.0.0.1:5000/ فتظهر صفحةٌ مشابهةٌ لما يلي: وبذلك أصبح من الممكن استخدام مكونات بوتستراب لتنسيق مظهر العناصر في تطبيق فلاسك في جميع القوالب. الخاتمة تعرّفنا في هذا المقال على كيفيّة استخدام قوالب HTML في تطبيق فلاسك، إذ استخدمنا المتغيرات لتمرير البيانات من الخادم إلى القوالب مستفيدين من مفهوم وراثة القوالب لتجنُّب تكرار الشيفرات، كما استخدمنا عناصر مثل عبارات "if" الشرطية وحلقات "for" التكرارية، وربطنا بين صفحات مختلفة من صفحات التطبيق، كما تعرّفنا على كيفية تطبيق المُرشّحات لتعديل نص ما أو لعرض شيفرة HTML موثوقة، ونهايةً استخدمنا بوتستراب لتنسيق مظهر التطبيق. ترجمة -وبتصرف- للمقال How To Use Templates in a Flask Application لصاحبه Abdelhadi Dyouri. اقرأ أيضًا المقال التالي: كيفية التعامل مع الأخطاء في تطبيقات فلاسك Flask المقال السابق: تعلم بناء موقعك الإلكتروني الأول باستخدام إطار عمل فلاسك Flask بلغة بايثون استخدام أطر العمل في برمجة تطبيقات الويب: فلاسك نموذجا1 نقطة
-
يمكن ألّا تنفق شيئًا عند نشر موقع الويب الخاص بك أو يمكن أن تتخطى الميزانية المحددة، ولهذا يمكن أن تتساءل كم سيُكلفك بناء موقع ويب كامل؟ وكيف ستجني ما أنفقته؟ سنستعرض في هذا المقال عملية تطوير موقع ويب بأكمله وحساب التكلفة المادية المتوقعة لكل خطوة، فيمكن ألّا يكون دخولك عالم الويب رخيصًا كما تعتقد. قبل الشروع في قراءة هذا المقال عليك أن تطلع على الفرق بين صفحة الويب وخادم الويب وغيرها من المصطلحات، كما عليك أن تكون على دراية بمفهوم أسماء النطاقات. البرمجيات سنتعرف في الفقرات القادمة على بعض البرمجيات الأساسية التي تحتاجها لتطوير موقع ويب والتكلفة المادية لها. محررات النصوص من المرجح أنك تملك محرر نصوص مثل المفكرة Notepad في ويندوز أو جي-إدت Gedit في لينوكس أو محرر النصوص TextEdit في ماك أو إس. لكن استخدام محرر نصوص يلوّن الشيفرات ويتحقق من صحتها قواعديًا ويساعدك في تنظيمها سيريحك ويسهِّل تطوير المواقع. يمكنك الحصول على الكثير من محررات النصوص مجانًا مثل: Atom. Brackets. Bluefish. TextWrangler. Eclipse. Netbeans. Visual Studio Code. كما يمكنك اختبار Sublime Text المدة التي تشاء لكنه سيظهر لك رسائل تشجعك على شراءه بينما يكلفك PhpStorm ما بين 20 إلى 200 دولار وفقًا للخطة التي تحتاجها. يحصل المطورون الأفراد أو مطوري المشاريع مفتوحة المصدر على Visual Studio Express مجانًا. وعادة ما تحصل على فترة تجريب مجانية للمحررات المدفوعة. ننصحك كبداية أن تجرب عدة محررات لتقرر ما يناسبك منها. كما ننصحك باستخدام محرر بسيط إن كنت ستكتب ملفات HTML وCSS وجافاسكربت بسيطة. لا يعكس ثمن المحرر جودته بالضرورة، عليك أن تجرب هذا المحرر وتقرر بنفسك إن كان يلبي احتياجاتك. يعدّ محررًا Sublime Text رخيص الثمن لكنه يأتي مع الكثير من الإضافات المجانية التي توسّع قدراته كثيرًا. محررات الصور من المرجح أن يزوّدك نظام التشغيل الذي تستخدمه بمحرر أو مستعرض صور بسيط مثل Paint في ويندوز وبرنامج Eye of Gnome في أوبونتو وبرنامج Preview في ماك. وبالطبع فهي برمجيات محدودة نسبيًا وسرعان ما تحتاج إلى محررات صور أكثر قوة لإضافة الطبقات والتأثيرات والمجموعات. يمكن أن تكون هذه المحررات مجانية مثل GIMP أو بتكلفة معقولة أقل من 100 دولار مثل PaintShop Pro أو بتكلفة عالية نسبيًا مثل أدوبي فوتوشوب Adobe Photoshop. اختر أيًا من تلك المحررات فهي تقدم وظائف متشابهة. وبالرغم من أنّ بعضها يشمل الكثير من الميزات، لكنك لن تستخدمها كلها. اطلع على الأدوات التي يستخدمها المطورون الآخرون إن كنت ستتبادل المشاريع معهم في مرحلة ما. إذ يمكن لجميع المحررات تصدير المشاريع المنجزة على شكل ملفات بتنسيقات معيارية لكنها تخزّن المشاريع التي لا تزال تحت التطوير بتنسيقات خاصة. تتمتع معظم الصور على الإنترنت بحقوق نشر، لذا عليك التحقق من رخصة استخدام الصورة قبل استخدامها. تزوّدك بعض المواقع مثل Pixabay بصور تحمل الرخصة CC0 لذا يمكنك استخدامها وتعديلها ونشرها بشكلها المعدّل لأغراض تجارية. محررات الوسائط إن أردت إضافة مقاطع فيديو أو مقاطع صوتية إلى موقعك، يمكنك تضمين خدمات ويب موجودة مثل يوتيوب YouTube أو ديلي موشن Dailymotion أو فيميو Vimeo أو تضمين مقاطع فيديو خاصة بك (تحقق من تكلفة عرض الحزمة التي سترد لاحقًا في المقال). يمكنك استخدام برامج مجانية للعمل مع المقاطع الصوتية (مثل Audacity وWavosaur) أو مدفوعة بتكاليف يمكن أن تصل لمئات من الدولارات (مثل Sony Sound Forge وAdobe Audition). وكذلك الأمر مع محررات الفيديو إذ يمكنك استخدام المحررات مجانية مثل PiTiVi وOpenShot لنظام التشغيل لينوكس وبرنامج iMovie لنظام التشغيل ماك أو إس أو يمكنك استخدام محررات معتدلة التكلفة أقل من 100 دولار مثل Adobe Premiere Elements أو بتكلفة تصل إلى مئات الدولارات (مثل Adobe Premiere Pro وAvid Media Composer وFinal Cut Pro. وغالبًا ما يغطي محرر الفيديو الذي يأتي مع كاميرتك الرقمية كل احتياجاتك. أدوات نشر المواقع ستحتاج إلى وسيلة لرفع ملفات موقعك من القرص الصلب على حاسوبك إلى خادم الويب، لذلك تساعد بعض أدوات النشر مثل S)FTP client) أو RSync أو Git/GitHub في إنجاز الأمر. يحتوي كل نظام تشغيل على برنامج عميل S)FTP) كجزء من مدير الملفات مثل Windows Explorer في ويندوز وNautilus وهو مدير ملفات شائع في أنظمة التشغيل لينوكس وMac Finder في ماك أو إس. يختار المطورون عادة برامج S)FTP) مخصصة لاستعراض المجلدات الموجودة على الحاسوب أو الخادم بشكل متجاور وتخزين كلمات مرور الخادم. هناك العديد من الخيارات الموثوقة والمجانية إن أردت أن تثبّت برنامج عميل S)FTP) مثل FileZilla لكل المنصات وWinSCP لنظام التشغيل ويندوز وCyberduck لكل من ويندوز وماك وغيرها الكثير. إنّ بروتوكول FTP غير آمن بطبيعته لذلك تأكد من استخدام SFTP وهي النسخة الآمنة المشفّرة من FTP التي تتعامل معها معظم مزودات الخدمة هذه الأيام افتراضيًا. يمكنك بالطبع استخدام تقنيات آمنة أخرى مثل Rsync مع SSH. المتصفحات إما أن يكون لديك بالفعل متصفح أو يمكنك تحميل أي متصفح مجاني مثل فايرفوكس أو كروم. الولوج إلى ويب سنتعرف الآن على التجهيزات والخدمات الأساسية التي تحتاجها لدخول ويب. حاسوب ومودم يتطلب بناء ونشر موقع ويب إلى حاسوب بتكلفة تختلف بشدة وفقًا لميزانيك ومكان إقامتك. فإن أردت نشر موقع بسيط ستحتاج إلى حاسوب بسيط قادر على تشغيل محرر ومتصفح ويب وبالتالي ستكون تكلفته قليلة عند هذا المستوى. لكن إن أردت إنتاج تصاميم أكثر تعقيدًا لموقعك تضم صورًا مؤثرة أو أن تنتج مقاطع فيديو أو مقاطع صوتية فستحتاج إلى حاسوب أفضل. تحتاج أيضًا إلى رفع الملفات إلى خادم بعيد لذلك لا بدّ من وجود مودم Modem. يمكن لمزود خدمة الإنترنت ISP أن يمنحك اتصالًا بالإنترنت مقابل بضعة دولارات شهريًا ولكن يختلف الميزانية وفقًا لمكان إقامتك. الولوج إلى مزود خدمة انترنت تأكد من أنك تستخدم حزمة اتصال (أو حيز نطاق تراسلي) bandwidth كافي: يمكن أن يكون الولوج إلى مزود الخدمة عبر حزمة اتصال منخفضة ملائمًا لدعم موقع ويب بسيط يضم صورًا بأحجام معقولة ونصوصًا وبعض ملفات التنسيق CSS وبعض ملفات جافاسكريبت، وسيكلفك ذلك بضع عشرات من الدولارات شهريًا بما في ذلك أجرة المودم. ستحتاج في المقابل إلى حزمة اتصال عريضة مثل DSL أو خدمة الكابل أو الولوج عبر الألياف الضوئية (فايبر) إن أردت موقعًا أكبر يضم مئات الملفات، أو إن أردت تزويد متابعيك بملفات فيديو أو صوت بأحجام عالية. يمكن ألا يكلفك الأمر أكثر من كلفة الحزمة المنخفضة ويمكن أن تصل التكاليف إلى مئات الدولارات شهريًا لأغراض أكثر احترافية. استضافة موقع ويب نناقش في الفقرات القادمة ما تحتاجه من خدمات لرفع موقع على ويب وتكلفة هذه الخدمات. مفهوم عرض حزمة الاستهلاك تتعلق الكلفة التي تتقاضاها مزودات الخدمة لاستضافة موقعك بعرض الحزمة التي يستهلكها الموقع. يعتمد الأمر على عدد الأشخاص الذين يزورون موقعك وعدد روبوتات ويب التي تدخل إلى موقعك لتوثيقه خلال فترة زمنية معينة، بالإضافة إلى المساحة التخزينية التي تستهلكها ملفاتك. لهذا السبب يخزن الأشخاص مقاطع الفيديو الخاصة بهم ضمن خوادم تقدم خدمات مخصصة لهذا الأمر مثل يوتيوب وديلي موشن وفيميو. يمكن أن يقدم لك مزود الخدمة عرضًا يسمح بدخول عدة آلاف من المستخدمين يوميًا وبمقدار تبادل بيانات (عرض حزمة استهلاك) معقول، ولكن يجدر بك الانتباه إلى أن ما ذكرناه سيُفسَّر بصورة مختلفة من مزود خدمة استضافة إلى آخر. وكقاعدة أساسية توقع أن تكلفك استضافة موثوقة لاستخدام شخصي ما بين 10 إلى 50 دولار شهريًا. أسماء النطاقات لا بد من شراء اسم نطاق خاص بك من خلال مزود خاص (شركة مُسجِّلة Registart أو مسجِّل)، ويمكن أن يكون مزود خدمة الاستضافة هو أيضًا مُسجّلًا (أي الشركة تقدم خدمة حجز النطاقات والاستضافة). سيكلّفك تسجيل اسم نطاق عادةً ما بين 5-15 دولار سنويًا، وتختلف هذه الكلفة للأسباب التالية: التزامات محلية: اختيارك لأسماء نطاقات عليا تحمل اسم دولة (مثل uk.) أكثر تكلفة وتختلف من دولة لأخرى. الخدمات المرتبطة باسم النطاق: تزودك بعض الشركات المسجِّلة بخدمات مثل الحماية من الإزعاجات عن طريق حجب عنوانك البريدي وعنوان بريدك الإلكتروني خلف عناوينهم الخاصة. فلن يستسطع أحد الوصول إلى عنوانك البريد إلى عن طريق الشركة المسجلّة بينما تحجب بريدك الإلكتروني وفق آلية التقنيع التي يعتمدها المُسجِّل. استضافة موقعك بنفسك أو باستخدام خدمات الاستضافة المدفوعة بإمكانك نشر موقعك بنفسك خطوة خطوة كأن تجهز قاعدة بيانات (عند الحاجة) ونظام إدارة المحتوى CMS مثل (ووردبريس Wordpress أو دوت كلير Dotclear أو spip وغيرها) وترفع قوالب المحتويات الجاهزة أو قوالبك الخاصة. كما يمكنك استخدام بيئة التشغيل الخاصة بمزود الاستضافة مقابل 10-50 دولار شهريًا، أو أن تشترك مباشرة بمزود استضافة مخصص له نظام إدارة محتوى جاهز مثل ووردبريس Wordpress أو تمبلر Tumblr أو بلوغر Blogger). لن يكلف هذا الأخير أي شيء حرفيًا، لكنك لن تكون قادرًا على التحكم الكامل بالقوالب وغيرها من الخيارات. الاستضافة المجانية مقابل الاستضافة المدفوعة يمكن أن يخطر في ببالك أنه لم عليك أن تدفع مقابل خدمة استضافة بالرغم من وجود العديد من عروض الاستضافة المجانية؟ إليك بعض المميزات للاسضافات المدفوعة: لديك حرية أكبر عندما تدفع. سيكون موقعك ملكك، وبإمكانك نقله بسلاسة من مزود خدمة إلى آخر. يمكن أن يضيف مزودي الخدمة المجانية إعلانات إلى محتوى موقعك دون أن تتحكم بذلك. يمزج البعض بين المقاربتين السابقتين، إذ يستضيفون مثلًا المدونة الرئيسية على مزود استضافة مدفوعة وباسم نطاق مستقل وخاص بالكامل، بينما يرفعون المحتوى الأقل أهمية إلى مزود استضافة مجانية. تصميم مواقع ويب والاستضافة الاحترافية عن طريق شركات خاصة إن أردت موقع ويب احترافي فيمكن أن ترغب بتوكيل المهمة لوكالة خاصة وبالتالي ستتغير التكلفة بناء على عوامل عدة مثل: هل الموقع بسيط مكون من عدة صفحات نصية؟ أم أنه أكثر تعقيدًا ويتكون من ألف صفحة مثلًا؟ هل تريد تحديث محتواه بانتظام؟ أو سيكون موقع ويب ساكن. هل ينبغي ربط الموقع بمنظومة المعلومات الخاصة بشركتك لجمع محتوى معين (مثل البيانات الداخلية)؟ هل تريد بعض الميزات الجديدة البرّاقة التي تمثل الموضة الحالية؟ حاليًا يطلب العملاء مواقع من صفحة واحدة ذات مظهر مركب. هل ترغب أن تتولى الوكالة أمر مشاكل المستخدمين أو حل مشاكل تتعلق بتجربة المستخدم UX؟ كأن تضع لك استراتيجية لتشجيع المستخدمين أو تصميم تجربة لاختيار حل من بين عدة خيارات. فيما يتعلق بالاستضافة ستتغير التكلفة بحسب عدة عوامل منها: هل تريد خوادم احتياطية في حال توقف الخادم الأساسي عن العمل؟ هل تكفي وثوقية أداء 95% أم أنك تحتاج إلى 99% وخدمة مستمرة على مدار الساعة؟ هل تريد خادمًا مخصصًا Dedicated Server عال المواصفات فائق التجاوب أم يكفيك خادم مشترك أبطأ؟ اعتمادًا على إجاباتك على كل سؤال سيكلفك الموقع من بضع آلاف وحتى مئات آلاف الدولارات. اطلعنا في هذا المقال على التكلفة المادية لبناء موقع ويب في كل خطوة من خطوات بنائه حتى نشره، وحان الوقت لتبدأ تصميم مواقع ويب وإعداد بيئة العمل المناسبة لك. ترجمة -وبتصرف- للمقال How much does it cost to do something on the Web. اقرأ أيضًا مفهوم الروابط التشعبية في مواقع الويب ما هو عنوان URL في الويب؟ ما هي الأدوات المستخدمة في بناء مواقع ويب؟ ما هي أدوات مطوري الويب المدمجة في المتصفحات؟1 نقطة
-
مقدّمة بعد أن تعرّفنا على بنية التّطبيق الذي سنبنيه سويا، سنبدأ بتهيئة وتنصيب بعض الحزم التّي سنعتمد عليها، وسنرى كيف يُمكننا تنظيم الملفّات لمرونة أكثر في التّعامل مع المشاريع الكبيرة، فعوضا عن وضع الشيفرة كاملة في ملفّ أو ملفّين، سنقوم باستعمال مبدأ المُخطّطات Blueprints الذي يوفّره لنا إطار العمل فلاسك لتنظيم التّطبيقات الأكثر تعقيدا. بنية التّطبيق المُعتادة سابقا، كنّا نستعمل ملفّا رئيسيّا واحدا ونقوم بتشغيله ليعمل الخادوم ونتمكّن من الوصول إلى التّطبيق عبر المُتصفّح من العنوان المُعتاد، وهكذا تكون جميع الموجّهات في ملفّ واحد، والملفّات السّاكنة في مجلّد واحد، وملفّات القوالب (ملفّات HTML) تكون جميعها في نفس المُجلّد. ملفّات التّطبيق المعتادة تكون على الشّكل التّالي: ├── app.py # ملفّ التّطبيق الرّئيسي ├── config.py # ملفّ الإعدادات ├── static # مجلّد الملفّات السّاكنة │ ├── css │ │ └── style.css │ ├── img │ │ └── logo.png │ └── js │ └── main.js ├── templates # مجلّد القوالب │ ├── index.html │ ├── posts.html مادام التّطبيق بسيطا فكلّ شيء سيكون على ما يرام، لكن ماذا لو كان التّطبيق يمتلك قسما لتسجيل المُستخدمين، عرض صفحاتهم الشّخصيّة، عرض المقالات، صفحات الأخطاء (مثل عدم تواجد صفحة أو خطأ بالخادوم …)، لوحة تحكّم للمُدير، لوحات التّحكم بأجزاء التّطبيق، واجهة برمجيّة للمُطوّرين API وغير ذلك من الخصائص التّي يتمتّع بها كل تطبيق كبير ذو وظائف مُتعدّدة. إن استعملت البنية المُشار إليها سابقا، ستواجه العديد من المشاكل، أولا سيكون الملفّ الرّئيسي مليئا بالموجّهات والدّوال، وقد يصل إلى آلاف الأسطر البرمجيّة ما سيجعل مهمّة الصّيانة وإضافة خصائص جديدة أمرا صعبا، كما أنّ ملفّات القوالب ستكون مجتمعة في مجلّد واحد، وإن كنت تعمل على تطوير التّطبيق مع فريق من المُطوّرين فسيجد كل شخص نفسك أمام ملفّات وشيفرات لا علاقة له بها، مثلا لو قُسّمت المهام بحيث يعمل كلّ مطوّر على قسم معيّن من التّطبيق، زيد هنا يعمل على نظام تسجيل للمُستخدمين، وعامر يعمل على إضافة قسم لعرض آخر التّعليقات المُضافة، وسعيد، مُصمّم الويب يعمل على تصميم صفحات أخطاء جميلة، وعبد القادر يعمل على لوحة تحكّم الإدارة، فكيف يُمكن لزيد أن يُعدّل الشيفرة التّي تقوم بتسجيل المُستخدمين دون المساس بالشّيفرة التّي تقوم بإعداد المقالات لعرضها على صفحة المقالات؟ المُخطّطات Blueprints المُخطّطات في فلاسك نظام لتجميع الموجّهات المُخصّصة لوظيفة مُعيّنة بعيدا عن المُوجّهات الأخرى، يُمكن كذلك تقسيم ملفّات القوالب والملفّات السّاكنة كذلك مع إتاحة خيار مُشاركة ملفّات مُحدّدة إن أردت ذلك. في هذا المشروع سنضع مجلّد قوالب لكلّ وظيفة، أمّا مُجلّد الملفّات السّاكنة فسيكون مُشتركا بين جميع القوالب، وهذا لأنّنا لن نحتاج إلى الكثير من ملفّات جافاسكريبت وملفّات css، وستكون الصّور مُشتركة كذلك. هناك نوعان معروفان من المُخطّطات، النّوع الأول يُقسّم ملفّات القوالب مع كلّ وظيفة ليكون كالتّالي: . ├── run.py ├── config.py ├── project │ ├── __init__.py │ ├── posts │ │ ├── __init__.py │ │ ├── templates │ │ │ ├── index.html │ │ │ ├── post.html │ │ │ ├── posts_by_category.html │ │ ├── views.py │ ├── static │ │ └── css │ │ └── style.css │ ├── templates │ │ ├── base.html │ └── users │ ├── __init__.py │ ├── templates │ │ ├── login.html │ │ └── register.html │ ├── views.py أمّا النّوع الثّاني فتجتمع فيه جميع ملفّات HTML في مُجلّد واحد كما يلي: . ├── run.py ├── config.py ├── project │ ├── __init__.py │ ├── posts │ │ ├── __init__.py │ │ ├── views.py │ └── users │ ├── __init__.py │ ├── views.py │ ├── templates │ │ ├── base.html │ │ ├── posts/ │ │ ├── users/ │ ├── static │ │ └── css │ │ └── style.css في المثالين السّابقين، لدينا مُخطّطان، مُخطّط خاصّ بالمقالات تحت مجلّد posts، وآخر خاصّ بالمُستخدمين في مجلّد users، ملفّ run.py مسؤول عن تشغيل التّطبيق وأمّا ملفّات __ini__.py فهي لجعل بايثون يفهم بأنّ كلّا من مجلّد المشروع project ومجلّدي المقالات والمُستخدمين عبارة عن حزم. أمّا ملفّا views.py فسيحتويان على الموجّهات المعنيّة بكلّ وظيفة، فمثلا مُوجّه عرض المقالات “/posts” سيكون في ملفّ posts/views.py أمّا موجّه تسجيل دخول المُستخدمين /login فسيكون في ملفّ users/views.py. لإخبار فلاسك بأنّ مجلّدي posts و users عبارة عن مُخطّطات، سنعرّف أولا كائنًا من صنف Blueprint في كل من ملفّات __init__.py في المُجلّدين، وبعدها سنقوم بتسجيلهما مع تطبيقنا الذي نُعرّفه في ملفّ __init__.py الأساسي -وهو المُتواجد في مجلّد project-. لك حريّة استخدام أي نمط تُريده، ففي النّهاية إطار فلاسك مُصمّم ليُوفّر لك كامل الحريّة في طريقة تنظيمك لملفّات التّطبيق، لكن اتّباع نمط مُتعارف عليه أفضل في مُعظم الحالات. سنستخدم في مشروعنا النّمط الأول، أي أنّ ملفّات HTML ستكون منفصلة حسب الوظيفة. بايثون 3 سنستعمل في إنشائنا لهذا التّطبيق النّسخة 3 من لغة بايثون، لن يتغيّر الكثير، فالاختلاف بين Python 2 و Python 3 بسيط جدا، وسأقوم بذكر أهم الاختلافات أثناء بناء التّطبيق في الدّروس القادمة. إذا كنت لا تزال تعتمد على بايثون 2 فأنصحك بأن تنتقل إلى بايثون 3 لأنّ الدّعم لهذه الأخيرة قد أصبح كبيرا ومُعظم مُطوري بايثون يستعملونها الآن، كما أنّها أحدث نُسخة. إذا أردت أن تتعلم كيفيّة تجهيز بايثون 3 على نظامك، يُمكنك اتّباع هذا الدّرس. تطبيق كلمة بما أنّ مشروعنا عبارة عن نظام لإدارة المُحتوى، قرّرت تسميّته “كلمة”، جميع الملفّات والمجلّدات الخاصّة بالتّطبيق ستكون بداخل مجلّد باسمkalima، لذا عليك إنشاؤه الآن في المكان المُفضّل لديك، المهم أن تعرف كيفيّة الوصول إليه عن طريق سطر الأوامر. في البداية، سننشئ الملفّات التّاليّة: . ├── run.py ├── project │ ├── __init__.py │ ├── posts │ │ ├── __init__.py │ │ ├── templates │ │ │ ├── posts.html │ │ ├── views.py │ ├── static │ │ └── css │ │ └── style.css │ ├── templates │ │ ├── base.html │ └── users │ ├── __init__.py │ ├── templates │ │ ├── users.html │ │ ├── login.html │ ├── views.py يُمكنك إمّا إنشاء المُجلّدات والملفّات يدويّا أو عبر نسخ الشيفرة التّالية وحفظها في ملفّ باسم create_app.py لإنشاء الملفّات والمُجلّدات باستعمال لغة بايثون تلقائيّا. import os import sys def mkapp(app_name, blueprints): dirs = ['{}', '{}/static', '{}/static/css', '{}/templates'] static_files = ['{s}/css/style.css'] templates_files = ['{t}/index.html', '{t}/base.html'] for d in dirs: os.mkdir(d.format(app_name)) open(app_name + '/' + "__init__.py", "w").close() # project/__init__.py for b in blueprints: os.mkdir(app_name + '/' + b) # project/posts os.mkdir(app_name + '/' + b + '/templates') # project/posts/templates open(app_name + '/' + b + '/' + "views.py", "w").close() # project/posts/views.py open(app_name + '/' + b + '/' + "__init__.py", "w").close() #project/posts/__init__.py open(app_name + '/' + b + '/templates/' + b + ".html", "w").close() # project/posts/templates/index.html for sf in static_files: static_file = app_name + '/' + sf.format(s='static') # project/static open(static_file, 'w').close() for tf in templates_files: templates_file = app_name + '/' + tf.format(t='templates') # project/templates open(templates_file, 'w').close() if __name__ == '__main__': app = sys.argv[1] blueprints = sys.argv[2:] mkapp(app, blueprints) يُمكنك تنفيذ السكربت بالأمر التّالي: $ python3 create_app.py project posts users بعدها أنشئ ملفّ login.html في مجلّد project/users/templates لأنّ السكربت لن يقوم بإنشائه. عليك كذلك إنشاء ملفّي run.py وconfig.py داخل مُجلّد kalima، الملفّ الأول مسؤول عن تشغيل الخادوم/ أمّا الملفّ الثّاني فمسؤول عن إعدادات التّطبيق. خاتمة تعرّفنا في هذا الدّرس على بنية التّطبيق الذي سنبنيه وكيفيّة توزيع ملفّاته إذ أنشأنا المُجلّدات والملفّات التّي ستكون مسؤولة عن الجانب العملي للتّطبيق، في الدّرس القادم، سنبدأ بتجهيز البيئة البرمجيّة وتنصيب أهم الحزم التّي سنحتاج إليها للبدء بتطوير التّطبيق.1 نقطة