كيفية إنشاء خريطة لأماكن السفر المرغوبة باستخدام Gatsby و React Leaflet و Hygraph

دقائق القراءة: 12

السفر متعة لا تضاهيها متعة، ولدينا جميعًا قائمة طويلة من الأماكن التي نحلم بزيارتها، ولكن نادرًا ما نجد الوقت الكافي لتحقيق كل ذلك دفعة واحدة. هنا يأتي دور “قائمة الأماكن المرغوبة للسفر” (Travel Bucket List)! ولكن كيف يمكننا إنشاء تطبيق خرائط مخصص يعرض جميع وجهاتنا المفضلة في مكان واحد؟

ملاحظة: اعتبارًا من يوليو 2022، أصبح اسم GraphCMS هو Hygraph. سيتم استخدام كلا الاسمين للإشارة إلى نفس الخدمة في هذا المقال.

ماذا سنبني؟

سنقوم ببناء تطبيق خرائط متكامل باستخدام Gatsby، يتم إدارة بياناته بواسطة نظام إدارة محتوى (CMS) مثل Hygraph. سيعرض هذا التطبيق علامات (markers) على الخريطة لوجهاتنا، بالإضافة إلى قائمة نصية بسيطة لتلك المواقع التي نرغب في زيارتها.

عرض توضيحي لتطبيق خريطة قائمة السفر المرغوبة

عرض توضيحي لتطبيق خريطة قائمة السفر المرغوبة

سنقوم بتشغيل التطبيق باستخدام قالب Gatsby Starter for Leaflet، ثم سنستخدم Hygraph لإنشاء وإدارة قائمة المواقع الخاصة بخريطتنا!

هل تطبيق الخرائط يبدو معقدًا؟ لا تقلق! إذا لم تكن قد تعاملت مع الخرائط من قبل، فلا تيأس. الأمر ليس بالصعوبة التي تتخيلها. إذا كنت تفضل البدء بأساسيات الخرائط، يمكنك قراءة المزيد حول كيفية عمل الخرائط أولاً.

الخطوة 1: إنشاء تطبيق جديد باستخدام Gatsby Starter Leaflet

سنبدأ باستخدام Gatsby Starter Leaflet. سيوفر لنا هذا القالب تطبيق React أساسيًا مع أدوات الخرائط مدمجة مسبقًا.

إنشاء تطبيق Gatsby جديد باستخدام Gatsby Starter Leaflet

للبدء، انتقل إلى المجلد الذي تريد إنشاء تطبيقك الجديد فيه وقم بتشغيل الأمر التالي:

gatsby new my-travel-bucket-list https://github.com/colbyfayock/gatsby-starter-leaflet

ملاحظة: يمكنك استبدال my-travel-bucket-list بأي اسم تريده. سيتم استخدام هذا الاسم لإنشاء المجلد الجديد للتطبيق.

بمجرد تشغيل الأمر، سيقوم Gatsby بتنزيل القالب وتثبيت التبعيات. بعد اكتمال العملية، انتقل إلى هذا الدليل وقم بتشغيل أمر التطوير:

cd my-travel-bucket-list
yarn develop # أو npm run develop

بمجرد الانتهاء، يجب أن يكون تطبيقك جاهزًا للعمل!

تنظيف بعض الأكواد التجريبية

نظرًا لأننا نستخدم قالبًا جاهزًا (Starter)، فإنه يحتوي على بعض الأكواد التجريبية. دعنا نقوم بتنظيفها لتجنب أي ارتباك.

افتح ملف src/pages/index.js.

أولاً، قم بإزالة كل شيء داخل دالة mapEffect باستثناء السطر الأول، وقم بإعداد اسم مستعار لـ leafletElement ليكون map:

 async function mapEffect ( { leafletElement: map } = {} ) {
  if ( !map ) return ;
 }

بعد ذلك، يمكننا إزالة تعريف markerRef في الجزء العلوي من مكون IndexPage، وإزالة الخاصية ref={markerRef} من مكون <Marker> الخاص بنا، واستيراد useRef بجوار React.

الآن، يمكننا إزالة جميع المتغيرات التي تبدأ بـ popup و time، بما في ذلك:

  • timeToZoom
  • timeToOpenPopupAfterZoom
  • timeToUpdatePopupAfterZoom
  • popupContentHello
  • popupContentGatsby

أخيرًا، يمكنك إزالة جميع الأسطر التالية:

 import L from 'leaflet' ;
...
 import { promiseToFlyTo, getCurrentLocation } from 'lib/map' ;
...
 import gatsby_astronaut from 'assets/images/gatsby-astronaut.jpg' ;
...
 const ZOOM = 10 ;

بمجرد الانتهاء، يجب أن نكون جاهزين للعمل مع تطبيق أساسي يحتوي على خريطة!

تطبيق جديد باستخدام Gatsby Starter Leaflet

تطبيق جديد جاهز مع Gatsby Starter Leaflet

الخطوة 2: إنشاء وإدارة قائمة مواقع السفر باستخدام GraphCMS (Hygraph)

إنشاء حساب GraphCMS (Hygraph)

للبدء مع GraphCMS (الآن Hygraph)، ستحتاج إلى حساب. لن نتناول هذه الخطوة بالتفصيل، ولكن الخبر السار هو أنهم يقدمون خطة مجانية سخية تسهل علينا التسجيل لاستخدامها في عرضنا التوضيحي!

سجل في Hygraph

بدلاً من ذلك، إذا كان لديك حساب بالفعل، يمكنك التأكد من تسجيل دخولك.

إنشاء مشروع GraphCMS (Hygraph) جديد

بمجرد تسجيل الدخول، سنرغب في إنشاء مشروع جديد. سنقوم بإنشاء مشروع يدويًا، لذا بمجرد الوصول إلى لوحة تحكم GraphCMS Dashboard، اختر Create new project:

إنشاء مشروع جديد في GraphCMS

إنشاء مشروع جديد في GraphCMS

هنا، يمكنك إدخال ما تريده لـ Name و Description مثل:

  • Name: My Travel Bucket List
  • Description: The locations that I want to travel to some day!

أسفل ذلك سترى خريطة حيث ستختار Region. هذا هو المكان الذي ستعيش فيه بيانات قاعدة بياناتك، وعلى الرغم من أنه قد لا يهم كثيرًا لأغراضنا، يمكنك اختيار الأقرب إليك.

تكوين مشروع جديد في GraphCMS

تكوين مشروع جديد في GraphCMS

بعد تحديد خياراتك، انقر فوق Create Project.

اختيار الخطة الشخصية في GraphCMS

اختيار الخطة الشخصية في GraphCMS

بعد ذلك، ستظهر لك خيارات الفوترة. نظرًا لأننا نقوم بإنشاء عرض توضيحي فقط، ضمن Personal، حدد Continue، وعند هذه النقطة سننتقل إلى لوحة تحكم مشروع GraphCMS الجديد الخاص بنا.

إنشاء مخطط نموذج محتوى (Content Model Schema) جديد باستخدام GraphCMS (Hygraph)

في GraphCMS (Hygraph)، يشير Content Model إلى نوع معين من البيانات له خصائص محددة مرتبطة به. في حالتنا، سيكون نموذجنا هو Destination (الوجهة)، والذي سيتم تعريفه بواسطة Name (الاسم) و Location (الموقع).

أولاً، انتقل إلى قسم Schema في GraphCMS (Hygraph) في الشريط الجانبي الأيسر وحدد Create Model.

إنشاء نموذج مخطط جديد في GraphCMS

إنشاء نموذج مخطط جديد في GraphCMS

بمجرد التحديد، سترى نافذة منبثقة تطلب بعض المعلومات الإضافية. هنا، يمكنك كتابة “Destination” كـ Display Name، والذي سيملأ أيضًا معظم الحقول الأخرى. سنتركها كما هي.

تكوين نموذج محتوى جديد في GraphCMS

تكوين نموذج محتوى جديد في GraphCMS

لا تتردد في إضافة وصف إذا أردت، ولكنه غير مطلوب. ثم حدد Create model.

الآن بعد أن أصبح لدينا نموذجنا (Model)، نحتاج إلى خصائصنا. أولاً، حدد Single line text في القائمة اليمنى للحقول وأضف Display Name باسم “Name”. سيؤدي هذا أيضًا إلى ملء App Id الذي يمكنك تركه كما هو. ثم انقر فوق Create.

إضافة وتكوين حقل نصي جديد في GraphCMS

إضافة وتكوين حقل نصي جديد في GraphCMS

بعد ذلك، قم بالتمرير لأسفل في خيارات الحقول على اليمين وتحت Location حدد Map. أضف “Location” كـ Display Name، والذي سيحدد App Id كـ “location” والذي يمكنك تركه كما هو. ثم بنفس الطريقة السابقة، انقر فوق Create.

إضافة وتكوين حقل خريطة جديد في GraphCMS

إضافة وتكوين حقل خريطة جديد في GraphCMS

الآن لدينا نموذج محتوى (Content Model) سنستخدمه لإنشاء مواقعنا!

نموذج محتوى الوجهة في GraphCMS

نموذج محتوى الوجهة في GraphCMS

إنشاء مواقعنا

أخيرًا، دعنا ننشئ مواقعنا. انتقل إلى Content في لوحة تحكم GraphCMS (Hygraph)، وتأكد من تحديد Destination ضمن System (يجب أن يكون هو الوحيد)، ثم حدد Create New.

إنشاء محتوى وجهة جديد في GraphCMS

إنشاء محتوى وجهة جديد في GraphCMS

الآن يمكننا البدء في إضافة جميع مواقعنا! أولاً، أضف اسم موقعك في حقل Name، ثم يمكنك استخدام مربع البحث تحت Location للعثور على هذا الموقع على الخريطة.

إضافة عنصر محتوى وجهة جديد في GraphCMS

إضافة عنصر محتوى وجهة جديد في GraphCMS

بمجرد الانتهاء، اضغط على Save and publish. سيؤدي هذا إلى إنشاء موقعك الأول! اتبع نفس الخطوات وقم بإنشاء العديد من المواقع كما تريد.

قائمة عناصر محتوى الوجهة في GraphCMS

قائمة عناصر محتوى الوجهة في GraphCMS

سنستخدم هذه المواقع لخريطتنا وقائمة الأماكن المرغوبة.

الخطوة 3: استعلام بيانات مواقع GraphCMS (Hygraph) باستخدام Gatsby و GraphQL

الآن بعد أن أصبح لدينا مواقعنا، دعنا نستخدمها!

إضافة إضافة (Plugin) إلى Gatsby للاستعلام عن بيانات GraphQL

أولاً، نحتاج إلى إضافة إضافة جديدة إلى مشروع Gatsby الخاص بنا للاستعلام عن بيانات GraphQL. في طرفيتك (terminal)، تأكد من أن خادم التطوير لا يعمل وقم بتشغيل:

yarn add gatsby-source-graphql # أو npm install gatsby-source-graphql

بعد ذلك، افتح ملف gatsby-config.js في جذر مشروعك وأضف ما يلي إلى الإضافات (plugins) الخاصة بك:

{
  resolve: 'gatsby-source-graphql',
  options: {
    typeName: 'GCMS',
    fieldName: 'gcms',
    url: '[API ENDPOINT]',
  }
}

هذا هو ما سيقوم بجلب بياناتنا من GraphCMS (Hygraph)، ولكننا نحتاج إلى نقطة نهاية (endpoint).

العثور على نقطة نهاية API الخاصة بنا لـ GraphCMS (Hygraph)

افتح متصفحك مرة أخرى وتوجه إلى مشروع GraphCMS (Hygraph) الخاص بك. بعد تحديد Settings في قائمة التنقل اليسرى، حدد API Access.

الوصول إلى API في GraphCMS

