إن كانت المطرقة هي كل ما بيدك, فسترى كل الأشياء مسامير
دا غالباً هيبقى اول بوست فالبلوج دي.
معظم الناس لو طلبت منهم يعملوا موقع بسيط, هيقربوا ببطء لReact1 , Angular, Vue, او الخمسوميت فريم وورك اللي موجودين حالياً.
بصراحة, اول لما جيت افكر اعمل البلوج دي اتجهت للحاجة اللي انا اعرفها, React. بس, بعدها بدأت افكر شوية وافتكرت اني كنت قريت عن استرو وانه يعتبر مخصص للStatic Sites, حاجات مش محتاجة Interactivity كتير.
قبل مابدأ, انا كنت محتاج حاجات معينة:
- محتاج ان الموقع يكون سريع. انا حرفياً مش بعمل حاجة مذهلة لأنه يكون بطيء, هو كل اللي بتشوفه HTML و CSS مش اكتر.
- محتاج ان كتابة البوستس تكون سهلة. لو كتابة البوستس صعبة, مش هيبقى عندي شغف اني اكتب.
- محتاج اني اعملة بسرعة. مش عايز ابدأ من الصفر, ولكن عايز انجز يعني!
انا مش هشرح استرو نفسه, لو عايز تتعلم اكتر عنه الdocumentation هتشرح احسن مني بكتير. بس, انا هشرح ازاي استرو حل المشاكل اللي اتكلمت عليها فوق.
سريع
لو بتعمل Static Site, فانت غالباً مش محتاج JavaScript. او بمعنى اصح, الـClient مش محتاج JavaScript.
استرو سريع عشان هو By default مش بيبعت اي JavaScript للClient. ولكن, استرو بيشتغل كCompiler. بتكتب كل كل ما تريد في ملفات .astro, وفالاخر دا بيتحول لملف HTML صغير يتبعت للـClient.
كمثال, بص عالكود دا, دا الكود اللي بيجيب كل البوستس في صفحة tags/. هي فاضية دلوقت, بس هتتملي (اتمنى).
---
import BaseLayout from "$lib/layouts/base_layout.astro";
import { getCollection } from "astro:content";
const pages = await getCollection("posts");
const tagMap = new Map();
for (const page of pages) {
for (const tag of page.data.tags) {
if (!tagMap.has(tag)) {
tagMap.set(tag, []);
}
tagMap.get(tag).push(page);
}
}
const uniqueTags = [...tagMap.keys()];
---
<BaseLayout>
<h1>تاجژ</h1>
{
uniqueTags.map((tag) => (
<div>
<h2 id={tag}>
<span>#{tag}</span>
</h2>
<ul>
{tagMap.get(tag).map((post) => (
<li>
<a
href={`/${post.data.pubDate.toISOString().substring(0, 10)}/${post.id}`}
>
<span>
{post.data.pubDate
.toISOString()
.substring(0, 10)}
</span>
<span>-</span>
<span>{post.data.title}</span>
</a>
</li>
))}
</ul>
</div>
))
}
</BaseLayout>
اية دا؟ انت بتضحك عليا؟! دي JavaScript اهي! واية دا كمان؟ 2 for loop جوا بعض!
دي !2 ازاي ممكن يكون سريع؟
عندك حق… دا مش اكتر حاجة Efficient…لو دا بيتعمل At runtime. الفكرة ان استرو بيشوف الكود دا, وبيحول كل حاجة لStatic HTML. مالاخر, بيعمل Compile للJavaScript اللي بتكتبه, وبيحوله لHTML & CSS. بالطريقة دي, استرو بيحفظ الـDX بأنه يسيبك تكتب لغة للScripting, وفنفس الوقت مبيعاقبش الـClient بأنه يبعتله حاجات هو مش محتاجها!
دا بيواجه الفكرة بتاعت الـFrontend Frameworks المشهورة, صفحة واحدة HTML وJavaScript تغير الـHTML بطريقة Dynamic (دي ال Single-Page Applications)
مش مصدقني؟ ادخل عالـNetwork Tab في الـChrome Devtools. مفيش ولا JavaScript Resource.
كتابة بوستس سهلة
من اكتر اللغات السهلة اللي ممكن تتعملها في ساعة حرفياً هي Markdown. وهي برضو من اكتر اللغات اللي الناس متعرفهاش, مش عارف لية. تحس ان البني ادمين كلهم قرروا يكتبوا الـReadMe بتاعتهم بالـAI.
غالباً, الكونتنت بتاعتك هتكتبها بMarkdown في استرو, والـMarkdown دا هيتحول لHTML فالاخر عشان الـBrowser بتاعك يقدر يقراه.
لية مكتبش بHTML على طول؟ انت ممكن تعمل كدا عادي, بس انت يعتبر بتعاقب نفسك. لو خيروك, هتحب تكتب دا:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title></title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
ولا دا؟
# Hello, World!
DX سريعة
انا شخص مبحبش اعمل UI. بالنسبالي اكتر جزء مضجر في كتابة اي Software. فابستعمل ادوات بتسهللي الموضوع لو جاتلي الفرصة, اولهم غالباً هي Tailwind.
تاني حاجة ممكن استعملها هي اي Component Library بتستعمل Tailwind. لو كنت بستعمل React او Next, كنت غالباً هختار ShadCn , بس انا كان عندي نظره لشكل الـBlog هيبقى عامل ازاي, وللأسف ملقتش حاجة بنفس الشكل اللي انا عايزه ومبتستعملش JavaScript, فاضطريت اكتب الـComponents بتاعتي بايدي (رعب).
الموضوع مكنش صعب اوي, عشان استرو برضو بيتيحلك انك تعمل الـComponents بتاعتك. اي ملف astro. يعتبر Component من وجهه نظر استرو.
دا مثلاً:
---
const { post } = Astro.props;
---
<div class="w-full">
<div
class="flex flex-wrap gap-x-3 divide-dotted text-xl text-wrap opacity-70"
>
<span class="text-wrap">
{post.data.pubDate.toISOString().substring(0, 10)}
</span>
{
post.data.tags.map((t) => (
<>
<span> • </span>
<a href={`/tags#${t}`}>
<span>#{t}</span>
</a>
</>
))
}
</div>
<h1 class="mb-0">
<a
href={`/${post.data.pubDate.toISOString().substring(0, 10)}/${post.id}`}
>
{post.data.title}
</a>
</h1>
<span class="italic">{post.data.subtitle}</span>
</div>
دا الكود اللي بيظهر الـTitle - Subtitle - Date - Tags بتاعت كل بوست. الـComponent بياخد Prop من النوع Post و بيRender دا على حسب كل بوست.
ممكن تستعمله كدا:
---
import { getCollection } from "astro:content";
import PostHeader from "./post-header.astro";
const allPosts = await getCollection("posts");
---
<div class="flex h-full w-full flex-col gap-y-12">
{
allPosts
.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
.map((post) => (
<div class="flex flex-col">{<PostHeader post={post} />}</div>
))
}
</div>
بتستعمله زي اي Component استعملته في حياتك (غالباً).
الناهية
استرو مش الـStatic Site Generator الوحيد, في Jekyll, 11ty, Hugo و غيرهم. طبعاً انا مستعملتهمش كلهم, ووارد جداً احب SSG غير استرو, ولكن صعب اتخيل DX اسهل من استرو.
اتمنى اني اكون شجعتك انك تستعمل استرو في مشروع ما, ولو استعملته بسبب البوست دا ابعتلي لينك!
Footnotes
-
رياكت Library مش Framework…عارف…عارف. ↩
-
حلو شكل الـO صح؟ دي Plugins استرو بيدعمها: remark-math و rehype-katex. استرو برضو بيدعم Syntax Highlighting في الكود ب Shiki و Prism. ↩