برنامه نویسی

CMS گالری تصاویر خود را بسازید

در این پست، من در مورد نحوه ایجاد یک CMS گالری تصاویر با صفحات Astro، Xata و Cloudflare صحبت می کنم. شما یاد خواهید گرفت که چگونه:

  • Xata را راه اندازی کنید
  • یک طرحواره با انواع ستون های مختلف ایجاد کنید
  • تغییر اندازه و تار کردن تصاویر
  • همه رکوردها را بدون صفحه بندی واکشی کنید
  • فرم‌ها را در Astro با استفاده از انتقال‌های view مدیریت کنید

قبل از اینکه شروع کنی

پیش نیازها

شما به موارد زیر نیاز خواهید داشت:

پشته فنی

فن آوری شرح
کش رفتن پلت فرم پایگاه داده بدون سرور برای برنامه های کاربردی مقیاس پذیر و بلادرنگ.
Astro چارچوبی برای ساخت وب سایت های سریع و مدرن با پشتیبانی باطن بدون سرور.
Tailwind CSS چارچوب CSS برای ساخت طرح های سفارشی
صفحات Cloudflare بستری برای استقرار و میزبانی برنامه های وب با توزیع جهانی.

راه اندازی پایگاه داده Xata

پس از ایجاد یک حساب کاربری Xata و ورود به سیستم، یک پایگاه داده ایجاد کنید.

یک پایگاه داده ایجاد کنید

مرحله بعدی ایجاد یک جدول است، در این مثال uploads، که شامل تمام تصاویر آپلود شده است.

یک جدول ایجاد کنید

عالی! اکنون، کلیک کنید طرحواره در نوار کناری سمت چپ و دو جدول دیگر ایجاد کنید profiles و photographs. با کلیک کردن می توانید این کار را انجام دهید یک جدول اضافه کنید. جداول جدید ایجاد شده به ترتیب شامل اطلاعات نمایه کاربر و داده های عکس(های) آپلود شده کاربر خواهد بود.

جدول تازه ایجاد شده

با تکمیل آن، شما طرح را خواهید دید.

طرحواره نمایش داده شد

بیایید به اضافه کردن ستون های مرتبط در جداولی که ایجاد کرده اید ادامه دهیم.

ایجاد طرحواره

در uploads جدول، شما می خواهید تمام تصاویر را فقط (و بدون ویژگی های دیگر) ذخیره کنید تا بتوانید در صورت نیاز دوباره به همان شی تصویر ارجاع دهید.

با اضافه کردن ستون به نام ادامه دهید image. این ستون وظیفه ذخیره سازی را بر عهده دارد file اشیاء را تایپ کنید در مورد ما، file تایپ شی برای تصاویر است، اما می‌توانید از آن برای ذخیره هر نوع حباب (مانند PDF، فونت‌ها و غیره) با اندازه حداکثر 1 گیگابایت استفاده کنید.

ابتدا کلیک کنید + اضافه کردن ستون و انتخاب کنید فایل.

اضافه کردن ستون

نام ستون را تنظیم کنید image و برای عمومی کردن فایل ها (به طوری که هنگام بازدید از گالری تصاویر به کاربران نشان داده شوند)، این را بررسی کنید فایل ها را به صورت پیش فرض عمومی کنید گزینه.

فایل ها را عمومی کنید

در profiles جدول، ما می‌خواهیم ویژگی‌هایی مانند Slug منحصربه‌فرد کاربر (مسیر آدرس اینترنتی که در آن گالری آن کاربر نمایش داده می‌شود)، نام آن‌ها، تصویر آن‌ها با ابعاد آن، و هش base64 تصویر تبدیل شده را ذخیره کنیم. شما از مزایای ذخیره سازی هش برای ایجاد 0 صفحه(های) تغییر چیدمان تجمعی (CLS) بهره خواهید برد.

با اضافه کردن ستون به نام ادامه دهید slug. مسئول حفظ منحصر به فرد بودن هر نمایه ای است که ایجاد می شود. کلیک + یک ستون اضافه کنید، انتخاب کنید String تایپ کرده و نام ستون را به عنوان وارد کنید slug. برای مرتبط کردن یک اسلاگ تنها با یک کاربر، آن را بررسی کنید Unique ویژگی برای اطمینان از اینکه ورودی های تکراری درج نمی شوند.

اضافه کردن ستون راب

به روشی مشابه، ایجاد کنید name، image، height و width ستون ها به عنوان String نوع (اما نه Unique).

عالیه میتونی ذخیره کنی imageHash مانند Text تایپ کنید تا بتوانید فوراً هش تاری تصویر را به اندازه تای بازیابی کنید 200 KB. در حالی که String یک نوع پیش‌فرض عالی است، برای ذخیره بیش از 2048 کاراکتر، باید به آن سوئیچ کنید Text نوع در مورد محدودیت های موجود در محدودیت های ستون Xata بیشتر بخوانید.

