بناء معرض صور احترافي باستخدام Gatsby و Cloudinary: دليل شامل

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

مقدمة إلى تطوير الويب الحديث باستخدام JAMstack

وفقًا لماثياس بيلمان (Mathias Biilmann)، الرئيس التنفيذي والمؤسس المشارك لشركة Netlify، فإن JAMstack هو "بنية تطوير ويب حديثة تعتمد على JavaScript من جانب العميل، وواجهات برمجة تطبيقات (APIs) قابلة لإعادة الاستخدام، وMarkup مُنشأ مسبقًا". تتمثل الجوانب الرئيسية لتطبيق JAMstack فيما يلي:

  • يعمل التطبيق بالكامل على شبكة توصيل محتوى (CDN) أو شبكة توصيل تطبيقات (ADN).
  • كل شيء موجود في نظام التحكم بالإصدارات Git.
  • تُشغل عمليات الإنشاء الآلية (Automated builds) ضمن سير عمل محدد عندما يدفع المطورون الكود.
  • يتم النشر التلقائي للـ Markup المُنشأ مسبقًا إلى CDN/ADN.
  • يعتبر التطبيق "بلا خادم" (Serverless) عمليًا. بمعنى أوضح، نحن لا نقوم بصيانة أي تطبيقات من جانب الخادم (server-side applications)، بل نستخدم خدمات موجودة بالفعل (مثل البريد الإلكتروني، الوسائط، قواعد البيانات، البحث، وما إلى ذلك).

وهنا حقيقة ممتعة: العديد من الميزات التي كانت تتطلب في السابق واجهة خلفية مخصصة (custom back-end) يمكن الآن إنجازها بالكامل من الواجهة الأمامية (front-end).

في هذا المقال، سنتعلم كيفية بناء تطبيق JAMstack يتضمن:

  • خدمة API لتقديم ملفات الوسائط.
  • مولد موقع ثابت (Static Site Generator - SSG) لإنشاء الـ Markup المُنشأ مسبقًا.
  • وأخيرًا، سنقوم بنشره عبر CDN.

ماذا سنبني اليوم؟ معرض صور تفاعلي!

سنقوم ببناء معرض صور. نظرًا لحبي للأفلام، قررت إنشاء معرض صور لممثليني المفضلين، وسأطلق عليه اسمًا مرحًا: imaginary. سنستخدم خدمة إدارة الوسائط المسماة Cloudinary لاستضافة وإدارة صورنا. توفر هذه الخدمة أيضًا واجهات برمجة تطبيقات (APIs) للمطورين لتحميل واسترجاع الوسائط مثل الصور ومقاطع الفيديو وغيرها.

لبناء الواجهة الأمامية (front-end) لمعرض الصور، سنستخدم إطار عمل يسمى Gatsby. إن Gatsby هو إطار عمل مفتوح المصدر (open-source) يعتمد على مكتبة React لإنشاء المواقع والتطبيقات.

أخيرًا، سنتعلم كيفية نشر التطبيق على CDN باستخدام عملية بناء ونشر تلقائية. لهذا الغرض، سنستخدم Netlify CDN. في نهاية المقال، سيبدو تطبيقنا imaginary بهذا الشكل:

معرض صور Gatsby و Cloudinary بعد الانتهاء

ملخص سريع (TL;DR)

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

  • يمكنك الوصول إلى العرض التوضيحي لمعرض الصور من هنا: http://imaginary.netlify.app/
  • جميع الأكواد المصدرية المستخدمة في هذا المقال موجودة في مستودع GitHub الخاص بي. لا تتردد في متابعته، حيث أقوم بتحديث الكود المصدري بشكل متكرر. إذا أعجبك العمل، يرجى دعمه بنجمة.

لنبدأ الآن!

إعداد Cloudinary: استضافة وإدارة الصور

أولاً، قم بإنشاء حساب في Cloudinary. الخطة المجانية كافية تمامًا لتطبيق معرض الصور الخاص بنا. سجل الدخول باستخدام بيانات اعتماد حسابك للوصول إلى لوحة تحكم Cloudinary dashboard. يرجى تدوين كل من Cloud name و API Key و API Secret، حيث سنحتاج إليها في تطبيقنا.

لوحة تحكم Cloudinary توضح بيانات الاعتماد

بعد ذلك، قم بتحميل الصور التي تختارها لاستخدامها في image gallery. يمكنك إنشاء مجلد وتسميته بما تشاء. في حالتي، قمت بتسميته artists ورفعت الصور إليه. لاحظ أننا سنستخدم اسم هذا المجلد لاحقًا عند دمج Cloudinary مع Gatsby. يرجى تحديد كل صورة وإضافة Title (عنوان) و Description (وصف). سنستخدم هاتين المعلومتين الوصفيتين كتعليقات للصور (image captions) ونص بديل (alt-text) على التوالي في معرض الصور الخاص بنا.

إدارة الصور في Cloudinary مع إضافة العناوين والأوصاف

هذا كل شيء. يرجى عدم مشاركة مفتاح API secret والمفتاح (key) مع أي شخص. لننتقل الآن إلى الإعدادات المطلوبة لـ Gatsby.

إعداد Gatsby: بناء الواجهة الأمامية

يتطلب المشروع المعتمد على Gatsby وجود Node.js ليعمل. تأكد من تثبيت Node.js. يمكنك تنزيل وتثبيت Node.js من هنا. سيُظهر التثبيت الناجح إصدار Node باستخدام هذا الأمر:

node -v

إنشاء دليل المشروع

أنشئ دليل مشروع لتنظيم الكود المصدري. لننشئ دليلاً باسم imaginary.

mkdir imaginary
cd imaginary

تهيئة المشروع

هناك العديد من مشاريع البداية (starter projects) لإنشاء تطبيق Gatsby. بينما تبسط مشاريع البداية العديد من التعقيدات، إلا أنها قد تكون مربكة بعض الشيء لتطبيق بسيط مثل تطبيقنا. مع الأخذ في الاعتبار ذلك، سنقوم بتهيئة مشروع Gatsby بسيط بأنفسنا. افتح موجه الأوامر واكتب الأمر التالي لتهيئة مشروع يدعم Node.js:

npm init -y

تثبيت وإعداد Gatsby الأولي

قم بتثبيت أداة gatsby-cli عالميًا (globally). ستساعدنا هذه الأداة في العمل مع بيئة Gatsby.

npm install -g gatsby-cli

قم بتثبيت تبعيات Gatsby و React و ReactDOM. يمكنك إما استخدام الأمر npm install كما هو موضح أعلاه، أو الأمر yarn add إذا كان لديك yarn مثبتًا.

yarn add gatsby react react-dom

لنضف أيضًا ملف .gitignore بالمحتوى التالي:

.cache
public
node_modules
*.env

يمكنك اختياريًا إنشاء ملفي README.md و LICENSE. في هذه المرحلة، يجب أن يحتوي مشروعنا على هذه المجلدات والملفات:

هيكل ملفات مشروع Gatsby الأولي

تحتاج مشاريع Gatsby إلى ملف تهيئة خاص يسمى gatsby-config.js. في هذا الوقت، سنحتاج إلى ملف فارغ. أنشئ ملفًا باسم gatsby-config.js بالمحتوى التالي:

module.exports = {
  // keep it empty
}

الآن حان الوقت لإنشاء صفحتنا الأولى باستخدام Gatsby. أنشئ مجلدًا باسم src في جذر مجلد المشروع. أنشئ مجلدًا فرعيًا باسم pages تحت src. أنشئ ملفًا باسم index.js تحت src/pages بالمحتوى التالي:

import React from 'react';

export default () => {
  return (
    <>
      

Images to load here...

> ) }

في هذه المرحلة، يجب أن تبدو ملفات ومجلدات مشروعنا بهذا الشكل:

هيكل ملفات مشروع Gatsby مع أول صفحة

تشغيل التطبيق محليًا

جرب الأمر التالي في موجه الأوامر لتشغيل التطبيق محليًا:

gatsby develop

بشكل افتراضي، يعمل تطبيق Gatsby على رقم المنفذ 8000. افتح متصفحك المفضل وادخل إلى التطبيق على العنوان http://localhost:8000. يجب أن تراه يعمل كما يظهر في لقطة الشاشة أدناه:

تطبيق Gatsby يعمل محليًا على المنفذ 8000

هذا كل شيء. الآن، لقد قمنا بإعداد كل من Cloudinary و Gatsby بنجاح. حان الوقت لربطهما معًا.

دمج Cloudinary و Gatsby: جلب الصور

يتمتع إطار عمل Gatsby بدعم مجتمعي ضخم، وهناك العديد من الإضافات (plug-ins) لتلبية الاحتياجات الحرجة. في أوائل عام 2020، قدم فريق Cloudinary إضافتين رائعتين لـ Gatsby لمجتمع المطورين:

  • Gatsby-Source-Cloudinary: يساعد في جلب الصور المخزنة وقت البناء (build time) من Cloudinary إلى تطبيق/موقع Gatsby.
  • Gatsby-Transformer-Cloudinary: يساعد في تحميل الصور المحلية من تطبيق/موقع Gatsby إلى Cloudinary.

نظرًا لأننا مهتمون فقط بجلب الصور إلى معرض الصور هنا، فسنقوم بتثبيت إضافة gatsby-source-cloudinary فقط. سنقوم أيضًا بتثبيت حزمة مساعدة تسمى dotenv للتعامل مع متغيرات البيئة (environment variables) مثل المفتاح السري (Secret Key)، ومفتاح API، وما إلى ذلك) محليًا. لنقم بتثبيتهما. افتح موجه الأوامر واستخدم الأمر التالي:

yarn add dotenv gatsby-source-cloudinary

الآن، اتبع هذه الخطوات لجلب الصور إلى تطبيقنا.

إعداد متغيرات البيئة

أنشئ ملف .env في جذر مجلد المشروع وأضف المحتوى التالي إليه. يرجى ملاحظة أن القيم في أزواج المفتاح-القيمة (key-value pairs) متاحة في لوحة تحكم Cloudinary dashboard كما رأينا سابقًا.

CLOUDINARY_CLOUD_NAME=<YOUR_CLOUDINARY_NAME>
CLOUDINARY_API_KEY=<YOUR_CLOUDINARY_API_KEY>
CLOUDINARY_API_SECRET=<YOUR_CLOUDINARY_API_SECRET>

تكوين Gatsby لجلب الصور

عدّل ملف gatsby-config.js لإضافة المحتوى التالي:

require('dotenv').config();

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-cloudinary`,
      options: {
        cloudName: process.env.CLOUDINARY_CLOUD_NAME,
        apiKey: process.env.CLOUDINARY_API_KEY,
        apiSecret: process.env.CLOUDINARY_API_SECRET,
        resourceType: `image`,
        prefix: `artists/`,
        context: true,
        tags: true,
        maxResults: 50
      }
    }
  ]
}

هناك بعض الأمور التي تحدث هنا. نحن نخبر Gatsby باستخدام إضافة gatsby-source-cloudinary مع بعض المعلمات. يتم جلب المعلمات cloudName و apiKey و apiSecret من ملف .env باستخدام حزمة dotenv. نحدد أيضًا قيمة المعلمة resourceType كـ image لأننا غير مهتمين بجلب أنواع أخرى من الوسائط. يجب أن تكون قيمة المعلمة prefix هي نفسها اسم مجلد الصور في Cloudinary. نحدد context و tags كـ true لجلب البيانات الوصفية السياقية (contextual metadata) ومعلومات العلامات (tag information) للصورة. كما قمنا بتعيين maxResults إلى 50 حتى لا نتقيد بالقيمة الافتراضية وهي 10.

إنشاء مكون معرض الصور (Gallery Component)

بعد ذلك، أنشئ مجلدًا يسمى components تحت src وأنشئ ملفًا يسمى Gallery.js بداخله. يستخدم Gatsby لغة استعلام GraphQL لاستعلام البيانات من مصادر مختلفة مثل markdown و JSON و Excel. في حالتنا، سنستخدم Cloudinary كمصدر لاستعلام الصور باستخدام إضافة gatsby-source-cloudinary التي تم تكوينها بالفعل.

الآن قم بتعديل ملف Gallery.js وأضف المحتوى التالي:

import React from 'react';
import { useStaticQuery, graphql } from 'gatsby';

const Gallery = () => {
  const data = useStaticQuery(
    graphql`
      query CloudinaryImage {
        allCloudinaryMedia {
          edges {
            node {
              secure_url
              context {
                custom {
                  alt
                  caption
                }
              }
              resource_type
            }
          }
        }
      }`
  );

  const images = data.allCloudinaryMedia.edges;

  return (
    
{images.map((image, index) => (
{image.node.context.custom.alt}
{image.node.context.custom.caption}
))}
) }; export default Gallery;

كما نرى أعلاه، نستخدم استعلام GraphQL لجلب مسارات الصور المصدرية ومعلومات السياق. نستخدم هذه المعلومات للتكرار وإضافة الصور مع تعليق (caption).

تحديث الصفحة الرئيسية

الخطوة التالية هي تعديل ملف index.js لاستيراد ملف Gallery.js واستخدامه.

import React from 'react';
import Gallery from '../components/Gallery';

export default () => {
  return (
    <>
      
    >
  )
}

إذا كنت تقوم بتشغيل gatsby develop بالفعل، فيرجى إيقافه وتشغيله مرة أخرى. ادخل إلى التطبيق مرة أخرى في المتصفح. يجب أن ترى التطبيق مع جميع الصور التي تم جلبها من Cloudinary. ولكن انتظر، لا يبدو أنيقًا كما وُعدنا. يجب علينا القيام ببعض أعمال CSS هنا.

تنسيق معرض الصور باستخدام CSS

أنشئ ملفًا يسمى gallery.css تحت المجلد src\components وأضف المحتوى التالي فيه:

body {
  background: #000000 url("https://res.cloudinary.com/atapas/image/upload/v1602214656/misc/6284_n48wtw.jpg") repeat-x center top;
  color: #FFFFFF;
}

.container {
  margin-top: 55px;
}

.wave {
  float: left;
  margin: 20px;
  animation: wave ease-in-out 1s infinite alternate;
  transform-origin: center -20px;
}

.wave:hover {
  animation-play-state: paused;
}

.wave img {
  border: 5px solid #f8f8f8;
  display: block;
  width: 200px;
  height: 250px;
  background-color: #000;
}

.wave figcaption {
  text-align: center;
}

.wave:after {
  content: '';
  position: absolute;
  width: 20px;
  height: 20px;
  border: 1.5px solid #ffffff;
  top: -10px;
  left: 50%;
  z-index: 0;
  border-bottom: none;
  border-right: none;
  transform: rotate(45deg);
}

.wave:before {
  content: '';
  position: absolute;
  top: -23px;
  left: 50%;
  display: block;
  height: 44px;
  width: 47px;
  background-image: url(https://res.cloudinary.com/atapas/image/upload/v1602212639/misc/screw-head_oglfcu.png);
  background-size: 20px 20px;
  background-repeat: no-repeat;
  z-index: 16;
}

@keyframes wave {
  0% {
    transform: rotate(3deg);
  }
  100% {
    transform: rotate(-3deg);
  }
}

استورد ملف gallery.css إلى ملف Gallery.js بالشكل التالي:

import './gallery.css';

هذا كل شيء. يجب أن ترى التطبيق يبدو أفضل بكثير من ذي قبل، وكأن الصور معلقة على حائط مع حركة رسوم متحركة (animation) فيها.

معرض الصور النهائي بعد تطبيق التنسيقات والرسوم المتحركة

نشر التطبيق على Netlify

الخطوة الأخيرة هي نشر التطبيق علنًا حتى نتمكن من عرضه. أولاً، أنشئ مستودعًا (repository) في GitHub وادفع الكود المصدري إليه. ثم أنشئ حسابًا في Netlify لتسجيل الدخول. اتبع هذه الخطوات البسيطة لنشر تطبيقك على Netlify CDN مع دعم CI/CD المدمج:

  1. إنشاء موقع جديد من Git: قم بالمصادقة على حساب GitHub الخاص بك وحدد مشروع معرض الصور. في حالتي، اسم المشروع هو imaginary.
  2. إنشاء موقع جديد في Netlify من مستودع Git
    اختيار مستودع GitHub للمشروع

  3. تكوين إعدادات البناء والنشر: في الخطوة التالية، قدم معلومات حول أمر البناء (build command) كـ gatsby build ودليل النشر (publish directory) كـ public/.
  4. تحديد أمر البناء ودليل النشر في Netlify

  5. إعداد متغيرات البيئة: انقر على Site settings لإخبار Netlify باسم سحابة Cloudinary، والمفتاح السري، ومفتاح API، وما إلى ذلك. تصفح إلى خيار Environment وانقر على زر Edit variables. أضف ثلاثة متغيرات كما هو موضح أدناه بالقيم الموجودة في لوحة تحكم Cloudinary dashboard الخاصة بك.
  6. صفحة إعدادات الموقع في Netlify
    إضافة متغيرات البيئة في Netlify
    إدخال قيم متغيرات البيئة لـ Cloudinary

  7. تشغيل النشر: تصفح إلى خيار Deploys وقم بتشغيل نشر جديد (trigger a fresh deploy).
  8. تشغيل عملية نشر جديدة في Netlify

  9. تغيير اسم الموقع (اختياري): يمكنك تغيير اسم الموقع ليناسب احتياجاتك. في حالتي، أصبح https://imaginary.netlify.app/.
  10. تغيير اسم الموقع في Netlify

الآن انتهينا. أصبح التطبيق يعمل ومتاحًا للجمهور.

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

لقد قدم هذا المقال دليلًا عمليًا وشاملًا لبناء معرض صور ديناميكي باستخدام تقنيات JAMstack الحديثة. من خلال دمج قوة Gatsby كمولد مواقع ثابتة مع مرونة Cloudinary في إدارة الوسائط، تمكنا من إنشاء تطبيق عالي الأداء، آمن، وقابل للتوسع. إن استخدام GraphQL لجلب البيانات من Cloudinary يوضح كفاءة Gatsby في التعامل مع مصادر البيانات الخارجية، بينما يضمن النشر التلقائي عبر Netlify تجربة تطوير مبسطة وسريعة. هذا النهج لا يقلل فقط من تكاليف الصيانة والتشغيل بفضل طبيعته "بلا خادم"، بل يوفر أيضًا تجربة مستخدم ممتازة بفضل سرعة التحميل العالية والأمان المعزز. إن القدرة على فصل الواجهة الأمامية عن الواجهة الخلفية (decoupled architecture) تمنح المطورين مرونة كبيرة وتفتح آفاقًا واسعة لإنشاء تطبيقات ويب حديثة وفعالة.

اترك تعليقاً

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