الوصول إلى API في GraphCMS

قبل أن ننسخ نقطة نهاية API Endpoint الخاصة بنا، نحتاج أولاً إلى تحديث أذوناتنا حتى نتمكن من الاستعلام عن API الخاص بنا. ضمن Public API Permissions، ضع علامة في المربع بجوار Content from stage Published وانقر على Save.

تكوين أذونات API في GraphCMS

تكوين أذونات API في GraphCMS

بعد ذلك، انسخ عنوان URL تحت Endpoints:

نسخ نقطة نهاية API في GraphCMS

نسخ نقطة نهاية API في GraphCMS

والصقها في ملف gatsby-config.js الذي قمنا بتعديله أعلاه:

{
  resolve: 'gatsby-source-graphql',
  options: {
    typeName: 'GCMS',
    fieldName: 'gcms',
    url: 'https: //[region-id].graphcms.com/v2/[project-id]/master',
  },
},

ملاحظة: سيحتوي عنوان URL الخاص بك على قيم فعلية داخل [region-id] و [project-id].

احفظ ملف gatsby-config.js الخاص بك وابدأ تشغيل خادم التطوير مرة أخرى (yarn develop) ونحن جاهزون للانطلاق!

الاستعلام عن مواقعنا عبر GraphQL

أخيرًا، دعنا نستعلم عن بياناتنا بالفعل حتى نتمكن من استخدامها في تطبيقنا. سنقوم بإنشاء React Hook جديد سنتمكن من استخدامه لجلب مواقعنا في أي مكان داخل تطبيقنا.

ضمن src/hooks/index.js، أضف السطر التالي إلى القائمة الموجودة:

 export { default as useDestinations } from './useDestinations' ;

سيسمح لنا هذا باستيراد خطافنا (hook) بشكل أكثر ملاءمة والذي سننشئه لاحقًا.

ضمن src/hooks، أنشئ ملفًا جديدًا باسم useDestinations.js والصق هذا الكود:

 import { graphql, useStaticQuery } from 'gatsby' ;

 export default function useDestinations ( ) {
  const { gcms = {} } = useStaticQuery( graphql `
   query {
    gcms {
     destinations {
      id
      name
      location {
       latitude
       longitude
      }
     }
    }
   }
  ` );

  let { destinations } = gcms;

  return {
   destinations,
  };
 }

هنا، نقوم بالآتي:

  • استيراد أدوات graphql و useStaticQuery من Gatsby.
  • نقوم بإنشاء دالة جديدة (أو خطاف hook) يتم تصديرها افتراضيًا.
  • في هذه الدالة، نستخدم useStaticQuery لإنشاء استعلام GraphQL جديد يطلب من GraphCMS (Hygraph) إرجاع بنية البيانات التي حددناها.
  • يعيد هذا الاستعلام قيمة نقوم بتفكيكها على الفور لجلب كائن gmcs.
  • نقوم بتفكيك destinations من gmcs وإعادتها كجزء من كائن جديد من خطافنا.

باستخدام هذا، يمكننا الآن استخدام خطافنا في أي مكان في تطبيقنا!

توجه إلى ملف src/pages/index.js الخاص بك، أولاً قم باستيراد خطافنا الجديد:

 import { useDestinations } from 'hooks' ;

وفي الجزء العلوي من مكون IndexPage، استعلم عن بياناتنا:

 const { destinations } = useDestinations();

يضع هذا جميع مواقعنا في متغير destinations. يمكننا اختبار ما إذا كان هذا يعمل عن طريق تسجيله في وحدة التحكم:

 console .log( 'destinations' , destinations);

وبمجرد فتح متصفحنا والنظر في وحدة تحكم أدوات مطور الويب، يمكننا رؤية بيانات موقعنا!

تسجيل بيانات الوجهات في وحدة تحكم الويب

تسجيل بيانات الوجهات في وحدة تحكم الويب

الخطوة 4: إنشاء قائمة بالأماكن المرغوبة وإضافتها إلى الخريطة

سنبدأ بإنشاء قائمة نصية بسيطة لوجهاتنا. سيتيح لنا هذا رؤية جميع وجهاتنا بتنسيق سهل القراءة.

إنشاء قائمة نصية لوجهاتنا

داخل IndexPage وفوق “Still Getting Started?”، دعنا نضيف الكود التالي:

<h2>My Destinations</h2>
<ul>
  { destinations.map(destination => {
    const { id, name } = destination;
    return <li key = {id} > { name } </li>
  })}
</ul>

يقوم هذا الكود بالآتي:

  • يضيف عنوانًا جديدًا لقائمتنا.
  • ينشئ قائمة غير مرتبة جديدة (unordered list).
  • يتكرر عبر destinations وينشئ عنصر قائمة جديدًا لكل وجهة يتضمن اسم الموقع.

بمجرد الحفظ وإعادة التحميل، يجب أن نرى قائمتنا أسفل خريطتنا!

قائمة أساسية جديدة للوجهات في التطبيق

قائمة أساسية جديدة للوجهات في التطبيق

تبدو القائمة غريبة بعض الشيء، أليس كذلك؟ ربما نريد تنسيقها بشكل أفضل لتناسب الصفحة.

افتح ملف src/assets/stylesheets/pages/_home.scss وداخل الفئة .home-start، أضف:

 .home-start {
  ...
  ul {
   list-style : none;
   padding : 0 ;
   margin : 1.2em 0 ;
  }
 }

دعنا أيضًا نعدل h2 لتباعد الأشياء بشكل أفضل قليلاً:

 .home-start {
  ...
  h2 {
   margin-top : 2em ;
   & :first-child {
    margin-top : 0 ;
   }
  }
 }

بمجرد الحفظ وإعادة التحميل، يجب أن تبدو أفضل قليلاً.

الوجهات في التطبيق مع أنماط منسقة

الوجهات في التطبيق مع أنماط منسقة

لا تتردد في إجراء تغييرات إضافية، لكننا سنتركها عند هذا الحد في الوقت الحالي.

إضافة وجهاتنا إلى الخريطة

الآن يمكننا أخيرًا إضافة وجهاتنا إلى الخريطة!

داخل مكون <Map> الخاص بنا، لدينا بالفعل <Marker>. يسمح لنا هذا بإضافة علامة بسهولة إلى الخريطة بالنظر إلى موضع. سنأخذ هذا المفهوم ونجمعه مع قائمتنا النصية لإضافة مواقعنا إلى الخريطة.

دعنا نحدث كود <Map> الخاص بنا ليتطابق مع ما يلي:

< Map {...mapSettings}>
  { destinations.map( destination => {
    const { id, name, location } = destination;
    const position = [location.latitude, location.longitude];
    return < Marker key = {id} position = {position} />
  })}
</ Map >

هنا نقوم بالآتي:

  • نتكرر عبر destinations لإنشاء قائمة جديدة ديناميكيًا من المكونات داخل <Map> الخاص بنا.
  • داخل كل تكرار، نقوم بتفكيك بياناتنا من destination.
  • نقوم بإنشاء مصفوفة position جديدة مع خطوط الطول والعرض.
  • نقوم بإنشاء Marker جديد حيث نستخدم موضعنا لإضافته إلى الخريطة.

هذا يعطينا علاماتنا على الخريطة!

علامات لكل وجهة في تطبيق الخرائط

علامات لكل وجهة في تطبيق الخرائط

لكننا نريد معرفة ما هي كل هذه المواقع، لذا دعنا نضيف أيضًا نافذة منبثقة (popup) لكل علامة ستظهر الاسم.

أولاً، نحتاج إلى استيراد Popup من react-leaflet:

 import { Marker, Popup } from 'react-leaflet' ;

ثم، دعنا نحدث مكون <Marker> الخاص بنا لإرجاع:

 return (
  < Marker key = {id} position = {position} >
   < Popup >
    { name }
   </ Popup >
  </ Marker >
 );

