یاد بگیرید که چگونه با این پروژه RSS Reader یک برنامه کامل SvelteKit بسازید.
RSS یک استاندارد محبوب برای توزیع محتوای وب در قالب ساختار یافته است. بسیاری از افراد، از علاقه مندان به فناوری گرفته تا معلمان، از RSS استفاده می کنند تا از آخرین اخبار و پست های وبلاگ های مورد علاقه خود به روز بمانند.
نوشتن RSS Reader خود یک کار ساده است که با SvelteKit، یک فریمورک متا که بر روی Svelte ساخته شده است، حتی آسان تر می شود.
راه اندازی پروژه SvelteKit
کد مورد استفاده در این پروژه در یک مخزن GitHub موجود است و برای استفاده شما تحت مجوز MIT رایگان است. اگر میخواهید نگاهی به نسخه زنده این پروژه بیندازید، میتوانید این دمو را مشاهده کنید.
قبل از ادامه، باید زمان اجرا Node.js و همچنین Node Package Manager (NPM) را روی دستگاه خود نصب کرده باشید. ترمینال خود را باز کنید و دستور زیر را اجرا کنید:
npm create svelte
# or
yarn create svelte
این باید رابط خط فرمان (CLI) ایجاد شده توسط Vite را راهاندازی کند. نام پروژه خود را بگذارید و قالب برنامه را روی “پروژه اسکلت” تنظیم کنید. بررسی نوع با TypeScript را غیرفعال کنید و هر گزینه دیگری را که می خواهید انتخاب کنید. پس از آن، به دایرکتوری پروژه بروید و اجرا کنید:
npm install
# or
yarn
پس از نصب وابستگی های پیش فرض، باید دو بسته به نام های: rss-parser و moment را نصب کنید. بسته اول تجزیه داده های XML را آسان تر می کند، در حالی که بسته دوم به شما کمک می کند تا تاریخ ها را به درستی قالب بندی کنید. در ترمینال خود، موارد زیر را اجرا کنید:
npm install rss-parser
npm install moment
# or
yarn add rss-parser
yarn add moment
اکنون می توانید با اجرای دستور زیر سرور توسعه را راه اندازی کنید.
npm run dev
# or
yarn dev
محتویات فایل App.css را پاک کنید و ساختار پروژه را طوری تغییر دهید که چیزی شبیه به شکل زیر باشد. هر دایرکتوری که از قبل وجود ندارد ایجاد کنید و فایل های خالی ایجاد کنید تا با نام های زیر مطابقت داشته باشد:
شما فقط باید دایرکتوری src را تغییر دهید، که باید شامل یک دایرکتوری lib و یک فایل lib/addToLocalStorage.js باشد. همچنین باید شامل دایرکتوری مسیرهایی باشد که شامل یک دایرکتوری فرزند به نام فید و چهار فایل است: +layout.js، +layout.svelte، +page.svelte و +server.js. داخل فید، دایرکتوری به نام [title] با دو فایل در داخل ایجاد کنید: +page.server.js و +page.svelte.
ممکن است برای ایجاد دایرکتوری [title] در خط فرمان مشکل داشته باشید زیرا بسیاری از پوسته ها از براکت های مربع برای تطبیق الگو استفاده می کنند. اگر با خطا مواجه شدید، نام دایرکتوری را ذکر کنید، به عنوان مثال:
mkdir '[title]'
ایجاد مسیر API برای بررسی فیدهای RSS معتبر
فایل routes/+server.js را باز کنید و ابزار json را وارد کنید. همچنین Parser را از بسته rss-parser وارد کنید.
import { json } from "@sveltejs/kit";
import Parser from "rss-parser";
اکنون، یک تابع ناهمزمان، GET، صادر کنید و در url به عنوان پارامتر ارسال کنید. در این تابع دو ثابت rssLink و parser ایجاد کنید.
ثابت اول باید پارامتر جستجو را از url ارسال شده نگه دارد، در حالی که دومی، تجزیه کننده، باید یک نمونه شی Parser جدید را ذخیره کند. سپس متد parseURL را در تجزیه کننده فراخوانی کرده و rssLink را به عنوان پارامتر ارسال کنید. در نهایت پاسخ را با تابع json سریال کنید و آن را برگردانید.
export async function GET({url}) {
const rssLink = url.searchParams.get('url');
const parser = new Parser();
let feed = await parser.parseURL(rssLink);
return json(feed);
}
طراحی صفحه اصلی
SvelteKit از یک سیستم مسیریابی مبتنی بر سیستم فایل استفاده می کند. به طور پیش فرض، فایل routes/+page.svelte به عنوان صفحه اصلی وب سایت شما عمل می کند.
فایل +page.svelte را باز کنید و در تگ اسکریپت، تابع addToLocalStorage را از دایرکتوری lib وارد کنید. شما هنوز این را ایجاد نکردهاید، اما بعداً این کار را انجام خواهید داد. پس از وارد کردن تابع، دو متغیر url و ready ایجاد کنید و متغیر آماده را روی false قرار دهید.
<script>
import addToLocalStorage from '$lib/addToLocalStorage';
let url;
let ready = false;
</script>
در قسمت نشانه گذاری موارد زیر را اضافه کنید:
<main>
<h1>RSS Reader</h1>
<h3>Add a new feed:</h3>
<input
type="url"
placeholder="Enter a valid RSS link..."
bind:value={url}
on:input={() => {
if (url.length > 0) {
setTimeout(() => {
ready = true;
}, 250);
} else {
ready = false;
}
}}
/>
</main>
بلوک کد بالا یک عنصر ورودی را تعریف می کند که اگر طول ورودی کاربر بزرگتر از صفر باشد، متغیر آماده را روی true تنظیم می کند. در مرحله بعد، کد را اضافه کنید تا در صورت درست بودن، برخی از عناصر را ارائه کنید.
{#if ready}
{#await fetch(`/?url=${url}`).then((res) => res.json())}
<p>Gathering information... Please wait</p>
{:then data}
{#if data.message === 'Internal Error'}
<p>Something went wrong...Check your URL and try again</p>
{:else}
<div>
{#if data.image}
<img
src={data.image.url}
alt={data.title}
/>
{/if}
<p>{data.title}</p>
<p>{data.description || ''}</p>
{console.log(data) || ''}
</div>
<button on:click={()=>{
addToLocalStorage(data.title, url);
location.reload();
}}>Add to My Feeds</button>
{/if}
{/await}
{/if}
این بلوک کد درستی آماده بودن را بررسی می کند، سپس با مسیر API که قبلا ایجاد کرده اید تماس می گیرد. این کد مسئول بررسی اینکه آیا URL وارد شده توسط کاربر به فید RSS معتبر اشاره دارد یا خیر.
در نهایت، یک استایل اولیه برای صفحه مانند این اضافه کنید:
<style>
img {
width: 40px;
height: 40px;
}
input {
padding: 15px;
font-size: 20px;
width: 50%;
}
</style>
تنظیم Layout
کد زیر را به فایل layout.js اضافه کنید. این کد به Svelte می گوید که فایل +layout.svelte را فقط روی کلاینت اجرا کند:
export const prerender = false;
export const ssr = false;
در مرحله بعد، در فایل +layout.svelte، لیست فیدها را از حافظه محلی برگردانید.
<script>
let feeds = JSON.parse(window.localStorage.getItem('feeds')) || [];
feeds = feeds.reverse();
</script>
بعد، علامت گذاری برای نوار ناوبری مانند این اضافه کنید:
<nav>
<a href="/">Home</a>
<span>My Feeds:</span>
<div class="my-feeds">
{#each feeds as feed}
{@const number = feeds.indexOf(feed)}
<div>
{number + 1}. <a href={`/feed/${feed.title}?url=${feed.url}`}>{feed.title}</a>
</div>
{/each}
</div>
</nav>
یک جزء اسلات و یک ظاهر طراحی را برای چیدمان اضافه کنید:
<slot />
<style>
nav {
display: flex;
font-size: 18px;
background-color: white;
padding: 10px;
width: 98vw;
}
.my-feeds {
display: flex;
white-space: nowrap;
overflow-x: scroll;
margin-left: 30px;
gap: 10px;
}
span {
white-space: nowrap;
font-weight: 900;
margin-left: 20px;
margin-right: -5px;
}
</style>
افزودن یک URL معتبر به فضای ذخیرهسازی محلی
هنگامی که برنامه تأیید کرد که یک فید RSS وجود دارد، ایده خوبی است که مکانیزمی برای ذخیره آن URL در حافظه محلی داشته باشید تا کاربر مجبور نباشد دوباره آن را وارد کند. فایل addToLocalStorage.js را باز کنید و موارد زیر را اضافه کنید:
export default function addToLocalStorage (title, url) {
let feedInLocalStorage = JSON.parse(localStorage.getItem("feeds")) || [];
localStorage.setItem(
"feeds",
JSON.stringify([...feedInLocalStorage, {title:title, url:url}])
);
}
این کد از متد setItem در localStorage برای ذخیره آرایه حاوی دادههای مربوط به فیدهای کاربر استفاده میکند.
ارائه فهرست ورودی ها برای فید RSS خاص
موارد زیر را به فایل [title]/+page.server.js اضافه کنید:
import Parser from "rss-parser";
export async function load({url}){
const rssLink = url.searchParams.get('url');
const parser = new Parser();
let feed = await parser.parseURL(rssLink);
return {...feed};
}
این کدی است که در کنار فایل +page.svelte اجرا می شود. آخرین ورودی ها را از یک فید خاص دریافت می کند. اکنون، در فایل +page.svelte، بسته moment را وارد کرده و یک data prop اضافه کنید:
<script>
import moment from 'moment';
export let data;
</script>
در مرحله بعد، یک تصویر را در صورت در دسترس بودن رندر کنید و از هر آیتم در آرایه data.items عبور کنید و محتوای مناسب را ارائه دهید:
{#if data.items}
{#each data.items as item}
{@const number = data.items.indexOf(item)}
<div class="item">
{number + 1}.
<a href={item.link}> {@html item.title}</a>
<div class="metadata">
<span>{item.author || item.creator || ""}</span>
<span>{moment(item.isoDate).fromNow()}</span>
</div>
<div class="snippet">{item.contentSnippet || ""}</div>
</div>
{/each}
{:else}
<p>Something went wrong...</p>
{/if}
در نهایت صفحه را به دلخواه استایل دهید:
<style>
.snippet {
font-size: 18px;
}
a {
font-size: 25px;
text-decoration: underline;
color: black;
&:visited {
color: gray;
}
&:hover {
text-decoration: none;
}
}
.item {
display: flex;
flex-direction: column;
padding: 10px 10px;
}
.metadata {
display: flex;
gap: 10px;
margin: 10px 0px 10px 0px;
}
img {
width: 40px;
height: 40px;
}
</style>
شما اکنون یک RSS خوان بسیار ساده با SvelteKit ایجاد کرده اید.
RSS برای چه چیزی مناسب است؟
اگر میبینید که چندین وبسایت، وبلاگ، منابع خبری یا پادکست را دستکاری میکنید، RSS دروازهای برای تجربه خواندن سازمانیافتهتر و با صرفهتر زمان است.
به خاطر داشته باشید که اگرچه RSS ابزاری فوقالعاده برای جمعآوری محتوا و پیگیری اخبار است، اما برای سناریوهای محتوای بیدرنگ، تعاملی، بسیار امن یا بسیار شخصیشده مناسب نیست.