لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 03/12/17 في كل الموقع
-
مقدّمة بعد أن ألقينا نظرة على كيفيّة استخدام إطار العمل Flask لإنشاء تطبيقات ويب بسيطة بالاستعانة بقاعدة بيانات SQLite، سنبدأ هذه السّلسلة بالدّخول إلى عالم إضافات Flask التّي ستسهّل علينا الكثير من المهام كإعداد نظام لتسجيل الدّخول والخروج، والتّعامل مع نظام قاعدة بيانات، وكذلك التّحكم في تطوير التّطبيق عن طريق سطر الأوامر؛ وكذلك استعمال أدوات لتطوير تطبيق أكثر أمانا. سنتطرّق أيضا إلى بعض المفاهيم المتقدّمة كتشفير كلمات المرور وتهجير قواعد البيانات وغير ذلك. صحيح بأنّ هذه السّلسلة مطولة نوعا ما إلا أنّها ستكون شاملة لمُساعدتك على تطوير أي تطبيق يمر على خاطرك أو يطلبه منك أحد عملائك. وإن كنت جديدا إلى عالم تطوير الويب فستتعلّم من هذه السّلسلة ما يكفي لتبدأ مشوار العمل كمطوّر تطبيقات ويب سواء عن طريق إنجاز مشاريع لعملاء على منصّات العمل الحر كمنصّة مُستقل أو بناء مشاريعك الخاصّة. سنقوم في هذا الدّرس بالتّعرف على فكرة وبنية التّطبيق الذي سنبنيه في رحلتنا هذه. المُتطلّبات بالإضافة إلى أساسيّات إطار العمل Flask، ستحتاج كذلك إلى معرفة كيفيّة التّعامل مع نماذج HTML عبر مكتبة WTForms وإضافة Flask-WTF ويُمكنك الاطّلاع على سلسلة دروس خاصّة بهذا الموضوع على الأكاديميّة. سلاسل الدّروس التّي يجب عليك أن تطّلع عليها لفهم أفضل لهذه السّلسلة من الدّروس المُتقدّمة نوعا ما، عليك أن تطّلع وتطبّق سلاسل الدّروس التّاليّة: سلسلة مدخل إلى إطار العمل Flask درس إنشاء تطبيق لاختصار الرّوابط باستخدام إطار العمل Flask بجزئيه الأول و الثاني. سلسلة التّحقق من مُدخلات المُستخدم باستخدام مكتبة WTForms وإضافة Flask-WTF ستكون لغة جافاسكربت مُفيدة كذلك، ولا مفرّ من إتقانها إن كنت ترغب بأن تُصبح مُطور ويب أفضل، كما أنّني لن أشرح كل كبيرة وصغيرة عند التّعامل معها في التّطبيق، وهذا لأنّ الهدف من السّلسلة هو تعليمك كيفيّة إتقان التّعامل مع إطار العمل فلاسك وهذا بالطّبع لا يشمل شيفرة جافاسكربت. ستحتاج كذلك إلى تعلّم أداة Git لإدارة نُسَخ التّطبيق والتّعامل مع التّطبيق بعد نشره على منصّة Heroku. ما الذي ستتعلّمه من هذه السّلسلة؟ ستتعلم في هذه السّلسلة تقنيات متقدّمة لإدارة مشاريع تطبيقات الويب، وكيفيّة التّعامل مع قاعدة بيانات PostgreSQL وأداة SQLAlchemy لإدارة الجداول (إضافة، قراءة، تعديل وحذف البيانات)، وكذلك الطرق البسيطة لتهجير قواعد البيانات Database Migration وستتعرّف كذلك على طرق توزيع ملفّات التّطبيق على شكل وحدات وحزم لتنظيم أكثر. سنستخدم كذلك مكتبة WTForms لإدارة نماذج HTML وجعلها أكثر أمانًا للحماية من هجمات مُحتملة من المُخرّبين والمُخترقين. وسنعد كذلك نظامًا أكثر أمانًا لتسجيل الدّخول واستيثاق المُستخدمين، وسنتطرّق كذلك إلى كيفيّة نشر التّطبيق إلى منصّة Heroku لتربطه بعد ذلك باسم نطاق خاصّ إن أردت ذلك. ستتعلّم كذلك طريقة حماية كلمات المرور عن طريق تشفيرها في قاعدة البيانات باستعمال خوارزميّة Bcrypt للتّشفير، وذلك لتجنّب حفظها كنصّ مجرّد يسهل استخدامه من طرف المُخترق إذا وصل إلى قاعدة البيانات. وقد تعرّفنا سابقًا على كيفيّة استعمال الجلسات Sessions لإنشاء نظام تسجيل دخول وخروج بسيط، صحيح بأنّ ذلك النّظام يعمل بشكل جيّد، إلّا أنّه لا يعد آمنًا، ويُمكن أن يتعرّض تطبيقنا لهجمات كثيرة من قبل المُخترقين، ولحماية العضويات والبيانات في الموقع، سيتوجّب علينا أن نُدير الجلسات بطريقة أكثر تعقيدًا، لكنّ هناك إضافة لإطار العمل فلاسك لتبسيط هذا الأمر ولن نحتاج إلى العمل على ذلك بأنفسنا، وبالتّالي فسيُصبح تطبيقنا أكثر أمانًا دون عناء كبير، وكلّ هذا وأكثر سنتعلّمه بتفصيل أكبر في الدّروس القادمة. بنية التّطبيق التّطبيق الذي سنعمل عليه في هذه السّلسلة من الدّروس عبارة عن نظام إدارة محتوى ومنصّة للتّدوين الجماعي، ستكون هناك بعض الميّزات الفريدة وستكون هناك ميّزات أخرى مفقودة، إذا سبق لك وأن تعاملت مع أحد أنظمة التّدوين الأخرى كمنصّة ووردبريس WordPress، Blogger أو Tumblr أو حتى منصّة medium فستتمكّن بنهاية هذه السّلسلة من التّخلي عن هذه المنصّات وإنشاء منصّة بسيطة خاصّة بك لتكتب عليها، أو تستطيع تعديل المشروع بعد الانتهاء منه لتُضيف ميّزات أخرى أو تُطبّق فكرة فريدة لتطرح مشروعًا على أرض الواقع لتتمكّن من الاستفادة منه ماديّا إن أردت ذلك. سيتمكّن مُستخدمو المنصّة من إنشاء حساب خاصّ بهم لينشروا مقالاتهم التّي يكتبونها، إضافة المقالات ستتمّ عن طريق كتابتها بتنسيق الماركداون Markdown ومن ثمّ نشرها، سيتمكّن كلّ مُستخدم من الحصول على رابط خاصّ بمقالاته لنشرها للآخرين، سيتمكّن الكاتب من إضافة وسوم لمقالاته، وكذلك إدراجها ضمن قسم معيّن، لكل مقالة قسم للتّعليقات ليتمكّن المُستخدمون الآخرون من التّعليق على مقال معيّن. سيكون للتّطبيق نكهة اجتماعيّة، بحيث سيتمكن المُستخدمون من مُتابعة بعضهم البعض، وكذلك إضافة مقالات إلى المُفضّلة والإعجاب بها لنتمكّن من فرزها وترتيبها حسب الأكثر إعجابًا، الأكثر نشاطًا (أكبر عدد من التعليقات) وبعدها ستتمكّن من إضافة خاصيّات أخرى بنفسك باتّباع نفس الطّريقة، مثلًا بعد الانتهاء من التّطبيق ستتمكّن من تطبيق فكرة ترتيب المقالات حسب الأكثر إعجابًا لإضافة خاصيّات أخرى (الأكثر شعبيّة حسب عدد التّعليقات، الأكثر زيارة...). صحيح بأنّنا سنبني تطبيقًا مُعقّدا وكبيرًا، إلّا أنّني لن أشرح كلّ شيء بتفصيل ممل، سأشرح بالتّفصيل فقط الأفكار الجديدة وما تراه لأوّل مرّة حتى لا تكون هذه السّلسلة أطول من اللازم، خاصّة وأنّ بعض الأساليب ستكون مُشابهة جدّا لبعضها البعض، فمثلاً طريقة السّماح للمُستخدم بإضافة مقال خاص به مُشابهة جدّا لطريقة فرز المقالات حسب قسم مُعيّن (لكل مُستخدم مقالاته ولكلّ قسم مقالاته كذلك). سنضع للتّطبيق بعض الميّزات المُفيدة كنظام أرشفة لتأريخ كلّ مقال حسب تاريخ إضافته، كما سيكون لتعليقات المقال نظام مُشابه، وسنستغل نفس الطّريقة لتخصيص تاريخ انضمام للمُستخدم. في النّهاية، تذكّر بأنّ هذه السّلسلة من الدّروس ستكون تطبيقيّة بالدّرجة الأولى، وستتعلّم فيها كيفيّة بدء مشاريعك التّطويريّة الخاصّة بك بلغة بايثون وإطار فلاسك، أمّا كيفيّة الاستفادة القصوى منها فمعروفة، عليك تطبيق ما تعلّمته وتختبر مع إضافة ميّزات ولو لم أذكرها، وإن أردت معرفة معمّقة عن أي شيء تحدّثت عنه دون أن أفصّل، يُمكنك دائما العودة إلى التّوثيق الرّسمي للأدوات والمكتبات والإضافات المعنيّة بالأمر، وإن كان لك سؤال معيّن فلا تتردّد في طرحه على قسم الأسئلة والأجوبة على الأكاديميّة. هناك المزيد الدّروس التّي ستندرج تحت هذه السّلسلة لن تُغطي فقط ما قرَأتَهُ للتّو، بل أكثر من ذلك، فهدفي من كتابة سلسلة الدّروس هذه هو تغطيّة الفراغ الموجود في الويب العربي، إذ أنّ التّوثيقات الرّسميّة للمكتبات وأطر العمل المُستعملة حاليّا عادة ما تكون مكتوبة باللغة الانجليزيّة فقط، لذا بتوفير سلسلة دروس كهذه ستمتلك أكبر قدر مُمكن من المُساعدة لتتمكّن من العمل على تطبيقاتك الخاصّة دون أن تضطر إلى اتّباع سلسلة دروس أخرى أو الاطّلاع على التّوثيقات الرّسميّة التّي عادة ما تكون مُفيدة أكثر إذا ما أردت أن تُنجز شيئًا بسيطًا، وعلى العكس من ذلك، فكتابة تطبيق كامل (كما في هذه السّلسلة) طريقة أفضل للتّعلم. ختاما هذا المقال عبارة عن مُقدّمة بسيطة لما سنخوضه في قادم الدّروس، في الدّرس القادم، ستبدأ المُتعة مع استكشاف كيفيّة التّعامل مع ملفّات ومُجلّدات التّطبيقات الكبيرة والمُعقّدة بطريقة بسيطة.1 نقطة
-
ارتفاع أعداد السُكان ونمو توجّهاتهم الاستهلاكيّة أدى إلى خلق تنافس رهيب على مستوى العالم بين الجهات المُصنِّعة المُنتِجة التي عملت -ولا تزال- على إغراق الأسواق بألوان مُختلفة من السّلع والخدمات. أدرك مُدراء التّسويق في تلك الشركات أهميّة الرّسائل التّسويقيّة المُناسبة، إضافة إلى تكاملها مع التّصميم الجيّد كعامل أساسي في جذب المُستهلكين ودفعهم إلى شراء المُنتجات، سواء كان شكل هذه الرّسالة على هيئة تغليف مصحوب بتصميم مُميّز للمُنتج أو على هيئة هويّة مُناسبة "Brand" أو إعلان لاصق "Poster" أو غلاف مجلة "Cover" أو غيرها. إنّ عملية الإخراج الفنّي للتّصميم يجب أن تتكامل مع إخراج طباعي جيّد للوصول إلى أفضل النتائج، فوجود تصميم جاهز مُميّز وجذّاب معروض على شاشة الحاسب لا يعني بالضّرورة أن يظهر بنفس النّتيجة عند وبعد الطّباعة. سنتناول في هذا المقال (والمقال الذي سيليه) المفاتيح الأساسية للدّخول إلى عالم التّصميم الطّباعي والتي يجب على أي مُصمّم أن يكون على دراية بأساسيّاتها. ما هو التّصميم الموجّه للطّباعة؟ندعو أي تصميم بأنه موجّه للطّباعة لمّا تكون نتيجة عرضه النّهائية على شكل حسّي مطبوع، وتندرج تحت هذا المفهوم جميع التّصاميم المُتعلّقة بالمُنتجات وتغليفها، وجميع التّصاميم الإعلانية المطبوعة كالجرائد والمجلّات واللّوحات الطُرقية، والتّصاميم التّرويجية المطبوعة كالمُلصقات الإعلانيّة " Posters" والمطويّات "Brochures" وبطاقات العمل "Business Cards" والأغلفة المُتنوّعة "Covers" ... الخ. لماذا نظام اللون CMYK في التّصاميم المُوجّهة للطّباعة وما هو الفرق بينه وبين RGB؟ ببساطة، يُمكن القول بأن CMYK هو اختصار لمزيج لوني مُؤلّف من الألوان التّالية: السّماوي Cyan – الأحمر الأرجواني Magenta – الأصفر Yellow - والأسود Black، ويُستخدم هذا النّظام مع الطابعات الكبيرة الأوفسيت Offset والطّابعات الرقميّة المُتطوّرة، بحيث نقول بأن الطّابعة ذات أربعة رؤوس كِناية عن الألوان الأربعة CMYK. لذا فعند طباعة المُلصقات الإعلانيّة " Posters" والمطويّات "Brochures" وبطاقات العمل "business Cards" وما شابهها نقوم بفرز التّصاميم وفق هذا النّظام. بينما النّظام الثاني RGB أو ما نُعبِّر عنه تجاوزًا بنظام "ألوان الشّاشة" فهو قائم على مزيج لوني مُؤلّف من الألوان الأساسية التّالية: الأحمر Red – الأخضر Green – الأزرق Blue، وهو يُستخدم مع أي تصاميم تُعرض على شاشة الحاسب كتصاميم المواقع الإلكترونيّة. إضافة إلى ذلك، هُناك طابعات منزليّة بسيطة من النوع Ink Jet تستخدم هذا النّظام من الألوان. لمحة سريعة للتعرف على أنواع الطّباعة والطابعات:تعدّدت منذ الأزل أشكال الطّباعة، وسنتحدّث بإيجاز عن أشهر التّقنيّات الطّباعية المتوفّرة حاليًّا والخاصّة بطباعة التّصاميم الإعلانيّة والترويجيّة والتّصاميم الخاصّة بالمُنتجات وتغليفها، والتي يتوجّب على المُصمّم أن يكون على اطّلاع على أساسياتها على الأقل. الطّباعة بالأوفسيت Offset: تُعدّ أشهر أنواع الطّباعة التّجاريّة في الوقت الحالي، وهي تعتمد مفهوم الطّباعة على اللوح Indirect Offset Lithography، ومن أهم مُميزاتها سهولة إعداد ألواح الطّباعة والأمان في نقل أدقّ التّفاصيل إلى المادّة المُراد الطّباعة عليها، كونها تقوم على تقنيّة طباعة أربع مسودات "أفلام طباعيّة " طبقًا للألوان الأربعة CMYK عبر ماكينة خاصّة بفرز الألوان، ثُم يتم طباعة المسوّدات على صفيحة معدنيّة "Plate" لتأتي بعدها عمليّة الطّباعة على المكنة. وتتميّز تقنيّة الطّباعة بالأوفسيت بإمكانية الطّباعة على مُختلف السّطوح والمواد كالورق والخشب واللّدائن والأقمشة وغيرها. الطّباعة الرقميّة Digital: تقوم على مبدأ أساسي وهو الطّباعة مُباشرة من الحاسب، مُستبعِدة الخطوات الميكانيكية التي تقوم عليها الطّباعة بالأوفسيت Offset، والتي ذكرناها آنفًا، وبالتّالي فإن الطّباعة الرّقميّة أسرع من سابقتها وتتميّز بإمكانية طباعة كمّيّات قليلة مع مرونة أكبر في إجراء تغييرات على كل طبعة. البرامج التصميميّةهُناك العديد من البرامج التّصميميّة المُتخصّصة، ولعل أهمها وأشهرها البرامج الصّادرة عن شركة Adobe، وسنشمل حديثنا باقة مُتكاملة بالإمكان استخدامها طبقًا للغرض المطلوب: Adobe illustrator ملك الرّسم الشُّعاعي عالي الدقة، أو ما يُدعى أدوبي إليستريتور، يُعدّ من أهم البرامج في مجاله، ويتميّز بدقّته العالية مهما صغرت أو كبرت تفاصيل العمل، وهو يُكامل بشكل مُمتاز باقي برامج شركة Adobe وعلى رأسها Photoshop. Adobe Photoshop من أشهر برامج التّصميم حول العالم، ويُعد الأفضل على الإطلاق فيما يخصّ الرّسوميات والصّور. إن تكامل العمل بين برنامجيّ فوتوشوب وإليستريتور كافٍ لجعل أيّ تصميم الأفضل من ناحيّة الرّسوميات والخطوط الفنّيّة من جهة والدّقة من جهة أخرى، ويُمكن استخدام أيّ منهما لوحده بحسب نوع العمل المُنفّذ. Adobe InDesign يُعدّ من أشهر وأهم البرامج للتّصميم والتّنسيق السّريع للمجلّات والجرائد والكتب الإلكترونية والمطبوعة، بحيث يحوي أدوات ومساحات عمل تُساهم في إنجاز أعمال احترافية خلال أوقات قصيرة نسبيًّا، ويُستخدم البرنامجُ في أقسام التّصميم لدى أهم المجلات والجرائد حول العالم. مُلاحظة: تتوفّر العديد من البرامج التّصميميّة التي تُعدّ جيدة وخيارات بديلة، وبعضها قد يكون بقوّة برامج شركة Adobe آنفة الذّكر، ولعل أهمّها تلك البرامج الصادرة عن شركة Corel المرموقة كبرنامج CorelDRAW المُتخصّص بالرّسوميات عاليّة الدقة، إضافة إلى برنامج Painter الصّادر عن ذات الشركة والمُتخصّص بالرسم الفنّي الاحترافي، إضافة إلى برامج صادرة عن جهات أخرى نذكر منها inkscape و Gimp مفتوحي المصدر. سبب تركيزنا على برامج Adobe هو كونها شائعة ولتكامُلها وتلبيتها الغرض من جهة، واعتمادها كبرامج عمل وتركيب montage أساسيّة من جهة أخرى، حيث أن مُعظم المطابع تُفضّل استلام ملفّات جاهزة للطّباعة بصيغ أحد برامج Adobe. التحضير الصحيح لمساحات العملالبداية الصّحيحة لأيّ تصميم مُوجّه للطّباعة تكمن في التّحضير الصّحيح لمساحات العمل والذي يقوم على الإجراءات الأساسية التّالية: 1- اختيار برنامج التّصميم الأفضل طبقًا لنوع العمل. 2- وضع نظام الألوان CMYK، واختيار المقاسات المُناسبة طبقًا لنوع التّصميم، واستخدام الدقة 300 dpi. 3- التّرتيب "مُهم" يُبعد التّشتّت ويزيد الإنتاجيّة: إن البداية الصّحيحة والترتيب الأنيق لأيّ عمل تصميمي سيجعل العمل سلسًا ومُمتعًا بشكل أكبر ويزيد من الإنتاجيّة للمُصمّم، كما أنّه سيساعد المطبعة أيضًا ويُقلل من عدد الأخطاء التي قد تظهر، لذا لا تغفل أبدًا عن ما يلي: - قُم بتسمية العمل بشكل واضح بجميع أجزاءه، وبالأخص إن تنوّعت المُنتجات أو تعدّدت الصّفحات. - اختر مقاسات سليمة واضحة. - رتّب الطبقات "Layers" ضمن مجموعات من المُجلّدات بشكل مُناسب واستخدم ألوان إيضاحيّة لذلك. 4- ضع هوامش مُناسبة على حواف التّصاميم المُوجهة للطّباعة (تمديدات لونيّة على الأطراف وليس نصوصًا) وذلك بسبب وجود احتمال تحرك مكنة القص (القاطعة – Cutting Machine) قليلاً بعد الطّباعة، ويُفضّل عادة استخدام هوامش بمقدار 1 سم كمسافة أمان "Safe Zone". (لاحظ الصورة) 5- لا تعتمد على ذاكرتك أبدًا، ووثّق كل شيء بدقّة وبخاصّة المعلومات الرّئيسيّة التي لها علاقة بالفرز وأي معلومات مُهمّة ستكون عُرضة للنّسيان مع مرور الوقت. مقاسات أشهر القوالبتذكّر بأنّه في عالم الطّباعة والتّصميم الطّباعي لا تُوجد مقاسات مُحددة للتقيّد بها، إنما بالإمكان على الدّوام ابتداع أفكار خلاّقة حسب الطّلب والحاجة. على سبيل المثال: - بطاقات العمل "Business Cards": عُرفت عادة بالمقاس 90 ملم للعرض و55 ملم للارتفاع، إنّما قد تجد أحد دور الأزياء الفاخرة قد اعتمدت نصف المقاس التقليدي المُتعارف من باب تحقيق نعومة أكثر للبطاقة. - المطويات "Brochures": كوجود إضافات مُعيّنة أو حواضن بداخلها لوضع البطاقات، أو وجود أحرف غير مُضلّعة، إضافة إلى أفكار كثيرة أخرى. وعلى سبيل الذكر فإننا نوضح لكم المقاسات العالميّة المُتعارف عليها على النّحو التّالي: أولاً: المقاسات العالميّة للتصاميم الدعائية والمُغلفاتالنوع العرض الارتفاع الوحدة الدّقة مطويّة Brochure 300 500 mm 300 dpi مطويّة صغيرة 95 210 mm 300 dpi بطاقة عمل Business Card 90 55 mm 350 dpi مُفكّرة Note book 75 115 mm 350 dpi كُتيّب booklet 120 170 mm 300 dpi علبة أسطوانة CD Box 240 (مقسومة من المنتصف) 120 mm 300 dpi ثانياً: المقاسات العالميّة للورق هذه المقاسات مُعتمدة من طرف الطابعات، وتُنفّذ بموجبها المُلصقات الإعلانيّة Poster والمطوياتBrochures عادة: النّوع العرض الارتفاع الوحدة الدّقة A4 210 297 mm 300 dpi A6 105 148 mm 300 dpi A5 148 210 mm 300 dpi A3 297 420 mm 300 dpi نصيحة: اجعل أدوات القياس حاضرة بجانبك، واطّلع على أي تصاميم مُشابهة لأيّة أعمال تودّ تنفيذها قبل البدء للاستلهام من جهة واستعراض المقاسات على الواقع من جهة أخرى. خلاصةكُنا معكم في مُقدّمة موجزة حول الأمور التي يجب ألّا يغفلها أي مُصمّم يسعى للانطلاق في مجال تنفيذ التّصاميم المُجهّزة للطّباعة أو لإثراء معلوماته في هذا الجانب. عرّجنا على أشهر الطّابعات التّجاريّة المُستخدمة مع أهم البرامج التّصميميّة في مجالها وطرق التّحضير الصّحيح لمساحات العمل إضافة إلى تعريفكم بمقاسات أشهر القوالب الموجودة. سنكون سعداء بإثراء المقال بتعليقاتكم وإضافاتكم القيّمة.1 نقطة
-
يعتبر React.js -على حداثته- من أقوى أطر عمل Javascript (بعضهم قد يسميه مكتبة وليس إطار عمل) لبناء الواجهات الرسومية على الويب، حيث طبّق أفكارًا جديدة في هذا المجال، جعلت شِفرة الواجهات البرمجية أكثر نظافة، سرعة وأكثر قابلية للصيانة. يسمح لك React ببناء الواجهة الرسومية في مجموعة مكونات، كل مكوّن عبارة عن سرد لهيكلة ومنطق المكون، إذا تمزج بين شِفرة HTML مخصصّة وشِفرة جافاسكربت تصف سلوك ذاك المكون، ليكون قائما بذاته وقابلا لإعادة الاستعمال. إطار عمل React مُطور من طرف شركة فيس بوك (Facebook)، وقد يكفيك ثقة ويجذب انتباهك بمجرد أن تعرف أن فيس بوك نفسها تستخدم React في واجهتها البرمجية على موقع Facebook نفسه! يمكنك فتح موقع Facebook وعرض شفرة HTML الخاصة به والبحث عن كلمة react للتأكد بنفسك. سنقوم في هذا الدرس بإنشاء مُربَّع تعليقات بسيط وفعَّال بإمكانك وضعه في مدوَّنتك، سيكون المُربَّع عبارة عن نُسخة مُجرَّدة من التعليقات الآنية التي تُقدمها لك تعليقات Disquse ،LiveFyre أو فيس بوك. ستجد في نهاية الدَّرس أنَّ لديكَ مُربَّع تعليقات يوفِّر ما يلي: عرض لجميع التعليقات.نموذج لإرسال تعليق.خُطَّافات لتوفير مُنتهى خلفي مُخصَّص custom backend.سوف يحتوي مُربَّع التعليقات كذلك على بعض المزايا اللَّطيفة: تعليق مُحسَّن: تظهر التَّعليقات في القائمة قبل أن يتمّ حفظها على الخادم وبناءً عليه تظهر التَّعليقات في التوِّ واللَّحظة.تحديثات حيَّة: تظهر تعليقات المستخدمين الآخرين في عرض التَّعليقات في نفس وقت الإرسال.هيئة Markdown: يُمكن للمستخدمين استخدام Markdown لتهيئة نصوصهم.هل ترغب في تخطِّي كل هذا ومعاينة المصدر؟ كل شيء موجود على GitHub. تشغيل الخادمرغم أنَّه ليس من الضروري أن تبدأ بهذا الجزء من الدرس إلَّا أنَّنا سنقوم في وقت لاحق بإضافة وظائف تتطلَّب المُشاركة POST إلى خادم قيد التشغيل. إذا كُنتَ واثقٌ من أنّك على دراية بهذا الأمر وترغب في إنشاء خادمك الخاص يُمكنكَ القيام بذلك. ولِمَن يُريد التَّركيز على تعلُّم React دون الحاجة إلى القلق بشأن جوانب الخادم، فلقد كتبنا خوادم بسيطة بعددٍ من اللُّغات: Python ،Ruby ،Go، Node.js و PHP. كلُّ هذا مُتاح على GitHub. يُمكن الاطِّلاع على المصدر أو تحميل ملفّ مضغوط للبدء. للبدء بتطبيق هذا الدَّرس، كلّ ما عليكَ فعله هو بداية تحرير public/index.php. البدءسنستخدم لهذا الدرس ملفَّات JavaScript سبق إنشاؤها على شبكة توصيل مُحتوى CDN. قم بفتح المُحرِّر المفضَّل لديك وقم بإنشاء مُستند HTML جديد: <!-- index.html --> <!DOCTYPE html> <html> <head> <title>Hello React</title> <script src="https://fb.me/react-0.13.3.js"></script> <script src="https://fb.me/JSXTransformer-0.13.3.js"></script> <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script> </head> <body> <div id="content"></div> <script type="text/jsx"> // Your code here </script> </body> </html>سيتمّ كتابة شفرات JavaScript في وسم السكربت هذا طوال الفترة المتبقية من الدرس. مُلاحظة: قُمنا بإدراج jQuery هُنا لأننا نٌريد تبسيط الشَّفرات لاستدعاءات Ajax في المُستقبل، ولكنَّها ليست إلزاميَّة لعمل React. مُكوِّنكَ الأوَّلتتمحور الفكرة الأساسيَّة لـ React حول كل شيءٍ له علاقة بالمُكوِّنات التركيبيَّة القابلة للتَّشكيل modular, composable components. سنستخدم بنية المُكوٍّنات التالية لمثال مُربَّع التَّعليقات لهذا الدرس: - CommentBox - CommentList - Comment - CommentFormسنقوم الآن ببناء المُكوِّن CommentBox وما هو إلَّا وسم بسيط: // tutorial1.js var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> Hello, world! I am a CommentBox. </div> ); } }); React.render( <CommentBox />, document.getElementById('content') );لاحظ أن أسماء عناصر HTML تبدأ بحرف صغير في حين أن أسماء فئات React تبدأ بحرف كبير. 1. صياغة JSXستُلاحظ أوَّل ما تلاحظ تلكَ الصياغة المُشابهة لـ XML في شفرة JavaScript. لدينا precompiler بسيط يُترجم الجُملة البسيطة Syntactic Sugar إلى شفرات JavaScript المُجرَّدة هذه: // tutorial1-raw.js var CommentBox = React.createClass({displayName: 'CommentBox', render: function() { return ( React.createElement('div', {className: "commentBox"}, "Hello, world! I am a CommentBox." ) ); } }); React.render( React.createElement(CommentBox, null), document.getElementById('content') );إنَّ استخدام صياغة JSX اختياري ولكن وجدنا أنَّها أسهل استخدامًا من شفرات JavaScript مُجرَّدة. يُمكن قراءة المزيد في مقال صياغة JSX 2. ماذا يحدث هنانقوم بتمرير بعض الوظائف في كائن JavaScript إلى دالَّة ()React.createClass لإنشاء مُكوِّن React جديد. أهم هذه الوظائف ما تُسمَّى تصيير render والتي تُعيد شجرة من مُكوِّنات React والتي في نهاية المطاف ستقوم بالتصيير عبر HTML. لا تُعتبر وسوم عُقَد نموذج كائن مُستند DOM فعليَّة، وإنَّما هي تمثيلات من مُكوِّنات div الخاصَّة بـ React. يُمكنكَ اعتبارها كوسوم أو قطع من البيانات والتي يعرف React كيفيَّة التعامل معها. React آمن. لا نقوم بتوليد سلاسل HTML لذلك فإن حماية XSS تُعتبر الافتراضيَّة. لا يجب عليكَ إعادة شفرات HTML قياسيَّة. وإنَّما يُمكنكَ إعادة شجرة من المُكوِّنات التي قُمتَ (أو شخص آخر قام) ببنائها. هذا ما يجعل React قابلة للتَّشكيل composable: وهي عقيدة أساسيَّة في الواجهات الأماميَّة القابلة للصّيانة. يقوم ()React.render بتمثيل المُكوِّن القاعدي، بدء عمل الإطار، ثم إدخال الوسوم إلى عنصر نموذج كائن مُستند خام، يتمّ تقديم تلك الوسوم كمُعطى ثاني . تركيب المُكوِّناتسنُنشيء الآن هياكل بناء لكلٍّ من المُكوِّنين CommentList وCommentForm والتي ستكون -مرَّة أخرى- عبارة عن وسوم بسيطة. أضِف هذين المُكوِّنين إلى ملفِّك مع الحفاظ على تعريف commentBox الحالي واستدعاء React.render: // tutorial2.js var CommentList = React.createClass({ render: function() { return ( <div className="commentList"> Hello, world! I am a CommentList. </div> ); } }); var CommentForm = React.createClass({ render: function() { return ( <div className="commentForm"> Hello, world! I am a CommentForm. </div> ); } });ما سنقوم بعمله الآن هو تحديث مُكوِّن CommentBox لاستخدام المُكوِّنات الجديدة: // tutorial3.js var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> <CommentForm /> </div> ); } });لاحظ كيف تمَّ مزج وسوم HTML والمُكوِّنات التي قُمنا ببنائها. إنَّ مُكوِّنات HTML ما هي إلَّا مُكوِّنات React مُنتظمة، تمامًا مثل تلك التي تقوم بتعريفها ولكن مع فارق واحد. سيقوم مترجم JSX تلقائيًا بإعادة كتابة وسوم HTML إلى تعبيرات React.createElement() tagName وترك كل شيء على حدة. وهذا لمنع حدوث التَّلوّث في مساحة الاسم العموميَّة global namespace. استخدام الخصائصسنقوم الآن بانشاء مُكوِّن Comment، والذي سوف يعتمد على البيانات التي تمَّ تمريرها إليه من المُكوِّن الأساسي. يتمّ اتاحة البيانات التي تمّ تمريرها من مُكوِّن أساسي كـ "خاصيَّة" في المُكوِّن الفرعي. ويتمّ الوصول إلى هذه "الخصائص" من خلال this.props. يُمكننا باستخدام الخصائص props قراءة البيانات التي تمّ تمريرها إلى Comment من CommentList، وتصيير بعض الترميزات: // tutorial4.js var Comment = React.createClass({ render: function() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> {this.props.children} </div> ); } });يُمكنكَ وضع نصّ أو مُكوِّنات React في الشَّجرة وذلك بإحاطة تعبير JavaScript بأقواس داخل JSX (إما كخاصيَّة أو كمُكوِّن فرعي). نقوم بالوصول إلى خاصيَّات مُسمَّاه تمّ تمريرها إلى عنصر كمفاتيح على this.props وأيّ عناصر مُتداخلة كما this.props.children. خصائص المُكوِّننحتاج الآن وبعد أن قمنا بتحديد مُكوِّن Comment إلى تمرير اسم الكاتب ونصّ التعليق إلى هذا المُكوِّن. يسمح لنا هذا بإعادة استخدام نفس الشَّفرة لكلِّ تعليق مُختلف. لنقوم الآن بإضافة بعض التَّعليقات داخل مُكوِّن CommentList: // tutorial5.js var CommentList = React.createClass({ render: function() { return ( <div className="commentList"> <Comment author="Pete Hunt">This is one comment</Comment> <Comment author="Jordan Walke">This is *another* comment</Comment> </div> ); } });لاحظ أنَّنا قد قُمنا بتمرير بعض البيانات من مُكوِّن CommentList الأساسي إلى مُكوِّنات Comment الفرعيَّة. مرَّرنا على سبيل المثال Pete Hunt (عن طريق خاصيَّة) وThis is one comment (عن طريق عُقدة فرعيَّة تُشبه XML) إلى Comment الأوَّل. وكما ذكرنا بالأعلى فإنَّ مُكوِّن Comment سيعمل على الوصول إلى هذه الخصائص من خلال this.props.author، وthis.props.children. إضافة MarkdownMarkdown هي طريقة بسيطة لتهيئة مُضمّنة inline لنصِّك. على سبيل المثال، احاطة النص بعلامة النجمة (*) سيقوم بتأكيده. أولًا، أضِف مكتبة الطرف الثالث marked إلى تطبيقك. Marked هي مكتبة JavaScript تقوم بأخذ نص Markdown وتُحوِّله إلى صيغة HTML خام. هذا الأمر يتطلَّب وسم سكربت في قسم head (قُمنا بادراجه بالفعل في أرضيَّة React): <!-- index.html --> <head> <title>Hello React</title> <script src="https://fb.me/react-0.13.3.js"></script> <script src="https://fb.me/JSXTransformer-0.13.3.js"></script> <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js"></script> </head>سنقوم بعد ذلك بتحويل نصّ التَّعليق إلى Markdown ومن ثمَّ إخراجه: // tutorial6.js var Comment = React.createClass({ render: function() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> {marked(this.props.children.toString())} </div> ); } });كل ما فعلناه هنا هو استدعاء مكتبة marked. نحتاج إلى تحويل this.props.children من نصّ React مُحاط إلى سلسلة خام يُمكن لمكتبة marked فهمها ولذلك فإننا نقوم بستدعاء دالَّة ()toString. لكن لدينا مشكلة وهي أنَّه يتمّ إظهار وسوم HTML الموجودة في التَّعليقات بالشكل التَّالي في المُتصفح: This is another comment. هذا الأمر هو حماية React لك من هجوم XSS. هُناك طريقة للالتفاف على ذلك، ولكنَّ إطار العمل يُحذِّرُكَ من استخدامها: // tutorial7.js var Comment = React.createClass({ render: function() { var rawMarkup = marked(this.props.children.toString(), {sanitize: true}); return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <span dangerouslySetInnerHTML={{__html: rawMarkup}} /> </div> ); } });هذه الشَّفرات هي API خاصّ والذي عمدًا يجعل من الصَّعب إدراج شفرات HTML خام، في حالتنا بالنِّسبة لمكتبة marked فإنَّنا سنقوم بالاستفادة من هذا المنفذ الخلفيّ. تذكَّر: باستخدامك لهذه الميزة فإنَّك تعتمد على مكتبة marked أن تكون آمنة. نقوم في هذه الحالة بتمرير sanitize: true التي تطلب من مكتبة marked تنفيذ أي وسم HTML في المصدر بدلًا من تمريره دون تغيير. إضافة نموذج البياناتحتَّى الآن فإنَّنا نقوم بإدراج تعليقات مُباشرة في شفرات المصدر. بدلًا من ذلك، سنقوم بتصيير بضع من بيانات JSON في قائمة التعليق. يأتي هذا من الخادم في نهاية المطاف، ولكن في الوقت الراهن سنكتبها نحن في المصدر: // tutorial8.js var data = [ {author: "Pete Hunt", text: "This is one comment"}, {author: "Jordan Walke", text: "This is *another* comment"} ];الآن نحنُ بحاجة إلى إدخال هذه البيانات في مُكوِّن CommentList بطريقة نموذجيِّة. قُم بتعديل CommentBox واستدعاء ()React.render لتمرير هذه البيانات إلى CommentList عن طريق الخصائص props: // tutorial9.js var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.props.data} /> <CommentForm /> </div> ); } }); React.render( <CommentBox data={data} />, document.getElementById('content') );الآن حيثُ أنَّ البيانات مُتاحة في CommentList، سوف نقوم بتقديم التَّعليقات بطريقة ديناميكيَّة: // tutorial10.js var CommentList = React.createClass({ render: function() { var commentNodes = this.props.data.map(function (comment) { return ( <Comment author={comment.author}> {comment.text} </Comment> ); }); return ( <div className="commentList"> {commentNodes} </div> ); } });هذا كل شيء. الاستدعاء من الخادمسنعمل الآن على استبدال البيانات الثَّابتة ببعض البيانات الديناميكيَّة من الخادم. يتمّ ذلك بإزالة خاصيَّة البيانات data prop واستبدالها بعنوان URL للجلب: // tutorial11.js React.render( <CommentBox url="comments.json" />, document.getElementById('content') );هذا المُكوِّن مُختلف عن المُكوِّنات السَّابقة حيثُ أنَّه سيضطر إلى إعادة تصيير نفسه. لن يحتوي المُكوِّن على أيّ بيانات إلى أن يعود الطَّلب من الخادم، في هذه الحالة قد يحتاج المُكوِّن إلى تصيير بعض التَّعليقات الجديدة. الحالة التفاعليَّةقام كلّ مُكوِّن حتَّى الآن على أساس خصائصه بتصيير نفسه مرة واحدة. الخصائص props ثابتة: يتمّ تمريرها من المُكوِّن الأساسي و”مملوكة” من قبل المُكوِّن الأساسي كذلك. لتنفيذ التَّفاعلات، فإنَّنا نُقدِّم حالة قابلة للتغيير إلى المُكوِّن. حالة this.state هي خاصَّة بالمُكوِّن ويُمكن تغييرها من خلال استدعاء ()this.setState يقوم المُكوِّن بإعادة تقديم نفسه عند تحديث الحالة. وظائف ()render مكتوبة إلزاميًّا كدوال this.props وthis.state. يضمن إطار العمل أن تكون واجهة المستخدم دائمًا مُتَّسِقَة مع المُدخَلات. عندما يقوم الخادم بجلب بيانات سنقوم نحن بتغيير بيانات التعليق لدينا. لنُضيف الآن مصفوفة من بيانات التَّعليق كحالة للمُكوِّن CommentBox: // tutorial12.js var CommentBox = React.createClass({ getInitialState: function() { return {data: []}; }, render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm /> </div> ); } });يتمّ تنفيذ دالَّة ()getInitialState مرَّة واحدة فقط خلال دورة حياة المُكوِّن كما أنَّها تبدأ الحالة الأوليَّة للمُكوِّن. تحديث الحالةنُريد عند إنشاء المُكوِّن لأوَّل مرَّة أن نحصل على (GET) بعض بيانات JSON من الخادم وتحديث الحالة لتعكس أحدث البيانات. هذا من شأنه أن يكون نقطة نهاية ديناميكيَّة لو كان الأمر في تطبيق حقيقي، ولكن سنستخدم لهذا المثال ملف JSON ثابت لابقاء الأمور بسيطة: // tutorial13.json [ {"author": "Pete Hunt", "text": "This is one comment"}, {"author": "Jordan Walke", "text": "This is *another* comment"} ]سنقوم باستخدام مكتبة jQuery للمساعدة في عمل طلب غير متزامن asynchronous request إلى الخادم. مُلاحظة: حيثُ أنَّ هذا الأمر أصبح تطبيق AJAX فإنَّك سوف تحتاج لتطوير تطيبقك باستخدام خادم ويب بدلًا من أن ملف موجود في نظام ملفاتك. قدَّمنا -كما هو مذكورٌ بالأعلى- العديد من الخوادم التي يُمكنكَ استخدامها على GitHub. توفر تلك الخوادم التأدية الوظيفيَّة التي تحتاجها لبقيَّة هذا الدرس. // tutorial13.js var CommentBox = React.createClass({ getInitialState: function() { return {data: []}; }, componentDidMount: function() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm /> </div> ); } });وظيفة componentDidMount هنا هي وظيفة تُستدعى تلقائيًا بواسطة React عندما يتمّ تصيير مُكوِّن. مفتاح التَّحديثات الديناميكيَّة هو استدعاء دالَّة ()this.setState. نقوم باستبدال مصفوفة التَّعليقات القديمة بواحدة جديدة من الخادم وتقوم واجهة المستخدم بتحديث نفسها تلقائيًا. بسبب هذا التفاعل، يُعتبر التغيير لإضافة تحديثات حيَّة طفيفًا. سوف نستخدم أسلوب بسيط في هذا الدَّرس ولكن لكَ الحُريَّة في استخدام WebSockets أو غيرها من التكنولوجيَّات. // tutorial14.js var CommentBox = React.createClass({ loadCommentsFromServer: function() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, getInitialState: function() { return {data: []}; }, componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm /> </div> ); } }); React.render( <CommentBox url="comments.json" pollInterval={2000} />, document.getElementById('content') );كل ما فعلناه هنا هو نقل استدعاء AJAX إلى وظيفة مُستقلَّة واستدعائها عند تحميل المُكوِّن الأوَّل واستدعائها كلّ ثانيتين بعد ذلك. حاول تشغيل هذا في مُتصفِّحك وتغيير ملف comments.json. في غضون ثانيتين ستظهر لكَ التغييرات. إضافة تعليقات جديدةحان الآن الوقت لبناء النموذج. على مُكوِّن CommentForm أن يسأل المُستخدم عن اسمه ونصّ التَّعليق، ثم يقوم بإرسال طلب إلى الخادم لحفظ التعليق. // tutorial15.js var CommentForm = React.createClass({ render: function() { return ( <form className="commentForm"> <input type="text" placeholder="Your name" /> <input type="text" placeholder="Say something..." /> <input type="submit" value="Post" /> </form> ); } });دعونا نجعل النموذج متجاوب. عندما يقوم المُستخدم بإرسال النَّموذج، يجب علينا مسحه clear، تقديم طلب إلى الخادم، ثُمَّ تحديث قائمة التعليقات. للبدء في تنفيذ هذا، سقوم بالاستماع إلى حدث ارسال النَّموذج ومسحه. // tutorial16.js var CommentForm = React.createClass({ handleSubmit: function(e) { e.preventDefault(); var author = React.findDOMNode(this.refs.author).value.trim(); var text = React.findDOMNode(this.refs.text).value.trim(); if (!text || !author) { return; } // TODO: send request to the server React.findDOMNode(this.refs.author).value = ''; React.findDOMNode(this.refs.text).value = ''; return; }, render: function() { return ( <form className="commentForm" onSubmit={this.handleSubmit}> <input type="text" placeholder="Your name" ref="author" /> <input type="text" placeholder="Say something..." ref="text" /> <input type="submit" value="Post" /> </form> ); } });1- الأحداث Eventsتقوم React بإرفاق مُعالجات الحدث في المُكوِّنات باستخدام اتفاقية التَّسمية camelCase. نقوم بإرفاق مُعالج onSubmit إلى النَّموذج الذي يعمل على مسح حقول النَّموذج عند إرساله مع إدخال صحيح. عليكَ استدعاء ()preventDefault بالحدث لمنع الإجراء الافتراضي للمُتصفِّح من اعتماد النَّموذج. 2- المراجع Refsنستخدم خاصيَّة ref لتعيين اسم للمُكوِّن الفرعي وthis.refs لارجاع المُكوِّن. يمكن أن نستدعي (React.findDOMNode(componentعلى مُكوّن للحصول على عنصر نموذج كائن مُستند المُتصفِّح الأصلي. 3- نداءات الخصائصعندما يُرسِل المُستخدم التَّعليق، فإنَّنا سوف تحتاج إلى تحديث قائمة التَّعليقات لتشمل التَّعليق الجديد. من الطبيعي أن تفعل كل هذا في مُكوِّن CommentBox حيث أنَّ المُكوِّن يمتلك الحالة التي تُمثِّل قائمة التَّعليقات. نحن بحاجة لتمرير البيانات من نُسخة المُكوِّن الفرعي الاحتياطيَّة إلى المُكوِّن. يتمّ فعل هذا في وظيفة render الخاصَّة بالأب عن طريق تمرير رد نداء جديد (handleCommentSubmit) في الابن ثُمَّ الزامها لحدث الابن onCommentSubmit. كُلَّما تم تشغيل الحدث، سيُنفَّذ الاستدعاء: // tutorial17.js var CommentBox = React.createClass({ loadCommentsFromServer: function() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, handleCommentSubmit: function(comment) { // TODO: submit to the server and refresh the list }, getInitialState: function() { return {data: []}; }, componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm onCommentSubmit={this.handleCommentSubmit} /> </div> ); } });سوف نستدعي الآن النِّداء من CommentForm عندما يقوم المُستخدم بإرسال النَّموذج: // tutorial18.js var CommentForm = React.createClass({ handleSubmit: function(e) { e.preventDefault(); var author = React.findDOMNode(this.refs.author).value.trim(); var text = React.findDOMNode(this.refs.text).value.trim(); if (!text || !author) { return; } this.props.onCommentSubmit({author: author, text: text}); React.findDOMNode(this.refs.author).value = ''; React.findDOMNode(this.refs.text).value = ''; return; }, render: function() { return ( <form className="commentForm" onSubmit={this.handleSubmit}> <input type="text" placeholder="Your name" ref="author" /> <input type="text" placeholder="Say something..." ref="text" /> <input type="submit" value="Post" /> </form> ); } });الآن وبعد أن أصبح النِّداء في مكانه الصحيح، كل ما علينا القيام به هو الإرسال إلى الخادم وتحديث القائمة: // tutorial19.js var CommentBox = React.createClass({ loadCommentsFromServer: function() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, handleCommentSubmit: function(comment) { $.ajax({ url: this.props.url, dataType: 'json', type: 'POST', data: comment, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, getInitialState: function() { return {data: []}; }, componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm onCommentSubmit={this.handleCommentSubmit} /> </div> ); } });تحديثات مُحسَّنةمشروعنا الآن كامل الوظائف ولكن من المُمل أن نقوم بانتظار الطَّلب حتَّى يكتمل قبل ظهور تعليقك في القائمة. يُمكننا إضافة هذا التَّعليق إلى القائمة لجعل التطبيق يعمل بشكلٍ أسرع. // tutorial20.js var CommentBox = React.createClass({ loadCommentsFromServer: function() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, handleCommentSubmit: function(comment) { var comments = this.state.data; var newComments = comments.concat([comment]); this.setState({data: newComments}); $.ajax({ url: this.props.url, dataType: 'json', type: 'POST', data: comment, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, getInitialState: function() { return {data: []}; }, componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm onCommentSubmit={this.handleCommentSubmit} /> </div> ); } });ختامًاانتهيتَ لتوك من إنشاء مربع تعليقات في بضع خطوات بسيطة. يُمكنك الآن التَّعرُّف على المزيد حول أسباب استخدام React، أو الخوض في مراجع API وبدء العمل. ترجمة -وبتصرّف- للمقال: Tutorial | React.1 نقطة
-
1 نقطة
-
نُتابع معكم ما بدأناه في الجزء السّابق من المقال، وسنحاول رسم المسارات الصّحيحة للتّصاميم الموجّهة للطّباعة. آلية تصدير التّصاميم إلى المطبعةبعد الانتهاء من التّصميم الطّباعي بشكل كامل يأتي دور التّصدير إلى أفضل صيغة لإرساله إلى المطبعة إنشاء ملف جاهز للطّباعة في Adobe Photoshop 1- تأكدّ بأن تكون الألوان مفروزة وفق النّمط CMYK. 2- قُم بدمج العمل بالكامل عبر الذّهاب إلى نافذة الطّبقات ثم بالضّغط بالزّر الأيمن على الطّبقة السّفلية (الأرضية) والضّغط على Flatten Image. 3- خزّن العمل النّهائي على هيئة ملف PDF من خلال اتّباع ما يلي: File ثم Save as ثم اختر من القائمة المُنسدلة Format حفظ العمل على صيغة Photoshop PDF في المكان المُراد. 4- عند الضّغط على Save ستظهر لك نافذة تتطلّب بعض الإعدادات، احرص على اختيار القيم حسب الصّورة أدناه، ثم اضغط على Save PDF. إنشاء ملف جاهز للطباعة في Adobe illustrator1- تأكدّ بأن تكون الألوان مفروزة وفق النّمط CMYK. 2- عدّل جميع الخطوط إلى outlines من خلال اتّباع ما يلي: Select ثم All وبعد ذلك Type ثم Create outline. 3- خزّن العمل النهائي على هيئة ملف PDF من خلال اتّباع ما يلي: File ثم Save as ثم اختر من القائمة حفظ العمل على صيغة Adobe PDF في المكان المُراد. 4- عند الضّغط على Save ستظهر لك نافذة تتطلّب بعض الإعدادات، احرص على اختيار القيم حسب الصّور الثّلاث أدناه، ثم اضغط على Save PDF. إنشاء ملف جاهز للطباعة في Adobe indesign1- تأكدّ بأن تكون الألوان مفروزة وفق النمط CMYK. 2- اضغط File ثم Export ثم اختر من القائمة حفظ العمل على صيغة Adobe PDF في المكان المُراد واضغط Save. 3-عند الضّغط على Save ستظهر لك نافذة تتطلّب بعض الإعدادات، احرص على اختيار القيم حسب الصّور الثّلاث أدناه، ثم اضغط على Save PDF فرز التّصاميم الطّباعيّة في المطابع - الألواح الطباعيّة – المقاسات والتقسيماتهناك أنواع مُختلفة من الورق والتي تُشكّل الألواح الطّباعية ولعل أكثرها شيوعًا: الكوشيه "kosheh paper" والكرتون وورق العجينة وورق الطبع الأبيض. يأتي كل نوع من أنواع الورق وفق أحجام وكثافات وأوزان "Grams" مُختلفة تُستخدم حسب الطّلب، ويأتي بعضها بالسطح اللامع "Gloss" وبعضها بسطح المت أو المطفي "Matte". تحدثنا مُسبقاً عن أشهر الطابعات التّجاريّة الحالية الأوفسيت Offset ويأتي منها عدة مقاسات أشهرها: - الطابعات ذات المقاس الصغير (50 × 35 سم) ويُدعى اللّوح الطّباعي printing board أو ما يُعرف بالمُصطلح العربي الدّارج "ربُع فرخ" نسبة إلى أن الفرخ من مقاس (100 × 70 سم). - الطابعات ذات المقاس الكبير (100 × 70 سم) ويُدعى اللّوح الطّباعي "فرخ". أشهر مقاسات ألواح الطباعة المُستخدمة وتقسيماتها:المقاس الفرخ (100 × 70 سم) وأشهر تقسيماته: (50 × 70 سم) ويُدعى نصف فرخ (50 × 35 سم) ويُدعى ربع فرخ (25 × 35 سم) ويُدعى ثُمن فرخ هُناك تقسيمات ثانويّة أخرى تُوزّع بحسب مقاسات التصميم، فمثلاً بإمكان تقسيم الفرخ إلى 16 قطعة كلٍ منها بمقاس (25 × 17.5 سم). ليس بالضرورة أن تكون التصاميم مُطابقة تمامًا للتّوزيع على الفرخ، فمثلًا إن كان لدينا تصميم بالمقاس (33 × 70 سم) يتم تكراره على ثلاثة قطع ضمن الفرخ وتزداد مساحة صغيرة تُدعى استريشة (ورق مهدور – wasted paper)، لاحظ الصورة: مقاس الجاير الكبير (66 × 88 سم) وأشهر تقسيماته: (44 × 66 سم) ويُدعى نصف جاير (44 × 33 سم) ويُدعى ربع جاير (22 × 33 سم) ويُدعى ثُمن جاير ليس بالضّرورة أن تكون التّصاميم مُطابقة تمامًا للتوزيع على الجاير، فقد تزداد بعد التوزيع مساحات صغيرة تُدعى استريشة (ورق مهدور – wasted paper). التقنيات والإضافات الطباعيّةالفن الطّباعي لا يقتصر على الطّباعة المُلوّنّة فحسب، وإنّما تتخلّله العديد من الإضافات الطّباعيّة ومن أهمها: اللّون الإضافي (اللّون الخامس) Extra color print هو عبارة عن لون إضافي يُمكن إسقاطه بعد طباعة التّصميم بألوانه الأربع الأساسيّة CMYK، وعادة يكون هذا اللون فضيًّا أو ذهبيًّا أو حتى أسود، ويُستخدم لأمرين أساسيين: - إضفاء حركة جذّابة على الطّباعة للفت الانتباه (ألم تلحظ يومًا إعلانًا مُميّزًا داخل مجلّة يحوي لونًا فضّيًّا أو ذهبيًّا بارزًا وبقوّة). - يُستخدم أيضًا لإضافة معلومات قابلة للإزالة أو التّعديل على الطّبعة الأساسيّة (مثل الوزن – التّاريخ – عنوان مُعيّن .. الخ)، فلو افترضنا على سبيل المثال تصميمًا لمُنتج مُعيّن يحوي شفرة خيطيّة "Barcode" مطبوعًا فوق التّصميم على هيئة لون خامس إضافي، وتغيّرت هذه الشفرة لاحقًا لسبب مُعيّن، بالإمكان هُنا عدم التكلّف بعمل المُسوّدات والصفائح المعدنيّة الطباعيّة مُجدّداً، وإنما الاكتفاء فقط بتعديل صفيحة الشّفرة الخيطيّة إلى صفيحة أخرى. مُلاحظة: اللّون الإضافي قد لا يكون لونًا خامسًا فقط بل قد يكون لونًا سادسًا أو سابعًا ... الخ (الفكرة هي أنه لون يُضاف بشكل مُنفصل بعد الطّباعة)، ويُسمى هذا اللون في Photoshop بـ Special color، وله قناة لونيّة مُستقلّة داخل مكان الألوان. الختم الحراري Hot Foil Stamping بعد الانتهاء من الطّباعة، بالإمكان وفي مواضع مُعيّنة إضافة طباعة حراريّة فوق التّصميم، كزخرفة أو ما شابه، ويُستخدم اللّون الذّهبي في الغالب لهذا الإجراء. التقنيّة عبارة عن ورق يوضع بين الطّبعة وبين مكبس حراري (جهاز يدوي بسيط غالبًا) بحيث يُطبع الشّكل (المحفور على المعدن) على التّصميم، ويُطلق على هذا النّوع من الطّباعة أيضًا اسم "البصمة”. لتوجيه الموضوع إلى المطبعة يتوجب على المُصمّم إرسال ملف مفتوح مُنفصل يحوي رسمة الشّكل المطلوب طباعته باللون الأسود الدّاكن مع توضيح مكان تموضع الشّكل داخل الطّبعة وإعلام المطبعة باللون المُراد (ذهبي – فضي .. الخ). يُنفّذ هذا النّوع من الطّباعة على الجلد أو الأوراق المُلوّنة غير المطبوعة في الغالب (تُستخدم بشكل كبير في الطّباعة على المصاحف والأجندات المُغلّفة بجلد أو ورق جلدي). التلميع البُقعي Spot UV عبارة عن تقنية جماليّة تُستخدم في مطبوعات المُنتجات أو المجلات أو البطاقات لإضافة لمعة بلاستيكيّة ضمن مواضع مُحدّدة للفت الانتباه، وتُعدّ من أكثر التّقنيات الطّباعيّة الإضافيّة استخدامًا، وتتوفر طبقات مُختلفة من التّلميع البُقعي بحيث تكون النّتيجة ملساء مع السّطح أو تُشعر اللّامس ببروز نافر عن الطبعة. السُلفان Lamination عبارة عن طبقة حماية بلاستيكيّة رقيقة تُلصق بشكل آلي على الطّبعة، تُساهم في حماية الطّبعة من عوامل الجوّ وتزيد الورق أو الكرتون المطبوع متانة، وتُضفي عليه ثقلًا لونيًّا. هُناك نوعان من السُلفان (اللّامع Gloss – والمت أو المطفي Matte ). على المُصمّم أن يكون حريصًا على توجيه المطبعة إلى أفضل نوع يُناسب تصميمه بحسب الشّكل العام للتّصميم وحسب الأسواق الموجّهة إليه. مُلاحظة: يبرز السُلفان اللّميع بشكل أفضل في تصاميم المُنتجات ذات الألوان البرّاقة وتُعطيها شكلًا بلاستيكيًّا لميعًا، أما السُلفان المت أو المطفي تزيد من ثقل المطبوعات التي تحمل الطابع الفخم (مثال: مطويّة "Brochure" لشركة أزياء بألوان بنّية فاتحة وتدرّجات البُني سيكون السُلفان المت أفضل عليه من اللميع). إرشادات عليك اتباعها كمُصمم عند إرسالك التصميم إلى المطبعةللمُنتجات أو المطبوعات ذات الأحرف المقصوصة بطرق غير مألوفة يجب أن تُرفق قوالب القص "die cutting" إلى المطبعة بشكل مُنفصل. رسم قوالب القص بسيط ويُفضّل أن يتم باستخدام برنامج Adobe illustrator نظرًا لدقّة الرّسم، بحيث يُعبّر الخط المُتّصل عن حد القصّ، أما الخط المُتقطّع فيُعبّر عن الطّي (الثّني). يُفضّل إرسال نماذج مطبوعة بشكل مُسبق (إن وجدت) إلى المطبعة لتقوم بدورها بمُطابقة الألوان عند الطّباعة، وإن لم يتوفر الأمر وكان لديك تصميم مُهتم بوصوله إلى أفضل نتيجة خاصّة ترغبها بإمكانك حينها أن تطلب من المطبعة بالتّواجد لديها عند بداية الطّباعة للاطلاع على النّماذج الأوّلية قبل إتمام كامل الطّبعة. معلومات وإرشادات هامّة لضمان أفضل نتائجللحصول على لون صافي اجعل نسبته 100% وباقي النّسب 0%. لاستعراض الألوان الأساسية الأربع بشكل سريع عبر برنامج أدوبي فوتوشوب اضغط Ctrl + 1 و Ctrl + 2 و Ctrl + 3 و Ctrl + 4. يتوجّب عليك كمُصمّم (مُتخصّص في التّصاميم الطّباعيّة) امتلاك كُتيّب (جدول النِمَر اللونيّة - Pantone Color Chart) خاص بالألوان CMYK لسحب أرقام الألوان المرغوبة مُباشرة، وهو يأتي عادة مع الطابعات الكبيرة عند شراءها، لكن بإمكانك البحث عنه بشكل مُنفصل وشراءه عبر أحد المتاجر الإلكترونية. * بالإمكان تحميل الجداول على هيئة ملفات PDF مجانيّة باستخدام الرابط التالي: http://www.tidyform.com/cmyk-color-chart.html حاول على الدّوام استخدام نِمَر لونيّة ثابتة، وخاصة في تصاميم المُنتجات للشركات وأيضاً الهويات Brands، بحيث أنه وببساطة لن تقلق بتغيير المطبعة وستضمن ظهور المطبوعات بنفس درجة اللون بالضبط في كُل مرة. ابتعد عن التدرجات اللونيّة الكثيرة واستخدم التقنيّة التي تجمع بين البساطة والأناقة عبر استخدام ألوان ثابتة واضحة موزّعة بشكل سليم. ابتعد عن الألوان الفاتحة جدًّا (الباهتة) وعلى أقل تقدير اختر كثافة اللون أكثر من 8% حتى تظهر بعد الطباعة، وتذكّر كُلما كانت كثافة اللّون أكثر وقلّ اختلاطه مع ألوان أخرى كُلما كانت النتائج أفضل. استخدم برنامج Adobe illustrator في حالة النّصوص الصّغيرة جدًّا، لأنه يعتمد على التصميم الشُّعاعي عالي الوضوح مهما كبر أو صغر الحجم، بينما Adobe Photoshop يُظهر تكسيرًا في الخطوط الصغيرة جدًّا كونه يعتمد نظام النُقاط Pixels. بالإمكان الدّمج في العمل بين فوتوشوب للرّسوميات والتّعديل على الصّور، وإليستريتور للكتابة. سوف تحتاج أحيانًا كمُصمّم لأن تضع نُصوصًا كتابيّة مُتناهية في الصّغر لسبب صغر حجم المُنتج أو كثرة المعلومات الكتابيّة المطلوبة (كالمُحتويات والقيمة الغذائية التي تُوضع في مواضع مُعينة خلف المُنتج).1 نقطة