وبمجرد الحفظ وإعادة فتح خريطتنا، يمكنك الآن النقر على كل علامة ورؤية اسم وجهاتنا!

نافذة منبثقة لكل علامة وجهة في تطبيق الخرائط

نافذة منبثقة لكل علامة وجهة في تطبيق الخرائط

قبل الانتهاء، قم بتوسيط الخريطة

سابقًا، كانت خريطتنا التجريبية متمركزة حول واشنطن العاصمة. دعنا نحدث ذلك إلى مركز العالم نظرًا لأن خريطتنا لا تركز على الولايات المتحدة.

حدث متغير LOCATION إلى:

 const LOCATION = {
  lat : 0 ,
  lng : 0 ,
 };

وبهذا، أصبح لدينا خريطتنا جاهزة!

تطبيق الخرائط النهائي مع العلامات والنوافذ المنبثقة لكل وجهة

تطبيق الخرائط النهائي مع العلامات والنوافذ المنبثقة لكل وجهة

ميزات إضافية يمكننا إضافتها إلى تطبيقنا

إليك بعض الأفكار لتحسين تطبيقك وتوسيع وظائفه:

  • إضافة طريقة لتحديد كل موقع تم زيارته:
    في GraphCMS (Hygraph)، يمكنك إضافة حقل جديد إلى نموذج محتوى Destination الخاص بك يسمح لك بتحديد ما إذا كنت قد زرت كل موقع أم لا. باستخدام هذه القيمة، يمكننا إضافتها إلى استعلامنا وتحديث خريطتنا بنوع من المؤشرات، مثل علامة صح، لإظهار أننا قد أتممنا زيارة هذا الموقع من قائمة الأماكن المرغوبة لدينا!
  • تخصيص أنماط خلفية الخريطة:
    نحن نستخدم إصدارًا عامًا من OpenStreetMap وهو مفتوح المصدر، ولكن Mapbox يقدم بعض الخرائط الرائعة التي يمكننا استخدامها لجعلها تبدو أكثر إثارة للإعجاب. إذا كنت ترغب في البدء في تغيير أنماط خريطتك، يمكنك مراجعة هذا الدليل الآخر لمعرفة كيفية استخدام Mapbox.
  • تنسيق علامات الخريطة بصورة مخصصة:
    يمكنك مراجعة دليل الفيديو الخاص بي حول كيفية تغيير العلامات إلى صورة مخصصة. يمكنك المضي قدمًا في ذلك واستخدام الميزة المذكورة أعلاه لإظهار صورة علامة مختلفة ديناميكيًا عند تحديد موقع كـ “تمت زيارته”.

هل ترغب في تعلم المزيد عن الخرائط؟

اطلع على بعض دروسي ومقاطع الفيديو الأخرى:

ما هي الأماكن التي تتمنى زيارتها في قائمة سفرك؟ شاركنا أفكارك على تويتر!

الخلاصة التقنية

لقد استعرضنا في هذا المقال عملية شاملة لبناء تطبيق خرائط تفاعلي باستخدام أحدث التقنيات في تطوير الويب. من خلال دمج Gatsby كإطار عمل ثابت سريع، و React Leaflet لتقديم الخرائط الديناميكية، و Hygraph (المعروف سابقًا بـ GraphCMS) كحل headless CMS لإدارة المحتوى، تمكنا من إنشاء تجربة مستخدم غنية ومرنة. تبرز أهمية هذه الأدوات في قدرتها على تبسيط عملية تطوير تطبيقات الخرائط المعقدة، مع توفير أداء عالٍ وقابلية للتوسع. إن استخدام GraphQL للاستعلام عن البيانات من Hygraph يضمن كفاءة عالية في جلب البيانات المطلوبة فقط، مما يعزز من سرعة التطبيق واستجابته. هذا النهج يفتح آفاقًا واسعة للمطورين لإنشاء تطبيقات خرائط مخصصة تلبي احتياجات متنوعة، سواء كانت لقوائم السفر الشخصية أو لمشاريع تجارية أكبر.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *