مقدمه‌ای بر تولید محتوای ایستا

طراحی و پیاده‌سازی وب‌سایت این روزها با سیستم‌های مدیریت محتوا و علی‌الخصوص سیستم‌های مدیریت محتوای مشهوری چون جوملا، وردپرس، دروپال و امثالهم گره خورده است؛ اما آیا به جز وب‌سایت‌های پویا راه دیگری هم برای طراحی و پیاده‌سازی وب‌سایت وجود دارد؟

وب‌سایت‌ها به طور کلی و از نظر سرو شدن، به دو دسته ایستا و پویا تقسیم می‌شوند. تفاوت، در نحوه آماده‌سازی صفحات برای ارائه به مخاطب است.

در روش ایستا، صفحات از قبل آماده‌سازی و ذخیره شده اند و دقیقاً به همان شکلی که در پرونده‌ها ذخیره شده‌اند به مخاطب ارائه می‌شوند. در این روند، هیچ عمل سمت‌سروری جز خواندن بایت‌به‌بایت پرونده و نوشتن بایت‌به‌بایت بر روی اتصال برقرار شده صورت نمی‌گیرد. اولین وب‌سایت‌هایی که ایجاد شدند، وب‌سایت‌های ایستا بودند.

وب‌سایت پویا در مقابل، با «سیستم پرونده» سر و کار چندانی ندارد و از «پایگاه داده» برای ذخیره داده‌ها و سپس یک برنامه برای سرو کردن محتوا برای هر درخواست استفاده می‌کند. این دسته از صفحات وب می‌توانند شامل فرم‌ها، احراز هویت، پرداخت اینترنتی، محتوای متغیر و... باشند.

وب‌سایت‌هایی که مطلقاً از صفحات ایستا استفاده می‌کنند، مزیت‌هایی دارند:

  1. میزبانی ارزان‌تر
  2. بسیار سریع‌تر
  3. عدم نیاز به پیکربندی
  4. عدم نیاز به پایگاه داده
  5. فاکتورهای امنیتی کمتر و امنیت بسیار بالاتر نسبت به سایت‌های پویا

اما بزرگ‌ترین عیب آن‌ها، نیاز به دستکاری پرونده‌ها برای ایجاد تغییرات است. اگر وب‌سایت شما تغییرات زیادی داشته باشد، باید کل پرونده‌ها را ویرایش کرد و دوباره بارگذاری کرد.

اگر وب‌سایت شما شامل صفحاتی ساده است، پس استفاده از یک سیستم مدیریت محتوا مانند وردپرس اضافه کاری است، اگر به همه امکانات یک سیستم مدیریت محتوا احتیاج دارید، یک سیستم مدیریت محتوا نصب کنید اما برای یک وبلاگ ساده، نصب وردپرس زیاده‌روی است! برای یک وبلاگ ساده، استفاده از یک «مولد سایت ایستا» کافی است.

«مولد سایت ایستا» چیست؟

در سال‌های اخیر ابزارهایی برای تسهیل تولید وب‌سایت‌های ایستا توسعه داده شده‌اند. این ابزارها با دریافت پرونده‌هایی به عنوان ورودی، صفحات وب ایستا را تولید می‌کنند که می‌توان پس از آن روی میزبان بارگذاری کرد.

انتخاب یک مولد سایت

تا به امروز مولدهای مختلفی طراحی و پیاده‌سازی شده‌اند؛ در اکوسیستم‌های مختلف، اهداف مختلف، نشانه‌گذاری‌ها و قالب‌سازی‌های مختلف و...

جدول زیر تعدادی از آن‌ها را با یک‌دیگر مقایسه می‌کند.

عنوان زبان محیط اجرا قالب ابزار ویرایشگر بصری مجوز تعداد ستاره‌ها تعداد فورک‌ها
Jekyll Ruby Ruby Liquid Jekyll Admin MIT 36k+ 7k+
Next Javascript Node.js Javascript (React) Monaco Editor MIT 32k+ 3k+
Hugo Go Go Go Hoku CMS Apache 2.0 30k+ 3k+
Gatsby Javascript Node.js React - MIT 28k+ 3k+
Hexo Javascript Node.js ماژولار (EJS, Pug, Haml, Mustache, Twig و...) Hexo Editor / Hexo Admin MIT 24k+ 3k+
GitBook Javascript Node.js Jinja2 GitBook Editor Apache 2.0 19k+ 2k+
Nuxt Javascript Node.js Vue - MIT 16k+ 1k+
Octopress Ruby Ruby Liquid - MIT 1k+ 150+
Wyam C#/.NET .NET Core ماژولار (Razor, Mustache, Liquid, PHP و..) - MIT 900+ 150+

از بین این ابزارها، ساده‌ترین و منعطف‌ترین آن‌ها در نظرم Wyam است. انتخاب از میان ابزارها به سلیقه شما بستگی دارد و احاطه شما بر زبان و محیط اجرای آن ابزار. اما اگر کاربر ویندوز هستید و اندک آشنایی با C#/.NET دارید، قصد طراحی سایت با Vue.js و React را ندارید و به دنبال ابزاری قدرتمند هستید؛ به شما Wyam را پیشنهاد می‌کنم.

معرفی Wyam

Wyam با هدف پیاده‌سازی یک مولد محتوای ایستا با انعطاف بسیار بالا که از Razor 1 استفاده می‌کند، توسط Dave Glick در سال ۲۰۱۴ بنیان‌گذاری شد. این ابزار حول مفهوم «خطوط تولید» طراحی شده است که به آن انعطاف بسیار بالایی می‌بخشد.

از آن‌جایی که Wyam برای سکوی .NET Core ارائه شده، در صورت نصب بودن .NET Core می‌توان با دستور زیر آن را نصب کرد:

dotnet tool install -g Wyam.Tool

یا اگر برای نصب راحت ابزارها روی ویندوز از Chocolatey استفاده می‌کنید، با دستور زیر می‌توانید آن را نصب کنید:

choco install wyam

روند تولید

Wyam بر اساس یک دستور پخت (Recipe) پوشه‌های ورودی را پردازش کرده و نهایتاً یک پوشه شامل خروجی به ما تحویل می‌دهد. هر دستور پخت شامل حداقل یک خط تولید (Pipeline) است و این خطوط تولید در کنار یکدیگر خروجی ما (که وب‌سایت است) را تشکیل می‌دهند.

شرح این دستور پخت، در پرونده پیکربندی که با نام config.wyam در پوشه پروژه فعلی است. این پرونده شامل یک اسکریپت به زبان C# است و شامل ارجاع‌ها به بسته‌های NuGet، اسمبلی‌های .NET، تعیین پیش‌فرض‌های دستور پخت، تغییرات در خطوط تولید دستور پخت (در صورت استفاده از دستور پخت‌های توکار) و یا ایجاد خطوط تولید جدید و... می‌شود. این اسکریپت در زمان تولید خروجی، با استفاده از سرویس کامپایلر Roslyn کامپایل شده و سپس فراخوانی می‌شوند.

هر خط تولید، از اتصال چندین ماژول به یک‌دیگر تشکیل می‌شود. معمولاً آخرین ماژول خط تولید بایستی خروجی را ذخیره کند. به عنوان مثال، عملکرد کلی خط تولید «صفحه هر مطلب وبلاگ» به این صورت است:

  1. ReadFiles: از هر پوشه ورودی، پرونده‌های مارک‌داون پوشه posts را بگیر.

  2. Markdown: آن‌ها را به HTML تبدیل کن.

  3. Yaml: فراداده را از سرآغاز دریافت کن.

  4. Razor:

    1. قالب مربوطه را از پوشه پوسته بیاور.
    2. کد HTML به‌دست‌آمده از تبدیل مارک‌داون را در قالب جای‌گذاری کن.
    3. داده‌های موجود در سرآغاز 2 پرونده مارک‌داون را در قالب جای‌گذاری کن.
  5. WriteFiles: حاصل را ذخیره کن.

در Wyam چندین دستورپخت آماده برای سرعت بخشیدن به روند تولید سایت پیش‌بینی شده است:

  1. بلاگ (Blog)
  2. کتاب اینترنتی (BookSite)
  3. مستندات (Docs)
  4. وب (Web)

هر دستور پخت می‌تواند از «پوسته» هم بهره ببرد. به عنوان مثال دستور پخت بلاگ پوسته‌های CleanBlog, Phantom و... را دارد که به صورت بسته NuGet منتشر شده‌اند.

تولید وبلاگ ایستا

برای تولید یک وبلاگ ایستا، می‌توانیم از دستورپخت بلاگ و یکی از پوسته‌های رسمی استفاده کنیم. یکی از پوسته‌هایی که Wyam در قالب بسته‌های NuGet در اختیار ما قرار داده است، CleanBlog است که در این مثال استفاده می‌کنیم. برای ایجاد وبلاگ از دستور زیر استفاده می‌کنیم:

C:\myblog> wyam new --recipe Blog

با اجرای این دستور، پروژه وبلاگ ایستا در پوشه فعلی (C:\myblog) ایجاد می‌شود. ساختار به وجود آمده به صورت زیر است:

|- input/
|-- posts/
|--- first-post.md
|-- about.md
|- config.wyam

همان‌طور که از ساختار مشخص است، هر پروژه می‌تواند در پوشه ریشه خودش، چندین پوشه ورودی داشته باشد. نام input به عنوان پیش‌فرض پوشه ورودی توسط ابزار شناخته می‌شود. وارد پوشه input می‌شویم. در پوشه posts نوشته‌ها قرار می‌گیرند و همچنین صفحات مجزا در کنار پوشه posts و درون پوشه input. قالب این پرونده‌ها، مارک‌داون است.

پرونده first-post.md را باز می‌کنیم تا اولین نوشته خود را ویرایش کنیم.

Title: First Post
Published: 1/1/2016
Tags: Introduction
---
This is my first post!

از خط اول تا جایی که خط‌چین قرار دارد، جزء «سرآغاز» محسوب می‌شوند و از قالب YAML پیروی می‌کنند. سرآغاز، شامل فراداده مرتبط با این مطلب است و هنگام تولید خروجی، پس از خوانده شدن توسط ماژول YAML، مورد استفاده ماژول Razor برای جای‌گذاری درون قالب قرار می‌گیرند. پرکاربردترین فراداده‌های مورد استفاده در مطالب، همین ۳ عنوان هستند؛ به ترتیب: تیتر مطلب، زمان انتشار و برچسب‌ها. مطالبی که دارای فراداده «زمان انتشار» نباشند، «پیش‌نویس» تلقی شده و روی خروجی وبلاگ قرار نخواهند گرفت.

خط‌چین که شامل ۳ کاراکتر خط تیره است، سرآغاز را از محتوا جدا می‌کند و پس از خط‌چین، محتوای مطلب در قالب مارک‌داون قرار می‌گیرد.

برای صفحات جداگانه نیز قضیه به همین منوال است؛ با این تفاوت که فراداده‌های «برچسب» و «زمان انتشار» کاربردی ندارند.

پیکربندی

نوبت انجام تنظیمات اولیه وبلاگ است. پرونده config.wyam را با یک ویرایشگر متن ساده یا حتی بهتر، یک ویرایشگر کد باز می‌کنیم. محتوای آن به صورت زیر است:

#recipe Blog

// Customize your settings and add new ones here
Settings[Keys.Host] = "host.com";
Settings[BlogKeys.Title] = "My Blog";
Settings[BlogKeys.Description] = "Welcome!";

// Add any pipeline customizations here

خط اول، دستور پخت را تعیین می‌کند. خطوط چهارم الی ششم، مقادیر اولیه فراداده را تعیین می‌کنند که هنگام جای‌گذاری در قالب کاربرد دارند. فراداده‌های تعیین‌شده به ترتیب «نام دامنه وبلاگ»، «عنوان وبلاگ» و «شرح وبلاگ» هستند. فهرست کامل فراداده‌های پشتیبانی‌شده توسط دستورپخت بلاگ را در اینجا ببینید.

در پایان می‌توانیم تغییراتی در خطوط تولید و دستور پخت ایجاد کنیم که در بخش‌های بعدی به این امر می‌پردازیم.

تولید خروجی و پیش‌نمایش

پس از انجام ویرایش‌ها، کافیست برای مشاهده پیش‌نمایشی از وبلاگ دستور زیر را اجرا کنیم تا ضمن تولید خروجی در پوشه output، سرور پیش‌نمایش روی آدرس localhost:5080 راه‌اندازی شود:

C:\myblog> wyam . -p --theme CleanBlog

اگر بخواهیم فقط خروجی تولید شود، دستور زیر را اجرا می‌کنیم:

C:\myblog> wyam . --theme CleanBlog

خروجی در پوشه output قرار دارد، پس برای انتشار کافی است فقط محتویات این پوشه را روی هاست بارگذاری کنیم.

شخصی‌سازی و تنظیم

ویرایش پوسته‌ها

در Wyam، پوسته‌ها بر اساس دستورپخت طراحی و آماده می‌شوند و سپس در قالب یک بسته NuGet منتشر می‌شوند یا در پوشه theme در ریشه پروژه قرار می‌گیرند. بنابراین برای ویرایش پوسته‌ای که از طریق بسته NuGet استفاده می‌شود، باید بسته NuGet را به پوشه theme استخراج کنیم یا در صورت در اختیار داشتن کد منبع پوسته، آن را در پوشه theme کپی کنیم.

در مورد پوسته CleanBlog، روش دوم ساده‌تر و آسان‌تر است. از اینجا می‌توانید به کد منبع پوسته CleanBlog دسترسی داشته باشید. برای دریافت آن، می‌توانید کل کد Wyam را از گیت‌هاب به صورت zip دانلود کنید یا با clone کردن مخزن Wyam، پوشه مربوط به پوسته را کپی کنید.

پوسته‌های Wyam به زبان Razor نوشته می‌شوند که ترکیبی از C# و HTML است. برای استفاده از کد C# در پوسته‌ها می‌توان کد را به صورت یک کتابخانه کامپایل‌شده در آورد و سپس اسمبلی آن را در پیکربندی مورد ارجاع قرار دهیم.

برای آشنایی بیشتر با Razor پیشنهاد می‌کنم اینجا را بخوانید.

پوسته فارسی CleanBlog

پوسته‌های Wyam من‌جمله CleanBlog، به زبان انگلیسی و دارای تاریخ میلادی هستند. فارسی‌سازی پوسته کار خاصی به جز جایگزینی رشته‌های انگلیسی با فارسی ندارد، اما برای افزودن تاریخ هجری شمسی باید در جایی که تاریخ مطلب را جای‌گذاری کرده‌ایم، پیش از جای‌گذاری تاریخ را به صورت هجری شمسی در بیاوریم. برای این کار از کلاس PersianDateTimeFormat استفاده می‌کنیم (که آن را در اینجا به اشتراک گذاشته‌ام). برای راست‌چین کردن صفحات، از آن‌جایی که این پوسته برپایه Bootstrap 3 طراحی شده است، استفاده از Bootstrap RTL Ondemand گزینه مناسبی به نظر می‌رسد. پروژه نهایی را در این مخزن می‌توانید مشاهده کنید و از آن به عنوان پایه و اساس وبلاگ ایستای خود استفاده کنید :)

شخصی‌سازی خط تولید

می‌توان از طریق مشخصه Pipelines تغییرات مدنظر را اعمال کرد. هر خط تولید یک نام منحصربه‌فرد دارد. برای پیدا کردن نام خطوط تولید هر دستور پخت می‌توانید به مستندات آن مراجعه کنید، به عنوان مثال خطوط تولید دستور پخت بلاگ از اینجا قابل دسترس است. اگر خط تولیدی با نام Name را فرض کنید، تکه‌کدهای زیر برای انجام عملیات روی آن خط تولید قابل استفاده‌اند.

افزودن خط تولید
Pipelines.Add("New",
    ModuleA(),
    ModuleB()
);
حذف خط تولید
Pipelines.Remove("Name");
جایگزینی خط تولید

برای جایگزین کردن یک خط تولید، همه ماژول‌های آن را حذف می‌کنیم و ماژول‌های جدید را جایگزین می‌کنیم.

Pipelines["Name"].Clear();
Pipelines["Name"].AddRange(
    ModuleA(),
    ModuleB()
);
افزودن خط تولید در ترتیب خاص
Pipelines.InsertAfter("PrevPipe", "Name",
    ModuleA(),
    ModuleB()
);
حذف یک ماژول از خط تولید

برای حذف یک ماژول براساس نام از یک خط تولید، به صورت زیر عمل می‌کنیم:

Pipelines["PipelineName"].Remove("ModuleName");

برای حذف یک ماژول براساس اندیس ترتیب در خط تولید، به صورت زیر عمل می‌کنیم:

Pipelines["PipelineName"].RemoveAt(3);
افزودن یک ماژول در ترتیب خاص یا جایگزینی یک ماژول در خط تولید

برای انجام این تغییرات باید از متدهای افزونه موجود در کلاس ModuleListExtension استفاده کنیم. این متدها توانایی افزودن و حذف کردن ماژول‌ها در خط تولید بر اساس نام ماژول، نوع و اندیس را می‌دهند. برای اطلاعات بیشتر، به مستندات مراجعه کنید.

چگونه بنویسیم؟

برای نوشتن و نشانه‌گذاری در مارک‌داون، نیاز به ویرایشگر خاصی نیست و حتی Notepad برای این امر کفایت می‌کند. اما Typora یکی از بهترین ویرایشگرهای رایگان مارک‌داون است که امکانات مناسبی به یک نویسنده ارائه می‌کند؛ از جمله «حالت تمرکز» و «حالت ماشین تایپ». از بین همه ویرایشگرهای موجود، این برنامه با اندکی تغییرات (استفاده از یک پوسته سفارشی) می‌تواند برای نوشتن مطالب به زبان فارسی مناسب باشد. پوسته سفارشی این نرم‌افزار را از اینجا بگیرید و طبق دستورالعمل ذکر شده در مستندات فعال کنید. این پوسته در واقع یکی از پوسته‌های اصلی Typora است که راست‌چین شده و قلم آزاد وزیر نیز به آن اضافه شده است.

انتشار

برای انتشار سایت ایستا هزاران روش وجود دارد که به تعدادی از آن‌ها به اختصار می‌پردازم.

هاست

تمام میزبانی‌های وب (اعم از ویندوز، لینوکس و...) توانایی میزبانی وب‌سایت‌های ایستا را دارا هستند. بنابراین کافیست با استفاده از FTP یا راه‌های دیگر انتقال پرونده به هاست، محتویات پوشه خروجی را در ریشه سایت بارگذاری کنیم.

سرور

برای انتشار روی یک سرور، کافی است از یک سرور HTTP استفاده شود. سرورهای HTTP ساده مانند Serve (در Node.js) یا SimpleHTTPServer (در پایتون) برای این کار کفایت می‌کنند؛ هر چند می‌توان از Lighttpd یا nginx برای بهره بردن از امکاناتی چون HTTPS و میزبانی سایت‌ها با دامنه‌های مختلف بهره برد اما مزیت اصلی سرور نسبت به هاست، در امکان تولید خروجی روی آن است. می‌توان تنها پوشه(های) ورودی را روی سرور با آخرین تغییرات به‌روزرسانی کرد و سپس خروجی را تولید کرد.

Netlify

Netlify سرویس میزبانی مخصوص سایت‌های ایستاست و یکی از بهترین‌ها برای میزبانی یک سایت ایستا به علت آسانی روند استقرار است. پلن رایگان آن برای وب‌سایت‌های شخصی و پروژه‌های متن‌باز ایده‌آل است: هر سایت در ابتدا یک زیردامنه از netlify.com است که می‌تواند دامنه اختصاصی خود را نیز داشته باشد. امکان استفاده از Let's Encrypt با تمدید خودکار هم وجود دارد. انتشار در Netlify پس از ایجاد حساب کاربری، بسیار ساده است: پوشه خروجی را بکشید و در صفحه مدیریت سایت رها کنید. به همین سادگی! در مستندات Wyam درباره انتشار روی Netlify توضیحات بیشتری داده شده است.

و اما بعد...

در آینده به نحوه استفاده از Git و یکپارچگی مداوم (CI) برای وب‌سایت ایستا خواهم پرداخت. با من همراه شوید :)

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

  1. فهرست مولدهای سایت ایستا
  2. معرفی Wyam توسط Scott Hanselman
  3. مستندات Wyam
  4. Wyam و Netlify
  5. ۷ دلیل برای دوری جستن از مولدهای سایت ایستا

  1. موتور نمایش طراحی شده برای ASP.NET MVC

  2. در بخش نوشتن به این مسئله پرداخته شده است