کلیک + یک ستون اضافه کنید و انتخاب کنید Text نوع

یک ستون اضافه کنید

نام ستون را به عنوان وارد کنید imageHash و فشار دهید Create column.

نام ستون را وارد کنید

بسیار شبیه به آنچه در بالا انجام دادیم، در photographs جدول، ما ایجاد می کنیم name، tagline، image، height، width، profile-slug، و slug مانند String نوع و imageHash به عنوان Text ستون را تایپ کنید ستون ها slug و profile-slug به ترتیب به عکس و پروفایل کاربر رجوع کنید.

دوست داشتني! با تمام کارهای انجام شده، طرح نهایی چیزی شبیه به زیر خواهد بود…

طرح واره نهایی

راه اندازی پروژه شما

برای راه‌اندازی، مخزن برنامه را شبیه‌سازی کنید و این آموزش را دنبال کنید تا همه چیزهایی را که در آن است بیاموزید. برای انجام پروژه، اجرا کنید:

git clone https://github.com/rishi-raj-jain/image-gallery-cms-with-astro-xata-cloudflare
cd image-gallery-cms-with-astro-xata-cloudflare
pnpm install
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Xata را با Astro پیکربندی کنید

برای استفاده یکپارچه از Xata با Astro، Xata CLI را به صورت سراسری نصب کنید:

npm install @xata.io/cli -g
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس، Xata CLI را مجاز کنید تا با حساب وارد شده مرتبط شود:

xata auth login
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مجوز CLI را صادر کنید

عالی! اکنون پروژه خود را به صورت محلی با دستور Xata CLI مقداردهی اولیه کنید:

xata init --db https://Rishi-Raj-Jain-s-workspace-80514q.ap-southeast-2.xata.sh/db/image-gallery-cms-with-xata-astro-cloudflare
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای ادغام با Astro به چند سوال یکباره سریع از CLI پاسخ دهید.

Xata init با پروژه Astro

پیاده سازی اکشن های فرم در Astro

همچنین می توانید با افزودن عبارت، انتقال در فرم ارسالی را مجاز کنید ViewTransitions جزء.
در اینجا نمونه ای از عملکردهای فرم فعال شده با انتقال view به داخل آورده شده است src/layouts/Layout.astro:

---
// File: src/layouts/Layout.astro

import { ViewTransitions } from "astro:transitions";
---

<html>
  <head>
    <ViewTransitions />
    
  </head>
  <body>
    
  </body>
</html>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این به شما امکان می‌دهد تا جریان باطن و فرانت‌اند را برای یک صفحه معین در Astro جانمایی کنید. فرض کنید، فرم ارسالی حاوی نام، اسلاگ و URL تصویر کاربر را می‌پذیرید، آن را روی سرور پردازش می‌کنید تا هش Base64 تاری ایجاد کند، و آن را با پایگاه داده بدون سرور Xata خود همگام‌سازی می‌کنید. در اینجا نحوه انجام همه این کارها در یک مسیر Astro آمده است (src/pages/profie/create.astro).

---
// File: src/pages/profile/create.astro

const response = { form: false, message: '', created: false, redirect: null }

// ...

if (Astro.request.method === 'POST') {
  try {
    // Indicate that the request is being processed
    response.form = true

    // Get the user email from the form submissions
    const data = await Astro.request.formData()

        // Get the user slug, name, and image: URL, width, and height from the form submissions
    const userSlug = data.get('slug') as string
    const userName = data.get('name') as string
    const userImage = data.get('custom_upload_user__uploaded_image_url') as string
    const userImageW = data.get('custom_upload_user__uploaded_w') as string
    const userImageH = data.get('custom_upload_user__uploaded_h') as string

        // Create a blur url of the user image

        // Create the user record with the slug

        // Redirect user to the next step
  } catch (e) {
    // pass
  }
}
---

<form method="post" autocomplete="off">
  <Upload selector="user" />
  <input required name="name" type="text" placeholder="Name" />
  <input
    required
    name="slug"
    type="text"
    placeholder="Slug (e.g. rishi-raj-jain)"
  />
  <button type="submit">
    Create Profile &rarr;
  </button>
</form>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مدیریت آپلود تصویر در سمت سرور با Xata SDK

(/photograph/create - جایی که کاربران عکس های خود را آپلود می کنند)

از آنجایی که صفحات Cloudflare اندازه بدنه درخواست می‌کنند تا 100 مگابایت اجازه می‌دهد، شما می‌توانید آپلود تصویر را در سمت سرور مدیریت کنید. یک نقطه پایانی Astro ایجاد کنید (src/pages/api/upload/index.ts) برای دریافت درخواست های POST حاوی باینری های تصویر و استفاده از Xata SDK برای ذخیره آنها در uploads جدول.

پس از انجام بررسی های سلامت روی بدنه درخواست، ابتدا یک رکورد جدید (خالی) در خود ایجاد کنید uploads جدول، و سپس از آن به عنوان مرجع برای قرار دادن تصویر (بافر) با استفاده از Xata TypeScript SDK استفاده کنید. پس از تکمیل موفقیت آمیز، نقطه پایانی با تصویر پاسخ می دهد public URL، height و width به قسمت جلویی برگردید تا در فیلدهای فرم قرار دهید.

// File: src/pages/api/upload/index.ts

import { json } from '@/lib/response';
import { getXataClient } from '@/xata';
import type { APIContext } from 'astro';

// Import the Xata Client created by the Xata CLI in src/xata.ts
const xata = getXataClient();

export async function POST({ request }: APIContext) {
  const data = await request.formData();
  const file = data.get('file');

  // Do sanity checks on file

  try {
    // Obtain the uploaded file as an ArrayBuffer
    const fileBuffer = await file.arrayBuffer();

    // Create an empty record in the uploads table
    const record = await xata.db.uploads.create({});
    // Using the id of the record, insert the file using upload method
    await xata.files.upload({ table: 'uploads', record: record.id, column: 'image' }, fileBuffer, {
      mediaType: file.type
    });

    // Read the inserted image
    const { image } = await xata.db.uploads.read(record.id);

    // Destructure its dimension and public URL
    const { url, attributes } = image;
    const { height, width } = attributes;
    return json({ height, width, url }, 200);
  } catch (error) {
    // Handle errors
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

استفاده از تبدیل تصویر Xata برای ایجاد تصاویر تار

هنگامی که کاربر نمایه خود را در /profile/create صفحه، قبل از ایجاد یک رکورد در profiles جدول، یک بافر Base64 از تصاویر تار خود ایجاد کنید. برای ایجاد تصاویر تار از تصاویر اصلی، از تبدیل تصویر Xata استفاده کنید. با تبدیل‌های تصویر Xata، می‌توانید یک URL عمومی درخواستی درخواست کنید که اندازه تصویر را به ارتفاع و عرض معین تغییر می‌دهد و تصویر را محو می‌کند. در این مثال خاص، می توانید اندازه تصویر را به ابعاد 100 در 100 تغییر دهید و آن را تا 75 درصد نسبت به تصویر اصلی تار کنید.

---
// File: src/pages/profile/create.astro

// Import the Xata Client created by the Xata CLI in src/xata.ts
import { getXataClient } from '@/xata'

// Import the transformImage function by Xata Client
import { transformImage } from '@xata.io/client'

const response = { form: false, message: '', created: false, redirect: null }

// ...

if (Astro.request.method === 'POST') {

    // Fetch the Xata instance
    const xata = getXataClient()

    // ...

    // Create a blur URL of the user image

  // Using Xata image transformations to obtain the image URL
    // with a fixed height and width and 75% of it blurred
  const userBlurURL = transformImage(userImageURL, {
    blur: 75,
    width: 100,
    height: 100,
  })

  // Create a Base64 hash of the blur image URL
  const userBlurHash = await createBlurHash(userBlurURL)

    // Create the user record with the slug

    // Redirect user to the next step
}
---
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همگام سازی پروفایل ها با استفاده از Xata SDK

پس از ایجاد تصاویر تار، آخرین مرحله در انتشار پروفایل ها (مشابه کاری که در انتشار عکس ها انجام می شود) ایجاد یک رکورد کاربری با جزئیات مرتبط با استفاده از Xata TypeScript SDK است. create فرمان در Astro، ما پیام موفقیت آمیز را برای کاربر قبل از هدایت به صفحه آپلود عکس تنظیم می کنیم. رندر شرطی یکپارچه یک نشانه بصری از موفقیت یا شکست عملیات را تضمین می کند و تجربه ای پاسخگو و کاربرپسند را ارائه می دهد.

---
// File: src/pages/profile/create.astro

// Import the Xata Client created by Xata CLI in src/xata.ts
import { getXataClient } from '@/xata'

const response = { form: false, message: '', created: false, redirect: null }

// ...

if (Astro.request.method === 'POST') {

    // ...

    // Create the user record with the slug
  await xata.db.profiles.create({
    slug: userSlug,
    name: userName,
    image: userImage,
    width: userImageW,
    height: userImageH,
    imageHash: userBlurHash,
  })

    // Send the user to photograph upload page
  response.redirect = '/photograph/create'

  // Set the relevant message for the user
  response.message = 'Published profile succesfully. Redirecting you to upload your first photograph...'
}
---


{
  response.form &&
    (response.created ? (
      <p class="rounded bg-green-100 px-3 py-1">{response.message}</p>
    ) : (
      <p class="rounded bg-red-100 px-3 py-1">{response.message}</p>
    ))
}




<script define:vars={{ success: response.created, location: response.redirect }}>
  if (success) {
    setTimeout(() => {
      window.location.href = location
    }, 1000)
  }
</script>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

با استفاده از پرس و جو Xata

صفحه پروفایل کاربر (src/pages/[profile]/index.astro) از Xata Client برای واکشی پویا و نمایش تمام عکس ها (صفحه بندی نشده) برای یک نمایه کاربر خاص استفاده می کند. برای جذب بصری کاربران به محض باز کردن گالری، از ذخیره شده استفاده می کنیم imageHash مقدار به عنوان پس زمینه تصاویر (برای بارگذاری). برای جلوگیری از CLS از ذخیره شده استفاده می کنیم width و height مقادیر برای اطلاع مرورگر از ابعاد مورد انتظار تصاویر.

---
// File: src/pages/[profile]/index.astro

// Import the Xata Client created by Xata CLI in src/xata.ts
import { getXataClient } from '@/xata'

import Layout from '@/layouts/Layout.astro'

// Get the profile slug from url path
const { profile } = Astro.params

// Fetch the Xata instance
const xata = getXataClient()

// Get all the photographs related to the profile
const profilePhotographs = await xata.db.photographs
                                                        // Filter the results to the specific profile
                                                        .filter({ 'profile-slug': profile })
                                                        // Get all the photographs
                                                        .getAll()
---

<Layout className="flex flex-col">
  <div class="columns-1 gap-0 md:columns-2 lg:columns-3">
    {
      profilePhotographs.map(
        ({ width: photoW, height: photoH, name: photoName, image: photoImageURL, tagline: photoTagline, imageHash: photoImageHash }, _) => (
                    {/* Destructure the width and height to prevent CLS */}
          <img
            width={photoW}
            height={photoH}
            alt={photoName}
            src={photoImageURL}
                        {/* Do not lazy load the first image that's loaded into the DOM */}
            loading={_ === 0 ? 'eager' : 'lazy'}
            class="transform bg-cover bg-center bg-no-repeat will-change-auto"
                        {/* Create a blur effect with the imageHash stored */}
            style={`background-image: url(${photoImageHash}); transform: translate3d(0px, 0px, 0px);`}
          />
        ),
      )
    }
  </div>
</Layout>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

(گالری تصاویر - ارائه تصاویر تار در ابتدا)

(گالری تصاویر - پس از بارگیری تصویر کامل)

استقرار در صفحات Cloudflare

مخزن آماده استقرار در Cloudflare است. برای استقرار یکپارچه با Cloudflare مراحل زیر را دنبال کنید

  1. با کد برنامه یک مخزن GitHub ایجاد کنید.
  2. کلیک ایجاد اپلیکیشن در بخش Workers & Pages داشبورد Cloudflare.
  3. حرکت به صفحات را بزنید و انتخاب کنید به Git متصل شوید.
  4. مخزن GitHub ایجاد شده را به عنوان پروژه جدید خود پیوند دهید.
  5. به پایین اسکرول کنید و به روز رسانی کنید چارچوب از پیش تعیین شده به Astro.
  6. به روز رسانی متغیرهای محیطی از .env به صورت محلی
  7. کلیک ذخیره و استقرار و به پروژه برگردید تنظیمات > کارکرد.
  8. اضافه کردن nodejs_compat به پرچم های سازگاری بخش
  9. مستقر کنید! 🚀

چرا صفحات Cloudflare؟

Cloudflare Pages برای این مورد خاص متمایز بود زیرا اندازه بدنه درخواستی تا 100 مگابایت را در طرح رایگان خود ارائه می دهد. این به دور زدن محدودیت اندازه بدنه درخواست 4.5 مگابایت در ارائه دهندگان میزبانی بدون سرور مختلف کمک کرد.

اطلاعات بیشتر

برای اطلاعات دقیق تر، منابع ذکر شده در این پست را بررسی کنید.

بعدش چی؟

اگر بازخوردی در مورد این آموزش دارید، می‌خواهید درباره Xata بیشتر بدانید، یا اگر می‌خواهید در وبلاگ یا آموزش اجتماعی مشارکت کنید، خوشحال می‌شویم از شما بشنویم. در Discord با ما تماس بگیرید یا به ما بپیوندید X | توییتر. ساختمان مبارک 🦋

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا