كيف يساعدني موقع الويب الخاص بي المستند إلى واجهة برمجة التطبيقات في السفر حول العالم
نشرت: 2022-03-10(هذا منشور برعاية.) مؤخرًا ، قررت إعادة إنشاء موقع الويب الخاص بي ، لأنه كان عمره ست سنوات وبدا - بأدب - "قديمًا" بعض الشيء. كان الهدف هو تضمين بعض المعلومات عني ، ومنطقة مدونة ، وقائمة بمشروعاتي الجانبية الأخيرة ، والأحداث القادمة.
أثناء قيامي بأعمال العميل من وقت لآخر ، كان هناك شيء واحد لا أرغب في التعامل معه - قواعد البيانات ! في السابق ، قمت ببناء مواقع WordPress لكل من أرادني ذلك. كان جزء البرمجة عادةً ممتعًا بالنسبة لي ، لكن الإصدارات ونقل قواعد البيانات إلى بيئات مختلفة والنشر الفعلي كانت مزعجة دائمًا. لا يقدم مقدمو خدمات الاستضافة الرخيصة سوى واجهات ويب ضعيفة لإعداد قواعد بيانات MySQL وكان الوصول إلى FTP لتحميل الملفات هو أسوأ جزء في Alwa. لم أرغب في التعامل مع هذا لموقعي الشخصي.
لذلك كانت المتطلبات التي أملكها لإعادة التصميم هي:
- مجموعة تقنيات حديثة تعتمد على JavaScript وتقنيات الواجهة الأمامية.
- حل إدارة المحتوى لتحرير المحتوى من أي مكان.
- موقع جيد الأداء بنتائج سريعة.
في هذا المقال ، أود أن أوضح لكم ما قمت ببنائه وكيف تبين أن موقع الويب الخاص بي كان رفيقي اليومي بشكل مفاجئ.
تحديد نموذج المحتوى
يبدو أن نشر الأشياء على الويب أمر سهل. اختر نظام إدارة المحتوى (CMS) الذي يوفر محرر WYSIWYG ( W hat Y ou S ee I s W hat Y ou G et) لكل صفحة مطلوبة ويمكن لجميع المحررين إدارة المحتوى بسهولة. هذا كل شيء ، أليس كذلك؟
بعد إنشاء العديد من مواقع الويب للعملاء ، بدءًا من المقاهي الصغيرة إلى الشركات الناشئة النامية ، اكتشفت أن محرر WYSIWYG المقدس ليس دائمًا الحل الفضي الذي نبحث عنه جميعًا. تهدف هذه الواجهات إلى تسهيل إنشاء مواقع الويب ، ولكن هنا تأتي النقطة:
بناء مواقع الويب ليس بالأمر السهل
لإنشاء محتوى موقع ويب وتحريره دون كسره باستمرار ، يجب أن تكون لديك معرفة وثيقة بـ HTML وأن تفهم على الأقل قدرًا ضئيلاً من CSS. هذا ليس شيئًا يمكنك توقعه من المحررين.
لقد رأيت تخطيطات معقدة مروعة تم إنشاؤها باستخدام محرري WYSIWYG ولا يمكنني أن أبدأ في تسمية جميع المواقف التي ينهار فيها كل شيء لأن النظام هش للغاية. تؤدي هذه المواقف إلى معارك وانزعاج حيث تلوم جميع الأطراف بعضها البعض على شيء كان لا مفر منه. حاولت دائمًا تجنب هذه المواقف وإنشاء بيئات مريحة ومستقرة للمحررين لتجنب رسائل البريد الإلكتروني الغاضبة التي تصرخ ، "ساعدوا! يتم تقسيم كل شيء."
يوفر لك المحتوى المنظم بعض المشاكل
لقد تعلمت بسرعة إلى حد ما أن الأشخاص نادرًا ما يكسرون الأشياء عندما أقسم كل محتوى موقع الويب المطلوب إلى عدة أجزاء ، كل منها مرتبط ببعضها البعض دون التفكير في أي تمثيل. في WordPress ، يمكن تحقيق ذلك باستخدام أنواع المنشورات المخصصة. يمكن أن يشتمل كل نوع منشور مخصص على العديد من الخصائص مع حقل نصي يسهل فهمه. لقد دفنت مفهوم التفكير في الصفحات تمامًا.

كانت وظيفتي هي توصيل أجزاء المحتوى وبناء صفحات ويب من كتل المحتوى هذه. هذا يعني أن المحررين لم يكونوا قادرين إلا على إجراء تغييرات بصرية قليلة ، إن وجدت ، على مواقعهم الإلكترونية. كانوا مسؤولين عن المحتوى والمحتوى فقط. يجب أن أقوم بإجراء تغييرات بصرية - لا يمكن للجميع تصميم الموقع ، ويمكننا تجنب بيئة هشة. بدا هذا المفهوم وكأنه مقايضة كبيرة وكان عادةً موضع ترحيب.
اكتشفت لاحقًا أن ما كنت أفعله هو تحديد نموذج المحتوى. تحدد راشيل لوفينجر ، في مقالتها الممتازة "نمذجة المحتوى: مهارة رئيسية" ، نموذج المحتوى على النحو التالي:
"يوثق نموذج المحتوى جميع أنواع المحتوى المختلفة التي ستوفرها لمشروع معين. يحتوي على تعريفات مفصلة لكل عناصر نوع المحتوى وعلاقاتهم ببعضهم البعض ".
لقد نجح البدء بنمذجة المحتوى بشكل جيد لمعظم العملاء ، باستثناء عميل واحد.
"ستيفان ، أنا لا أحدد مخطط قاعدة البيانات الخاص بك!"
كانت فكرة هذا المشروع الواحد هي إنشاء موقع ويب ضخم من شأنه أن يخلق الكثير من حركة المرور العضوية من خلال توفير الكثير من المحتوى - في جميع الأشكال المعروضة عبر العديد من الصفحات والأماكن المختلفة. قمت بإعداد اجتماع لمناقشة استراتيجيتنا للتعامل مع هذا المشروع.
أردت تحديد جميع الصفحات ونماذج المحتوى التي يجب تضمينها. لا يهم ما هو عنصر واجهة المستخدم الصغير أو الشريط الجانبي الذي يدور في ذهن العميل ، فقد أردت تحديده بوضوح. كان هدفي هو إنشاء بنية محتوى قوية تجعل من الممكن توفير واجهة سهلة الاستخدام للمحررين وتوفر بيانات قابلة لإعادة الاستخدام لعرضها بأي تنسيق يمكن التفكير فيه.
اتضح أن فكرة هذا المشروع لم تكن واضحة تمامًا ، ولم أستطع الحصول على إجابات لجميع أسئلتي. لم يفهم قائد المشروع أنه يجب علينا البدء بنمذجة المحتوى المناسبة (وليس التصميم والتطوير). بالنسبة له ، كان هذا مجرد طن من الصفحات. لا يبدو أن المحتوى المكرر ومناطق النص الضخمة لإضافة كمية هائلة من النص يمثل مشكلة. في ذهنه ، كانت الأسئلة التي لدي حول الهيكلية فنية ، ولا ينبغي أن يقلقوا بشأنها. لجعل قصة Lo'g قصيرة ، لم أفعل المشروع.
الشيء المهم هو أن نمذجة المحتوى لا تتعلق بقواعد البيانات.
يتعلق الأمر بجعل المحتوى الخاص بك في المتناول ومثبتًا في المستقبل. إذا لم تحدد احتياجات المحتوى الخاص بك عند بدء المشروع ، فسيكون من الصعب جدًا ، إن لم يكن من المستحيل ، إعادة استخدامه لاحقًا.
نمذجة المحتوى المناسب هي مفتاح مواقع الويب الحالية والمستقبلية.
مضمون: CMS مقطوعة الرأس
كان من الواضح أنني أردت اتباع نموذج محتوى جيد لموقعي أيضًا. ومع ذلك ، كان هناك شيء آخر. لم أرغب في التعامل مع طبقة التخزين لإنشاء موقع الويب الجديد الخاص بي ، لذلك قررت استخدام Contentful ، وهو نظام إدارة محتوى بدون رأس ، والذي (إخلاء المسؤولية الكامل!) أعمل عليه حاليًا. تعني كلمة "بدون رأس" أن هذه الخدمة تقدم واجهة ويب لإدارة المحتوى في السحابة وتوفر واجهة برمجة تطبيقات تعيد بياناتي بتنسيق JSON. ساعدني اختيار نظام إدارة المحتوى هذا على أن أكون منتجًا على الفور حيث كان لديّ واجهة برمجة تطبيقات متاحة في غضون دقائق ولم يكن عليّ التعامل مع أي إعداد للبنية التحتية. يوفر Contentful أيضًا خطة مجانية مثالية للمشاريع الصغيرة ، مثل موقع الويب الشخصي الخاص بي.
يبدو استعلام المثال للحصول على جميع منشورات المدونة كما يلي:
<a href="https://cdn.contentful.com/spaces/space_id/entries?access_token=access_token&content_type=post">https://cdn.contentful.com/spaces/space_id/entries?access_token=access_token&content_type=post</a>
ويبدو الرد في صيغة مختصرة كالتالي:
{ "sys": { "type": "Array" }, "total": 7, "skip": 0, "limit": 100, "items": [ { "sys": { "space": {...}, "id": "455OEfg1KUskygWUiKwmkc", "type": "Entry", "createdAt": "2016-07-29T11:53:52.596Z", "updatedAt": "2016-11-09T21:07:19.118Z", "revision": 12, "contentType": {...}, "locale": "en-US" }, "fields": { "title": "How to React to Changing Environments Using matchMedia", "excerpt": "...", "slug": "how-to-react-to-changing-environments-using-match-media", "author": [...], "body": "...", "date": "2014-12-26T00:00+02:00", "comments": true, "externalUrl": "https://4waisenkinder.de/blog/2014/12/26/handle-environment-changes-via-window-dot-matchmedia/" }, {...}, {...}, {...}, {...}, {...}, {...} ] } }
الجزء الرائع في Contentful هو أنه رائع في نمذجة المحتوى ، وهو ما طلبته. باستخدام واجهة الويب المتوفرة ، يمكنني تحديد جميع أجزاء المحتوى المطلوبة بسرعة. يُطلق على تعريف نموذج محتوى معين في Contentful نوع المحتوى. من الجيد الإشارة هنا إلى القدرة على صياغة العلاقات بين عناصر المحتوى. على سبيل المثال ، يمكنني بسهولة توصيل المؤلف بمنشور مدونة. يمكن أن ينتج عن هذا أشجار بيانات منظمة ، والتي تعتبر مثالية لإعادة الاستخدام في حالات الاستخدام المختلفة.

لذلك ، قمت بإعداد نموذج المحتوى الخاص بي دون التفكير في أي صفحات قد أرغب في إنشائها في المستقبل.

كانت الخطوة التالية هي معرفة ما أريد أن أفعله بهذه البيانات. سألت مصممًا أعرفه ، فخرج بصفحة فهرس للموقع الإلكتروني بالهيكل التالي.

عرض صفحات HTML باستخدام Node.js
الآن جاء الجزء الصعب. حتى الآن ، لم أضطر للتعامل مع التخزين وقواعد البيانات ، وهو ما كان إنجازًا رائعًا بالنسبة لي. لذا ، كيف يمكنني إنشاء موقع الويب الخاص بي عندما لا يتوفر لدي سوى واجهة برمجة تطبيقات؟
كان نهجي الأول هو نهج افعل ذلك بنفسك. بدأت في كتابة برنامج نصي بسيط من Node.js يسترد البيانات ويخرج بعض HTML منه.
استوفى عرض جميع ملفات HTML مقدمًا أحد متطلباتي الرئيسية. يمكن تقديم HTML الثابت بسرعة كبيرة.
لذا ، دعونا نلقي نظرة على النص الذي استخدمته.
'use strict'; const contentful = require('contentful'); const template = require('lodash.template'); const fs = require('fs'); // create contentful client with particular credentials const client = contentful.createClient({ space: 'your_space_id', accessToken: 'your_token' }); // cache templates to not read // them over and over again const TEMPLATES = { index : template(fs.readFileSync(`${__dirname}/templates/index.html`)) }; // fetch all the data Promise.all([ // get posts client.getEntries({content_type: 'content_type_post_id'}), // get events client.getEntries({content_type: 'content_type_event_id'}), // get projects client.getEntries({content_type: 'content_type_project_id'}), // get talk client.getEntries({content_type: 'content_type_talk_id'}), // get specific person client.getEntries({'sys.id': 'person_id'}) ]) .then(([posts, events, projects, talks, persons]) => { const renderedHTML = TEMPLATES.index({ posts, events, projects, talks, person : persons.items[0] }) fs.writeFileSync(`${__dirname}/build/index.html`, renderedHTML); console.log('Rendered HTML'); }) .catch(console.error);
<!doctype html> <html lang="en"> <head> <!-- ... --> </head> <body> <!-- ... --> <h2>Posts</h2> <ul> <% posts.items.forEach( function( talk ) { %> <li><%- talk.fields.title %> <% }) %> </ul> <!-- ... --> </body> </html>
هذا يعمل بشكل جيد. يمكنني إنشاء موقع الويب المطلوب بطريقة مرنة تمامًا ، واتخاذ جميع القرارات المتعلقة بهيكل الملف ووظائفه. لم يكن عرض أنواع صفحات مختلفة بمجموعات بيانات مختلفة تمامًا مشكلة على الإطلاق. يعرف كل من حارب قواعد وبنية نظام إدارة محتوى موجود مزود بعرض HTML أن الحرية الكاملة يمكن أن تكون شيئًا ممتازًا. على وجه الخصوص ، عندما يصبح نموذج البيانات أكثر تعقيدًا بمرور الوقت بما في ذلك العديد من العلاقات - فإن المرونة تؤتي ثمارها.
في هذا البرنامج النصي Node.js ، يتم إنشاء عميل Contentful SDK ويتم جلب جميع البيانات باستخدام طريقة العميل getEntries
. جميع الطرق المقدمة من العميل مدفوعة بالوعود ، مما يجعل من السهل تجنب عمليات الاسترجاعات المتداخلة بعمق. بالنسبة للقوالب ، قررت استخدام محرك قالب لوداش. أخيرًا ، لقراءة الملف وكتابته ، يقدم Node.js وحدة fs
الأصلية ، والتي تُستخدم بعد ذلك لقراءة القوالب وكتابة HTML الذي تم تقديمه.
ومع ذلك ، كان هناك جانب سلبي واحد لهذا النهج. لقد كان مجرد عظام. حتى عندما كانت هذه الطريقة مرنة تمامًا ، شعرت وكأنها إعادة اختراع العجلة. ما كنت أقوم ببنائه كان في الأساس مولد موقع ثابت ، وهناك الكثير منهم بالفعل. حان الوقت للبدء من جديد.
الذهاب لمولد موقع ثابت حقيقي
عادةً ما تتعامل مولدات المواقع الثابتة الشهيرة ، على سبيل المثال ، Jekyll أو Middleman ، مع ملفات Markdown التي سيتم تقديمها إلى HTML. يعمل المحررون مع هؤلاء ، ويتم إنشاء موقع الويب باستخدام أمر CLI. كان هذا النهج يفشل في أحد متطلباتي الأولية ، على الرغم من ذلك. أردت أن أكون قادرًا على تحرير الموقع أينما كنت ، ولا أعتمد على الملفات الموجودة على جهاز الكمبيوتر الخاص بي.
كانت فكرتي الأولى هي تقديم ملفات Markdown هذه باستخدام واجهة برمجة التطبيقات. على الرغم من أن هذا كان سينجح ، إلا أنه لم يكن على ما يرام. عرض ملفات Markdown للتحويل إلى HTML لاحقًا كانت لا تزال خطوتان لا تقدمان فائدة كبيرة مقارنة بحلي الأولي.

لحسن الحظ ، هناك تكاملات Contentful ، على سبيل المثال Metalsmith و Middleman. لقد قررت استخدام Metalsmith لهذا المشروع ، كما هو مكتوب في Node.js a'd لم أرغب في إحضار تبعية Ruby.
Metalsmith يحول الملفات من مجلد مصدر ويضعها في مجلد وجهة. لا يجب بالضرورة أن تكون هذه الملفات ملفات Markdown. يمكنك أيضًا استخدامه لتحويل Sass أو تحسين صورك. لا توجد حدود ، وهي مرنة حقًا.
باستخدام التكامل Contentful ، تمكنت من تحديد بعض الملفات المصدر التي تم أخذها كملفات تكوين ويمكن بعد ذلك إحضار كل ما هو مطلوب من واجهة برمجة التطبيقات.
--- title: Blog contentful: content_type: content_type_id entry_filename_pattern: ${ fields.slug } entry_template: article.html order: '-fields.date' filter: include: 5 layout: blog.html description: >- Recent articles by Stefan Judis. ---
يعرض هذا التكوين كمثال منطقة منشور المدونة مع ملف blog.html
الأصلي ، بما في ذلك استجابة طلب واجهة برمجة التطبيقات ، ولكنه يعرض أيضًا العديد من الصفحات الفرعية باستخدام نموذج article.html
. يتم تحديد أسماء الملفات للصفحات الفرعية من خلال entry_filename_pattern
.
كما ترى ، بشيء من هذا القبيل ، يمكنني إنشاء صفحاتي بسهولة. عمل هذا الإعداد بشكل مثالي للتأكد من أن جميع الصفحات تعتمد على API.
ربط الخدمة بمشروعك
كان الجزء المفقود الوحيد هو توصيل الموقع بخدمة CMS وإعادة عرضه عند تحرير أي محتوى. الحل لهذه المشكلة - webhooks ، التي قد تكون على دراية بها بالفعل إذا كنت تستخدم خدمات مثل GitHub.
Webhooks عبارة عن طلبات يتم إجراؤها بواسطة البرنامج كخدمة إلى نقطة نهاية محددة مسبقًا والتي تُعلمك بحدوث شيء ما. يمكن لـ GitHub ، على سبيل المثال ، إعادة إرسال رد عندما فتح شخص ما طلب سحب في أحد مستودعاتك. فيما يتعلق بإدارة المحتوى ، يمكننا تطبيق نفس المبدأ هنا. عندما يحدث شيء ما مع المحتوى ، قم بإجراء اختبار ping على نقطة نهاية واجعل بيئة معينة تتفاعل معها. في حالتنا ، هذا يعني إعادة تصيير HTML باستخدام metalmith.
لقبول خطافات الويب ، ذهبت أيضًا إلى حل JavaScript. يتيح موفر الاستضافة الذي أختاره (Uberspace) تثبيت Node.js واستخدام JavaScript على جانب الخادم.
const http = require('http'); const exec = require('child_process').exec; const server = http.createServer((req, res) => { res.setHeader('Content-Type', 'text/plain'); // check for secret header // to not open up this endpoint for everybody if (req.headers.secret === 'YOUR_SECRET') { res.end('ok'); // wait for the CDN to // invalidate the data setTimeout(() => { // execute command exec('npm start', { cwd: __dirname }, (error) => { if (error) { return console.log(error); } console.log('Rebuilt success'); }); }, 1000 * 120 ); } else { res.end('Not allowed'); } }); console.log('Started server at 8000'); server.listen(8000);
تبدأ هذه البرامج النصية خادم HTTP بسيطًا على المنفذ 8000. وتتحقق من الطلبات الواردة للحصول على رأس مناسب للتأكد من أنها خطاف الويب من Contentful. إذا تم تأكيد الطلب باعتباره webhook ، يتم تنفيذ الأمر المحدد مسبقًا npm start
لإعادة عرض جميع صفحات HTML. قد تتساءل عن سبب وجود مهلة في المكان. هذا مطلوب لإيقاف الإجراءات مؤقتًا للحظة حتى يتم إبطال البيانات الموجودة في السحابة لأن البيانات المخزنة يتم تقديمها من CDN.
اعتمادًا على بيئتك ، قد لا يكون خادم HTTP هذا متاحًا للوصول إلى الإنترنت. يتم تقديم موقعي باستخدام خادم اباتشي ، لذلك كنت بحاجة إلى إضافة قاعدة إعادة كتابة داخلية لجعل خادم العقدة قيد التشغيل متاحًا للوصول إلى الإنترنت.
# add node endpoint to enable webhooks RewriteRule ^rerender/(.*) https://localhost:8000/$1 [P]
API- البيانات المنظمة أولاً: أفضل الأصدقاء إلى الأبد
في هذه المرحلة ، تمكنت من إدارة جميع بياناتي في السحابة وسيتفاعل موقع الويب الخاص بي وفقًا لذلك بعد التغييرات.
التكرار في كل مكان
يعد التواجد على الطريق جزءًا مهمًا من حياتي ، لذلك كان من الضروري الحصول على معلومات ، مثل موقع مكان معين أو الفندق الذي حجزته ، في متناول يدي مباشرةً - وعادةً ما يتم تخزينه في جدول بيانات Google. الآن ، تم نشر المعلومات عبر جدول بيانات ، والعديد من رسائل البريد الإلكتروني ، والتقويم الخاص بي ، وكذلك على موقع الويب الخاص بي.
كان علي أن أعترف ، لقد خلقت الكثير من تكرار البيانات في التدفق اليومي الخاص بي.
لحظة البيانات المنظمة
حلمت بمصدر واحد للحقيقة (يفضل على هاتفي) لأرى بسرعة الأحداث القادمة ، ولكن أيضًا للحصول على معلومات إضافية حول الفنادق والأماكن. لا تحتوي الأحداث المدرجة على موقع الويب الخاص بي على جميع المعلومات في هذه المرحلة ، ولكن من السهل حقًا إضافة حقول جديدة إلى نوع المحتوى في Contentful. لذلك ، أضفت الحقول المطلوبة إلى نوع محتوى "الحدث".
لم يكن وضع هذه المعلومات في موقع الويب الخاص بي CMS في نيتي أبدًا ، حيث لا ينبغي عرضها عبر الإنترنت ، لكن الوصول إليها عبر واجهة برمجة التطبيقات جعلني أدرك أنه يمكنني الآن القيام بأشياء مختلفة تمامًا باستخدام هذه البيانات.

إنشاء تطبيق أصلي باستخدام JavaScript
لطالما كان إنشاء تطبيقات للجوال موضوعًا لسنوات حتى الآن ، وهناك عدة طرق لذلك. تعد تطبيقات الويب التقدمية (PWA) موضوعًا ساخنًا بشكل خاص هذه الأيام. باستخدام العاملين في الخدمة وبيان تطبيق الويب ، من الممكن بناء تجارب شبيهة بالتطبيقات كاملة تنتقل من أيقونة الشاشة الرئيسية إلى السلوك المدار في وضع عدم الاتصال باستخدام تقنيات الويب.
هناك جانب سلبي واحد لذكره. إن تطبيقات الويب التقدمية آخذة في الازدياد ، لكنها لم تصل بعد تمامًا. عمال الخدمة ، على سبيل المثال ، غير مدعومين على Safari اليوم وفقط "قيد الدراسة" من جانب Apple حتى الآن. كان هذا بمثابة كسر للصفقات بالنسبة لي لأنني كنت أرغب في الحصول على تطبيق غير متصل بالإنترنت على أجهزة iPhone أيضًا.
لذلك بحثت عن بدائل. كان أحد أصدقائي مهتمًا جدًا بـ NativeScript واستمر في إخباري عن هذه التكنولوجيا الجديدة إلى حد ما. NativeScript هو إطار عمل مفتوح المصدر لإنشاء تطبيقات جوال أصلية باستخدام JavaScript ، لذلك قررت أن أجربه.
التعرف على NativeScript
يستغرق إعداد NativeScript بعض الوقت لأنه يتعين عليك تثبيت الكثير من الأشياء لتطويرها لبيئات الهاتف المحمول الأصلية. سيتم إرشادك خلال عملية التثبيت عند تثبيت أداة سطر أوامر NativeScript لأول مرة باستخدام npm install nativescript -g
.
بعد ذلك ، يمكنك استخدام أوامر السقالات لإعداد مشاريع جديدة: tns create MyNewApp
ومع ذلك ، هذا ليس ما فعلته. كنت أقوم بمسح الوثائق ووجدت نموذجًا لتطبيق إدارة البقالة المدمج في NativeScript. لذلك أخذت هذا التطبيق ، وحفرت في الكود ، وقمت بتعديله خطوة بخطوة ، ليناسب احتياجاتي.
لا أريد الغوص بعمق في هذه العملية ، ولكن إنشاء قائمة تبحث فيها بكل المعلومات التي أردتها ، لم يستغرق وقتًا طويلاً.
يلعب NativeScript جيدًا مع Angular 2 ، والذي لم أكن أرغب في تجربته هذه المرة لأن اكتشاف NativeScript نفسه كان كبيرًا بدرجة كافية. في NativeScript ، عليك كتابة "طرق عرض". يتكون كل عرض من ملف XML يحدد التخطيط الأساسي و JavaScript اختياري و CSS. يتم تحديد كل هذه في مجلد واحد لكل عرض.

يمكن تحقيق عرض قائمة بسيطة باستخدام قالب XML مثل هذا:
<!-- call JavaScript function when ready --> <Page loaded="loaded"> <ActionBar title="All Travels" /> <!-- make it scrollable when going too big --> <ScrollView> <!-- iterate over the entries in context --> <ListView items="{{ entries }}"> <ListView.itemTemplate> <Label text="{{ fields.name }}" textWrap="true" class="headline"/> </ListView.itemTemplate> </ListView> </ScrollView> </Page>
أول شيء يحدث هنا هو تحديد عنصر الصفحة. داخل هذه الصفحة ، قمت بتحديد ActionBar
لمنحه مظهر Android الكلاسيكي بالإضافة إلى عنوان مناسب. قد يكون بناء الأشياء للبيئات المحلية أمرًا صعبًا بعض الشيء في بعض الأحيان. على سبيل المثال ، لتحقيق سلوك التمرير العملي ، يجب عليك استخدام "ScrollView". آخر شيء بعد ذلك ، ببساطة تكرار الأحداث الخاصة بي باستخدام ListView
. بشكل عام ، شعرت أنه بسيط جدًا!
ولكن من أين تأتي هذه الإدخالات التي تستخدم في العرض؟ اتضح أن هناك كائن سياق مشترك يمكن استخدامه لذلك. عند قراءة XML لطريقة العرض ، ربما لاحظت بالفعل أن الصفحة بها مجموعة سمات loaded
. من خلال تعيين هذه السمة ، أخبر العرض باستدعاء وظيفة JavaScript معينة عند تحميل الصفحة.
يتم تحديد وظيفة JavaScript هذه في ملف JS المعتمد. يمكن الوصول إليها بمجرد تصديرها باستخدام شيء exports.something
. لإضافة ربط البيانات ، كل ما يتعين علينا القيام به هو تعيين جديد يمكن ملاحظته لخاصية الصفحة bindingContext
. تنبعث الملاحظات في NativeScript من أحداث propertyChange
اللازمة للتفاعل مع تغييرات البيانات داخل "العروض" ، ولكن لا داعي للقلق بشأن ذلك ، لأنه يعمل خارج الصندوق.
const context = new Observable({ entries: null}); const fetchModule = require('fetch'); // export loaded to be called from // List.xml when everything is loaded exports.loaded = (args) => { const page = args.object; page.bindingContext = context; fetchModule.fetch( `https://cdn.contentful.com/spaces/${config.space}/entries?access_token=${config.cda.token}&content_type=event&order=fields.start`, { method: "GET", headers: { 'Content-Type': 'application/json' } } ) .then(response => response.json()) .then(response => context.set('entries', response.items)); }
آخر شيء هو جلب البيانات وتعيينها على السياق. يمكن القيام بذلك باستخدام وحدة fetch
الخاصة بـ NativeScript. هنا تستطيع أن ترى النتيجة.

لذا ، كما ترى - فإن إنشاء قائمة بسيطة باستخدام NativeScript ليس بالأمر الصعب حقًا. قمت فيما بعد بتوسيع التطبيق بعرض آخر بالإضافة إلى وظائف إضافية لفتح عناوين معينة في خرائط Google وعروض الويب لإلقاء نظرة على مواقع الويب الخاصة بالأحداث.
شيء واحد يجب الإشارة إليه هنا هو أن NativeScript لا يزال جديدًا تمامًا ، مما يعني أن المكونات الإضافية الموجودة على npm لا تحتوي عادةً على الكثير من التنزيلات أو النجوم على GitHub. أزعجني هذا في البداية ، لكنني استخدمت العديد من المكونات الأصلية (زر الكتابة الأصلي العائم ، وعرض الويب المتقدم الأصلي ، والنص الأصلي ، pulltorefresh) التي ساعدتني في تحقيق تجربة أصلية وعملت جميعها بشكل جيد.
يمكنك مشاهدة النتيجة المحسنة هنا:

كلما زاد عدد الوظائف التي أضعها في هذا التطبيق ، زاد إعجابي به وزادت استخدامه. أفضل جزء هو أنني أستطيع التخلص من تكرار البيانات ، وإدارة البيانات كلها في مكان واحد ، مع التحلي بالمرونة الكافية لعرضها في حالات الاستخدام المختلفة.
الصفحات بالأمس: محتوى منظم يعيش طويلاً!
أظهر لي بناء هذا التطبيق مرة أخرى أن مبدأ وجود بيانات بتنسيق الصفحة أصبح شيئًا من الماضي. لا نعرف إلى أين ستذهب بياناتنا - علينا أن نكون مستعدين لعدد غير محدود من حالات الاستخدام.
بالنظر إلى الوراء ، ما حققته هو:
- وجود نظام إدارة محتوى في السحابة
- عدم الاضطرار للتعامل مع صيانة قاعدة البيانات
- حزمة تقنية JavaScript كاملة
- وجود موقع ثابت فعال
- امتلاك تطبيق Android للوصول إلى المحتوى الخاص بي في كل مرة وفي كل مكان
والجزء الأهم:
ساعدني تنظيم المحتوى الخاص بي وإمكانية الوصول إليه على تحسين حياتي اليومية.
قد تبدو حالة الاستخدام هذه تافهة بالنسبة لك الآن ، ولكن عندما تفكر في المنتجات التي تصنعها كل يوم - فهناك دائمًا المزيد من حالات الاستخدام للمحتوى الخاص بك على منصات مختلفة. اليوم ، نقبل أن الأجهزة المحمولة قد تجاوزت أخيرًا بيئات سطح المكتب في المدرسة القديمة ، لكن منصات مثل السيارات والساعات وحتى الثلاجات تنتظر بالفعل تسليط الضوء عليها. لا أستطيع حتى التفكير في حالات الاستخدام التي ستأتي.
لذلك ، دعونا نحاول أن نكون مستعدين ونضع محتوى منظمًا في المنتصف لأنه في النهاية لا يتعلق الأمر بمخططات قواعد البيانات - بل يتعلق بالبناء للمستقبل.
مزيد من القراءة على SmashingMag:
- تجريف الويب باستخدام Node.js
- الإبحار باستخدام Sails.js: إطار على غرار MVC لـ Node.js
- 40 أيقونة سفر لتجميل تصاميمك
- مقدمة مفصلة لحزمة الويب