آغاز کار

ابتدا

این یک راهنمای قدم به قدم برای شروع به کار با میراست، در این راهنما، در کنار هم میرا را نصب میکنیم، آن را در یک شاخه‌ی جدید پیکربندی می‌کنیم، سپس چهار سایت را با مشخصات متفاوت تعریف می‌کینم، آن‌ها را تنظیم می‌کنیم و گام به گام شروع به ساختن آن‌ها در کنار هم می‌کنیم.

البته این راهنما در حال تکمیل است و به مرور، قسمت‌های بیشتری به آن افزوده می‌شود.

نصب میرا

میرا برای نصب به پرل نسخه 5.12 به بالا نیاز دارد

برای تست این که پرل را روی سیستم خود از قبل نصب شده دارید یا نه، terminal یا command line را باز کنید و تایپ کنید perl -v اگر پرل از قبل نصب شده باشد متنی شبیه به این را خواهید دید که ورژن پرل نصب شده را به شما نشان خواهد داد

This is perl 5, version 24, subversion 1 (v5.24.1)

اگر پرل را ندارید از این طریق آن‌را نصب کنید:

ویندوز

اگر از ویندوز استفاده میکنید Strawberry Perl یا «پرل توت فرنگی» را ابتدا نصب کنید
توت فرنگی cpan minus را به شکل توکار همراه خود دارد، برای نصب میرا تایپ کنید:

cpanm Mira

*نیکس (لینوکس، mac، BSD و ...)

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

برای نصب میرا میتوانید از شل پرل یا cpan.pm استفاده کنید و یا آن را با استفاده از cpan minus نصب کنید، توصیه میکنم از cpan minus استفاده کنید

۱- capn minus اگر capan minus را ندارید آن‌را نصب کنید

curl -L https://cpanmin.us | perl - --sudo App::cpanminus

یا

cpan App::cpanminus 

و بعد برای نصب میرا

sudo cpanm Mira

۲- نصب از طریق شل: در ترمینال دستور زیر را وارد کنید:

perl -MCPAN -e shell

و سپس تایپ کنید:

install Mira

یا به جای دو خط بالا، تنها از خط زیر استفاده کنید:

cpan Mira

ممکن است برای اجرای دستورهای بالای به دسترسی root نیاز پیدا کنید.

پیکربندی

پیکربندی میرا در یک مسیر جدید

ابتدا یک دایرکتوری جدید بسازید، نام آن را هر چه دوست دارید بگذارید، مثلا mira اگر در ویندوز هستید:

md mira

در لینوکس و مک:

mkdir mira

حالا وارد مسیر جدید شوید:

cd mira

و میرا را در این مسیر پیکر بندی کنید:

~/mira:>  mira init 

تعریف کردن یک پروژه جدید

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

برای نوشتن این مثال‌ با این فرض پیش می‌رویم که قصد داریم چهار سایت در کنار هم داشته باشیم:

۱- وبلاگ به زبان فارسی.
۲- وبلاگ به زبان انگلیسی.
۳- یک سایت برای نوشتن داستان‌های کوتاه، نام «دنباله‌دار» را برای این سایت در نظر می‌گیریم.
۴- یک سایت برای نوشتن مطالب آموزشی در مورد لینوکس.

در طول این راهنما سعی میکنیم این چهار سایت را در کنار هم در میرا بسازیم، تنظیم کنیم، قالب دهی کنیم و در نهایت منتشر کنیم. اما در ابتدا بیایید برای هر کدام با توجه به ورودی و خروجی مورد نظرمان یک تعریف مشخص کینم.

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

ضمیمه‌ها

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

فایل‌های پروژه اینها هستند:

گام اول: مشخص کردن نام‌ها

تعیین نام و محل ذخیره محتوا

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

وبلاگ فارسی: blog-fa
وبلاگ انگلیسی: blog-en
داستان دنباله‌دار: story
آموزش لینوکس: linux-learn

محل ذخیره محتوا:

پس از پیکربندی میرا چند پوشه برای شما ایجاد شده، یکی از این پوشه‌ها content است، محل اصلی ذخیره محتوا همین پوشه است، هر پوشه‌ی جدید در مسیر ریشه‌ی این مسیر، یک سایت جدید خواهد بود. پس در content این پوشه‌ها را ایجاد میکنیم:

~/mira/content/blog-fa/
~/mira/content/blog-en/
~/mira/content/story/
~/mira/content/linux-learn/

هر فایل یا دایرکتوری داخل هرکدام از این مسیرها، محتویات آن سایت را تشکیل خواهد داد

گام دوم: استراکچر

مشخص کردن فیلدهای پیش‌فرض برای هر سایت

۱- فرض را بر این میگیریم که برای هر نوشته در وبلاگ فارسی، تصمیم داریم یک عکس اختصاصی در نظر بگیریم، آن را در هدر در فیلدی به اسم image مشخص می‌کنیم.
همچنین در وبلاگ فارسی در نظر داریم دسته بندی براساس موضوع داشته باشیم category.

۲- در وبلاگ انگلیسی دسته بندی بر اساس تگ‌ها tags را مد نظر داریم.

۳- در مورد داستان‌هایمان بر اساس کلمات و موضوع داستان، کلمات کلیدی هر داستان را می‌خواهیم مشخص کنیم keywords همچنین میخواهیم اگر داستان دیگری هم نوشته‌ایم که شبیه به این داستان باشد، به آن لینک بدهیم suggests.

۴- در مورد آموزش‌ها هم میخواهیم این فیلدها را داشته باشیم: کلمات کلیدی tags، یک فیلد توضیحات برای کامل کردن تیتر description، دسته بندیهای موضوعی categories، یک عکس برای توضیح مطلب image، و از آنجا که بیشتر از یک نفر در قرار است آموزش‌هایشان را بنویسند، نام نویسنده author.

میتوانیم هر بارکه پست جدیدی را با دستور new میسازیم، موارد مورد نیاز را به هدر اضافه یا حذف کنیم. اما احتمالاً اینکار سخت خواهد بود، شاید یک بار فراموش کنیم فیلدی را اضافه کنیم یا با غلط املایی آن را تایپ کنیم یا هر چیز دیگری، اما راه حل برای اجتناب از این تکرار چیست؟ جواب استفاده کردن از شاخه‌ی structure است.

برای فیلدهای اختصاصی هر پست، میرا در شاخه‌ی structure برنامه ابتدا به دنبال نام فایلی هم نام با نام طبقه شما میگردد، اگر این فایل موجود باشد، به جز فیلدهایی که بالا نوشته شدند، محتوییات آن فایل نیز به هدر شما اضافه میشود، اگر این فایل موجود نبود، برای محتویات آن طبقه برنامه از فایل default استفاده میکند.

چهار فایل در شاخه‌ی structure همنام بانام سایت‌ها میسازیم

~/mira/structure/blog-fa
~/mira/structure/blog-en
~/mira/structure/story
~/mira/structure/linux-learn

محتوای هر یک از این چهار فایل را به این صورت مشخص میکنیم:

~/mira/structure/blog-fa

_index:
category:
image:

~/mira/structure/blog-en

_index:
tags:
 - 

~/mira/structure/story

_index:
keywords:
 - 
suggests:
 - 

~/mira/structure/linux-learn

_index:
description:
categories:
 - 
tags:
 - 
image:
author:

در مورد فیلد _index و کاربرد آن در ادامه خواهیم خواند. فعلا فقط آن را در فایل‌های استراکچر می‌گذاریم باشد.

حالا محتویات شاخه استراکچر این‌ها خواهند بود

~/mira/structure/
.
│
├── 
├── blog-en
├── blog-fa
├── default
├── linux-learn
└── story

دانلود شاخه structure

گام سوم: تنظیم پیکربندی یا کانفیگ کردن

توضیح تنظیمات در میرا

حالا باید مشخص کنیم هر کدام از این سایت‌ها را میخواهیم در چه آدرسی و به چه شکل منتشر کنیم، بدنه اصلی نوشته‌هایمان را چگونه بنویسیم، آدرس نهایی برای هر پست به چه شکلی باشد و …

برای مشخص کردن خصوصیات عمومی و خصوصی ساختمان و طبقات میرا، باید از فایل‌های config استفاده کنیم.

در میرا دو نوع فایل برای تنظیم پیکربندی‌ها داریم:

۱- تنظیم عمومی

تنظیم مشخصات عمومی و مشترک بین تمام طبقات.

فایل تنظیمات عمومی در شاخه اصلی که میرا را پیکر بندی کردیم با نام config.yml وجود دارد.

~/mira/config.yml

۲- تنظیم اختصاصی برای هر سایت یا طبقه

تنظیم‌ها اختصاصی هر طبقه در شاخه‌ی config و هم‌نام با نامی که برای آن طبقه یا سایت در شاخه‌ی content ساختیم به همراه پسوند yml.

در این مثال فایل‌های تنظیم اختصاصی با توجه به نام‌هایی که در گام دوم انتخاب کرده بودیم این‌ها خواهند بود:

~/mira/config/blog-fa.yml
~/mira/config/blog-en.yml
~/mira/config/story.yml
~/mira/config/linux-learn.yml

دانلود فایل config.yml و شاخه config

تنظیمات عمومی

ابتدا چند فرض عمومی را در نظر میگیریم:

فرض می‌گیریم تمام این موارد برای هر چهار سایت مقدار یکسانی باید داشته باشند:

  • نام نویسنده مطالب
  • آدرس ایمیل
  • تصویر نویسنده
  • لوگوی سایت

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

  • هر چهار سایت از یک قالب مشترک استفاده می‌کنند. template

برای قالب انتشار هر چهار سایت را با استفاده از یک قالب منتشر می‌کنیم، می‌خواهیم در ادامه قالب خودمان را با نام my-theme بسازیم، فعلاً فقط به مقداردهی اولیه اکتفا میکنیم و فیلد template را مقدار دهی میکنیم. این قالب را در ادامه همراه هم به وجود می‌آوریم.

  • سایت‌هایمان را قرار است در ریشه‌ی آدرس address.com منتشر کنیم. url و root
  • محل ذخیره فایل‌های ضمیمه عمومی یا همان static را address.com/static مشخص می‌کینم. static
  • محل ذخیره تصاویر مشترک مثل لوگو و... را address.com/static/imagesدر نظر می‌گیریم. imageurl

در گام پنجم در مورد فیال‌های ضمیمه و static کامل‌تر و با چند مثال صحبت خواهیم کرد.

  • تعداد پست‌هایی که در صفحه‌ی مشترک بین سایت‌ها میخواهیم نمایش دهیم را ۵ در نظر می‌گیریم. post_num
  • متن اصلی محتوا برای هر چهار سایت را با استفاده از فرمت markdown می‌خواهیم بنویسیم. default_markup
  • در صورتیکه هنگام استفاده از دستور mira new برای ایجاد پست جدید سوییچ -f را برای مشخص کردن طبقه(یا همان سایت) وارد نکنیم، به شکل پیش‌فرض نوشته جدید در وبلاگ فارسی به وجود بیاید. default_floor

فایل config.yml را با هر ویرایشگر متنی که دوست دارید باز کنید، تمام محتویات آن را پاک کنید و با مقادیر زیر جایگزین کنید:

~/mira/config.yml

title: نوشته های من 
description: نوشته‌های من در باره‌ی تجربیات روزانه و سفرهایم، آهنگ‌هایی که شنیدم و داستان‌هایی که مینویسم

author: اسم شما
email: Your@Email.com
url: http://www.address.com/
root: /
static: /static
imageurl: /static/images
default_markup: markdown
default_floor: blog-fa
post_num: 5
template: my-theme

logo: /static/images/logo.png
author_image: /static/images/author_image.png

تنظیمات اختصاصی برای هر سایت

می‌خواهیم هر کدام از این چهار سایت را در این آدرس‌ها منتشر کنیم:

  • وبلاگ فارسی: address.com/blog
  • وبلاگ انگلیسی: address.com/en
  • داستان دنباله‌دار: address.com/story
  • آموزش لینوکس: address.com/linux

برای این منظور باید فیلدهای url و root را مقدار دهی کنیم.

در مورد آدرس نهایی هر پست:
به یاد داشته باشید آدرس‌ها میتوانند به شکل پوشه یا فایل تولید شوند، برای دیدن تفاوت این دو مورد، در پایان گام تنظیمات، تفاوت فیلد permalink در فایل‌های تنظیمات وبلاگ فارسی با سایر سایت‌ها را ببینید.

  • تصمیم داریم نوشته‌های وبلاگ فارسی در آدرس‌هایی که براساس تاریخ انتشار و دسته بندی موضوعی تولید شده‌اند منتشر شوند و در آدرس نهایی category و تاریخ‌ها به شکل مسیر باشند و تیتر مطلب به شکل یک فایل باشد.
  • پست‌های وبلاگ انگلیسی از تاریخ انتشار در آدرس ثایت استفاده کنند. آدرس به شکل یک مسیر باشد.
  • برای داستان‌ها تنها نام داستان در آدرس باشد. آدرس به شکل یک مسیر باشد.
  • در آموزش لینوکس، در آدرس‌ هر پست نام نویسنده هم ذکر شده باشد. آدرس به شکل یک مسیر باشد. برای تنظیم این موارد در فایل تنظیمات فیلد permalink را باید مقدار دهی کنیم

لیست‌های آرشیوی مورد نظرمان:

  • برای وبلاگ فارسی category و آرشیو زمانی بر اساس تاریخ شمسی
  • برای وبلاگ انگلیسی tags و آرشیو زمانی بر اساس تاریخ میلادی
  • برای داستان هیچ لیست آرشیوی در نظر نداریم
  • و در آموزش هم tags, categories, author

برای این‌کار باید فیلد lists را مقدار دهی کنیم.

نمایش تعداد نوشته‌ها در هر صفحه:

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

برای نمایش تعداد هر پست در صفحه اول به فیلد post_num مقدار دهی میکنیم و برای تعداد پست‌ها در هر صفحه آرشیو هم archive_post_num
برای ترتیب نمایش هم فیلد post_sort

فایل‌های ضمیمه وبلاگ‌های فارسی و انگلیسی را هم در زیر شاخه‌ی آدرس خودشان در شاخه‌ی assets می‌خواهیم ذخیره کنیم، اما ضمیمه‌های آموزش لینوکس و داستان را در زیرشاخه‌ی آدرس خود سایت اما در شاخه‌ی static.

در آخر برای هر سه سایتی که به فارسی مینویسیم می‌خواهیم تاریخ هجری شمسی را هم داشته باشیم، برای این منظور باید پلاگین Jdate را فعال کنیم. و در وبلاگ فارسی آرشیو بر اساس تاریخ شمسی هم می‌خواهیم داشته باشیم.

برای تنظیمات عمومی فایل config.yml در ریشه اصلی از قبل موجود است، برای ذخیره کردن تنظیمات مشخص شده برای هر سایت هم، در دایرکتوری config هم‌نام با نام هر سایت در شاخه یک فایل جدید با پسوند yml میسازیم

~/mira/config/blog-fa.yml
~/mira/config/blog-en.yml
~/mira/config/story.yml
~/mira/config/linux-learn.yml

با توجه به تمام مواردی که در بالا برای تنظیمات در نظر گرفتیم هر کدارم از این چهار فایل باید اینگونه باشند:

~/mira/config/blog-fa.yml

title: وبلاگ فارسی من
description: اینجا وبلاگ فارسی من است
url: http://www.address.com/blog/
root: /blog/
static: /blog/assets
imageurl: /blog/assets/article_images
permalink: :category/:year/:month/:day/:title.html
post_num: 5
archive_post_num: 10
lists:
 - category
 - jdate
plugins:
 - Jdate
lang: fa

~/mira/config/blog-en.yml

title: my english blog
description: this is my english blog

url: http://www.address.com/en/
root: /en/
static: /en/assets
imageurl: /en/assets/images
permalink: :year/:month/:day/:title/
post_num: 5
archive_post_num: 10
lists:
 - tags
 - date
lang: en

~/mira/config/story.yml

title: دنباله دار
description: توضیحاتی در مورد داستان دنباله دار من
url: http://www.address.com/story/
root: /story/
static: /story/static
imageurl: /story/static/images
permalink: /:title/
post_num: all
post_sort: reverse
lists:
plugins:
 - Jdate
lang: fa

~/mira/config/linux-learn.yml

title: آموزش لینوکس
description: مطالبی که روزانه در مورد لینوکس یاد میگیریم و دوست داریم با دیگران به اشتراک بگذاریم

url: http://www.address.com/linux/
root: /linux/
static: /linux/static
imageurl: /linux/static/images
permalink: :author/:title/
default_markup: markdown
post_num: 10
archive_post_num: all
lists:
 - categories
 - tags
 - author
plugins:
 - Jdate
lang: fa

به فایل تنظیمات سایت «دنباله دار» نگاه کنید، فیلد lists وجود دارد، اما به آن مقداری داده نشده، این یعنی میخواهید هیچ آرشیوی نداشته باشید، اگر فیلد lists را به جای خالی رها کردن، کلا در تنظیمات وارد نمی‌کردیم، به معنی وجود نداشتن هیچ آرشیوی نیست، بلکه به این معنی بود که هر مقداری که فایل تنظیمات عمومی برای آرشیو در خود دارد برای این سایت هم همان مقدار در نظر گرفته شود.

همانطور که میبینید در هیچ کدام از فایل‌های تنظیم اختصاصی template و default_markup وجود ندارد، اما در فایل تنظیمات عمومی، config.yml در شاخه‌ی اصلی این فیلد هم وجود دارد و هم مقدار دارد، وجود نداشتن یک فیلد در تنظیمات اختصاصی به این معنی است که می‌خواهیم برای آن فیلد از تنظیمات عمومی پیروی کنیم. پس مقدار my-theme و markdown در config.yml، برای تمام سایت‌ها معتبر است.

نکته: در تنظیمات وبلاگ انگلیسی فیلدی را اضافه کرده‌ایم برای مشخص کردن زبان lang: en و در سایر سایت‌ها lang: fa این یک فیلد شخصی است که در تنظیمات هیچ تعریف مشخصی ندارد و روی تنظیمات تاثیری نمی‌گذارد، این فیلد را برای استفاده در قالب نهایی در آینده نوشته‌ایم، فعلا کاری با آن نداریم.

گام چهارم: تولید محتوا

نوشتن اولین پست

حالا که تمام کارهای اولیه را انجام دادیم شروع به نوشتن چند پست میکنیم در هر سایت می‌کنیم

mira new -t 'سلام دنیا' -f blog-fa

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

~/mira/content/blog-fa/2017-3-23-سلام-دنیا.md created

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

---
utid: 20170323112305
date: 2017-03-23 11:23:05
title: سلام دنیا
_index:
category: آزمایش
image: /blog/assets/article_images/hello.jpg
---
سلام دنیا  
این اولین نوشته من است که برای تست کردن نوشته شده.  
این یک متن آزمایشی است.

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

چند پست دیگر را هم بنویسید،

mira new -t 'first post' -f blog-en
mira new -t 'یک ویژگی جدید در آخرین نسخه هسته که تازه دیروز منتشر شده و به نظرم خیلی جالب بود' -f linux-learn
mira new -t 'آغاز' -f story

مثال‌هایی برای محتوا

برای اینکه مثال‌های کامل‌تری داشته باشیم، محتوای سایت‌هایمان را با استفاده از تعدادی از نوشته‌های سایت‌های زیر تکمیل می‌کنیم.

  • behroozam.com برای استفاده در وبلاگ فارسی
  • sallar.me وبلاگ انگلیسی
  • morde.ir داستان‌ها
  • linuxiha.ir آموزش لینوکس

دانلود شاخهcontent

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

گام چهارم: تولید محتوا

استفاده از ایندکس برای داشتن آدرس مرتب و کوتاه

اگر به یاد داشته باشید، برای ساختن فایل‌های استراکچر در سربرگ هر سایت، فیلدی به نام index را قرار داده بودیم: _index:

اما فیلد _index که در چیست و به چه دردی می‌خورد؟

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

/blog/CATEGORY/a2017/03/23/سلام-دنیا.html
/en/2017/03/23/first-post/
/linux/AUTHOR/یک-ویژگی-جدید-در-آخرین-نسخه-هسته-که-تازه-دیروز-منتشر-شده-و-به-نظرم-خیلی-جالب-بود/
/story/آغاز/

نکته: در آدرس‌هایی که برای مثال در بالا نوشته شده‌اند، CATEGORY و AUTHOR با مقداری که در هدر هر پست هست جایگزین می‌شود، فعلا چون در تمام قسمت‌ها مطلبی ننوشتیم از نام فیلدها استفاده کردیم.

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

~/mira/content/blog-fa/2017-3-23-سلام-دنیا.md

---
utid: 20170323112305
date: 2017-03-23 11:23:05
title: سلام دنیا
_index: hello world
category: آزمایش
image: /blog/assets/article_images/hello.jpg
---
سلام دنیا  
این اولین نوشته من است که برای تست کردن نوشته شده.  
این یک متن آزمایشی است.

و

~/mira/content/blog-en/first-post.md

---
utid: 20170323112351
date: 2017-03-23 11:23:51
title: first post
_index:
tags:
 - first
 - test
---
hello world  
this is my first post  

و

~/mira/content/story/2017-3-23-آغاز.md

---
utid: 20170323112408
date: 2017-03-23 11:24:08
title: آغاز
_index: start
keywords:
 - مقدمه
 - شروع
 - آغاز
suggests:
image: /story/assets/first.jpg
---
### مقدمه
شروع داستان نویسی من از این نقطه است و از این به بعد سعی می‌کنم هر هفته یک داستان جدید به داستان‌هایم اضافه کنم  

امیدوارم از خواندن آن‌ها لذت ببرید

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

~/mira/content/linux-learn/2017-3-23-یک-ویژگی-جدید-در-آخرین-نسخه-هسته-که-تازه-دیروز-منتشر-شده-و-به-نظرم-خیلی-جالب-بود.md

---
utid: 20170323112534
date: 2017-03-23 11:25:34
title: یک ویژگی جدید در آخرین نسخه هسته که تازه دیروز منتشر شده و به نظرم خیلی جالب بود
_index: amazing update
description: چند ویژگی جدید که در آخرین نسخه به هسته اضافه شده و انعطاف پذیری را چندین برابر افزایش می‌دهد
categories: 
 - هسته
 - لینوکس
tags:
 - هسته
 - لینوکس
 - آپدیت هسته
 - ویژگی جدید
 - هسته لینوکس
image: /linux/static/feutured/core.jpg
author: someone
---
این آپدیت که تازه دیروز منتشر شده بسیار بسیار هیجان انگیز است  
و چند ویژگی جدید را در خود دارد که شامل این‌ها هستند:
 - ...
 - ...

حالا آدرس نهایی تولید شده برای هرکدام از این پست‌ها به این شکل خواهند بود:

/blog/آزمایش/i2017/03/23/hello-world.html
/en/2017/03/23/first-post/
/linux-learn/someone/amazing-update/
/story/start/

به آدرس‌ها دقت کنید، وبلاگ فارسی با یک نام فایل با پسوند html تمام شده است، اما مابقی یک آدرس کامل بدون هیچ فایلی هستند، این آدرس‌ها در اصل این‌ها هستند:

/en/2017/03/23/first-post/index.html
/linux-learn/someone/amazing-update/index.html
/story/start/index.html

چند نکته و پیشنهاد در مورد محتوا

نکته:
نام و پسوند فایل‌ها در دایرکتوری محتوا یا content در پردازش نهایی هیچ تاثیری نخواهند داشت، به هر شکلی که می‌خواهید می‌توانید آن‌ها را تغییر دهید، برای مثال این نام فایل را ممکن است دوست نداشته باشید:

~/mira/content/linux-learn/2017-3-23-یک-ویژگی-جدید-در-آخرین-نسخه-هسته-که-تازه-دیروز-منتشر-شده-و-به-نظرم-خیلی-جالب-بود.md

آن‌را به هر چیزی که می‌خواهید تغییر دهید، مثلا:

~/mira/content/linux-learn/new-update.markdown

نکته:
همانطور که گفته شد نام و پسوند فایل محتوا تاثیری در پردازش آن ندارد، اما این مورد یک استثنا هم دارد، فایل‌هایی با پسوند .draft نادیده گرفته می‌شوند و از وجودشان چشم‌پوشی خواهد شد.

پیشنهاد
برای ساختن فایل‌های جدید با دستور mira new از تیتر مورد نظرتان استفاده نکنید، از یک نام ساده استفاده کنید و بعد تیتر و index را در هدر فایل مشخص کنید، برای مثال به جای این دستور:

mira new -t 'یک ویژگی جدید در آخرین نسخه هسته که تازه دیروز منتشر شده و به نظرم خیلی جالب بود' -f linux-learn

از چیزی شبیه به این استفاده کنید:

mira new -t 'new update' -f linux-learn

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

~/mira/content/linux-learn/2017-3-23-new-update.markdown
~/mira/content/linux-learn/new-update.md
~/mira/content/linux-learn/new.txt
~/mira/content/linux-learn/deep/2017-3-23-new-update.markdown
~/mira/content/linux-learn/folder/sub/folder/2017-3-23-new-update.markdown
~/mira/content/linux-learn/update/deep/more/deep/2017-3-23-new-update.markdown
~/mira/content/linux-learn/update/deep/more/deep/new.txt

گام پنجم: فایل‌ها و پوشه‌های ضمیمه یا statics

توضیح فایل‌های ضمیمه

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

میرا یک پوشه‌ی عمومی برای ضمیمه‌ها در ریشه‌ی اصلی در شاخه‌ی statics دارد

~/mira/statics

و بی‌نهایت پوشه‌ی دیگر برای هرسایت در شاخه‌ی content هر طبقه.

ضمیمه‌های عمومی

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

~/mira/statics محتویات این پوشه به مسیری که در فایل تنظیمات ~/mira/config.yml و فیلد static مسیر دهی کرده‌اید منتقل می‌شود و در قالب با استفاده از کد {{ MainSTATIC }} یا {{ MAIN.static }} قابل دسترسی خواهد بود.

برای مثال اگر فیلد static در فایل config.yml مساوی /attach باشد و سایت‌مان را قرار باشد در address.com منتشر کنیم، نتیحه مسیری شبیه به این خواهد بود:

~/mira/config.yml  >       static: /attach
 ‌
~/mira/statics     >       http://address.com/attach/

دانلود شاخه عمومی statics

ضمیمه‌های اختصاصی هر طبقه

در پوشه‌ی محتوای هر سایت در شاخه‌ی content هر پوشه‌ای که نامش با خط زیر یا همان آندرلاین _ شروع شود از نظر میرا یک پوشه‌ی ضمیمه به حساب می‌آید و تمام محتویات آن‌را بدون هیچ بررسی به مسیر اصلی سایت منتقل میکند.

یک مثال:
در بخش تنظیمات برای وبلاگ فارسی(blog-fa) در فیلدهای url و root مسیر blog را برای انتشار مشخص کردیم، پس هر پوشه‌ای که در مسیر blog-fa با ـ شروع شود به عنوان ضمیمه در مسیر blog آدرس دهی میشود، به این مثال‌ها دقت کنید:

~mira/content/blog-fa/_assets
/blog/assets/

~mira/content/blog-fa/_statics
/blog/statics/

~mira/content/blog-fa/deep/_image
/blog/deep/image

~mira/content/blog-fa/more/deep/folder/_attach
/blog/more/deep/folder/attach

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

~mira/content/blog-fa/more/content.md
~mira/content/blog-fa/more/deep/post.txt
~mira/content/blog-fa/more/deep/folder/contetnt.md
~mira/content/blog-fa/more/deep/folder/_attach
~mira/content/blog-fa/more/deep/folder/_attach/post.markdown

میرا سه فایل اول را که قبل از رسیدن به ~mira/content/blog-fa/more/deep/folder/_attach قرار دارند، برای انتشار بررسی و آماده می‌کند، اما فایل آخر ~mira/content/blog-fa/more/deep/folder/_attach/post.markdown را به عنوان یک فایل ضمیمه می‌شناسد و تنها آن را همان شکلی که هست به مسیر انتشار انتقال می‌دهد.

نکته:
احتمالا متوجه شدید که فیلد static در فایل تنظیمات اختصاصی هیچ تاثری در انتقال و آدرس‌دهی به مسیر فایل‌ها و پوشه‌های ضمیمه برای سایت‌ها ندارد.

این فیلد تنها جهت سهولت دسترسی در قالب و استفاده در قالب سایت با تگ {{ STATIC }} یا {{ SITE.static }} می‌باشد.

اگر فایل مثال برای content را دانلود کرده باشید، محتوای اختصاصی static هر سایت، همراه با فایل content دانلود شده

مسیر تصاویر یا imageurl

در تنظیمات یک فیلد دیگر را به نام imageurl مقدار دهی کرده بودیم، برخلاف فیلد static که در تنظیمات عمومی تاثیر گذار بود و در تنظیمات اختصاصی تنها برای دسترسی در قالب استفاده می‌شد، این فیلد در تنظیمات عمومی استفاده‌ی خاصی ندارد و فقط برای دسترسی در قالب تعریف شده، اما در تنظیمات اختصاصی تاثیر گذار است.

مورد استفاده این فیلد در پارسرهای داخلی میرا و هنگلم نوشتن متن محتوا است، در تنظیمات وبلاگ فارسی به این فیلد این مقدار را داده بودیم:

imageurl: /blog/assets/article_images

حالا در هر کدام از نوشته‌های این سایت اگر از تگ {{ img }} استفاده کنیم، میرا دنبال تصاویر در این مسیر میگردد.
نحوه‌ی استفاده از {{ img }} به این شکل است:

{{ img image/address/pic.jpg [alt] [title] }}

اولین نوشته در وبلاگ فارسی را به یاد دارید؟

~/mira/content/blog-fa/2017-3-23-سلام-دنیا.md

بیایید یک‌بار دیگر آن‌را ویرایش کنیم:

---
utid: 20170323112305
date: 2017-03-23 11:23:05
title: سلام دنیا
_index: hello world
category: آزمایش
image: /blog/assets/article_images/hello.jpg
---
سلام دنیا  
این اولین نوشته من است که برای تست کردن نوشته شده.

{{ img /future/sky.jpg [image alt] [pic title] }}

این یک متن آزمایشی است.

نتیجه‌ی نهایی برای انتشار این‌گونه خواهد بود:

<p>سلام دنیا</p>
<p>این اولین نوشته من است که برای تست کردن نوشته شده.</p>
<p><img src="/blog/assets/article_images/future/sky.jpg" alt="image alt" title="pic title"></p>
<p>این یک متن آزمایشی است.</p>

در برچسب {{ img }} مقادیر [alt] و [title] اختیاری هستند و می‌توانید از آن‌ها چشم پوشی کنید.

گام ششم: ساختن قالب

توضیح ساختار قالب در میرا

هر قالب در میرا یک پوشه است در شخه‌ی template

~mira/template/

گفتیم که در این مثال می‌خواهیم یک قالب جدید با نام my-theme را برای استفاده در سایت‌مان بسازیم. پس نیاز به یک دایرکتوری جدید به همین نام در مسیر فوق داریم:

~/mira/template/my-theme/

هر قالب در میرا از تعدادی فایل پوسته تشکیل می‌شود، پنج فایل به شکل پیش فرض تعریف شده‌اند و هر تعداد که بخواهید فایل‌های فرعی.

پنج فایلی که برای داشتن یک قالب کامل مورد نیاز هستند این ها هستند: main.tt2 و index.tt2 و archive.tt2 و post.tt2 و atom.tt2

یک توضیح مختصر در مورد اینکه هر کدام از این‌فایل‌ها برای چه کاری مورد استفاده قرار می‌گیرند:

فایل main.tt2 برای ساختن یک قالب مشترک بین تمام سایت‌هاست، یک صفحه ارتباطی. در اصل پوسته‌ی سازنده‌ی root عمومی که در config.yml تعریف کردیم. در این مثال address.com/index.html با این پوسته ساخته می‌شود.

فایل index.tt2 برای ساختن صفحه‌ی اصلی هر سایت در آدرسی است که برای آن در فیلدهای url و root تنظیماتش مشخص کرده‌اید استفاده می‌شود.

فایل archive.tt2 حاوی قالب ساخت تمام صفحات آرشیو است.

فایل post.tt2 برای ساختن قالب تکی پست‌ها و نوشته‌ها در آدرسی است که در فیلد permalink در تنظیمات سایت مشخص کرده‌ایم.

فایل atom.tt2 برای ساختن فید مطالب هر سایت به کار می‌رود.

پنج فایل جدید در شاخه‌ی قالب my-theme بسازید.

~/mira/template/my-theme/
.
│
├── archive.tt2
├── atom.tt2
├── index.tt2
├── main.tt2
└── post.tt2

می‌توانید قالبی را که در ادامه به ساختن آن می‌پردازیم را از این جا دانلود کنید:

دانلود شاخه template

main template

فایل main.tt2 برای ساختن یک قالب مشترک بین تمام سایت‌هاست، یک صفحه ارتباطی.

مسیری که به عنوان url و root در فایل config.yml مشخص کرده باشید با استفاده از این قالب ساخته می‌شود.

در این مثال این صفحه با استفاده از این قالب ساخته می‌شود.

address.com/index.html

این فایل را با هر ویرایشگری که دوست دارید باز کنید و کدهای زیر را در آن کپی کنید

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
    <meta charset="utf-8">
    <meta name="description" content="{{ MainDESCRIPTION }}">
    <meta name="author" content="{{ MainAUTHOR }}">
    <link rel="shortcut icon" href="{{ MAIN.author_image }}">
    <title>{{ PageTITLE }}</title>
    <style>
    entry img {
    max-width: 100% !important;
    }
    </style>
</head>
<body>
    <center>
    <img src="{{ MAIN.logo }}">
    <h1>{{ MainTITLE }}</h1>
    <h2>{{ MainDESCRIPTION }}</h2>
    </center>
    <hr>
    <table>
    <tr>
    {{ FOREACH site IN FLOORS.values.sort('name') }}
      <td style="border-right: 1px solid black; width: 25%;" valign="top">
      <h2><a href="{{ site.root }}">{{ site.name }}</a></h2>
      <p>{{ site.description }}</p>
      <hr>
      <ul>
      {{ FOREACH post IN site.posts }}
        <li><h4><a href="{{ post.url }}">{{ post.title }}</a><h4></li>
        {{ post.body.less }}
      {{ END }}
      </ul>
      </td>
    {{ END }}
    </tr>
    </table>

</body>
</html>

نکته: تمام مواردی را که در تنظیمات ذخیره شده می‌توان با استفاده از بر چسب‌های MAIN و SITE در قالب نیز فراخوانی کرد، مانند خط ۲۱ همین قالب که با استفاده از {{ MAIN.logo }} مقداری را که در config.yml ذخیره کرده بودیم را فراخوانی کردیم.

همیچنین می‌توان تنظیماتی که در شاخه‌ی config و برای هر سایت مشخص کرده‌ایم را به این شکل فراخوانی کرد: {{ SITE.lang }} و ...

حالا که یک قالب داریم میتوانیم اولین build را انجام دهیم:

mira build

یک نسخه‌ی قابل انتشار از سایت در شاخه‌ی public به وجود آمده، حالا با دستور mira view

یک سرور برای پیش نمایش اجرا می‌کینم.

حالا به این آدرس بروید:

127.0.0.1:5000

index template

فایل index.tt2 برای ساختن صفحه‌ی اصلی هر سایت در آدرسی است که برای آن در فیلدهای url و root تنظیماتش مشخص کرده‌اید.

در این مثال، آدرس‌های زیر با استفاده از این قالب ساخته می‌شوند:

address.com/blog/
address.com/blog/page/1/ , address.com/blog/page/2/ ...

address.com/en/
address.com/en/page/1/ , address.com/en/page/1/ ...

address.com/story/ ...
address.com/linux/ ...

کدهای زیر را در index.tt2 کپی کنید:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
    <meta charset="utf-8">
    <meta name="description" content="{{ DESCRIPTION }}">
    <meta name="author" content="{{ MainAUTHOR }}">
    <link rel="shortcut icon" href="{{ MAIN.author_image }}">
    <title>{{ PageTITLE }}</title>
    <style>
    entry img {
    max-width: 100% !important;
    }
    </style>
</head>
<body>
    <center>
    <img src="{{ MAIN.logo }}">
    <h1>{{ TITLE }}</h1>
    <h2>{{ DESCRIPTION }}</h2>
    </center>
    <hr>
    <table>
    <tr>
<!-- Content -->
    <td width="70%">
    {{ FOREACH post IN POSTS }}
      <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
      <h5>{{ post.CALENDAR.jday_name }} {{ post.CALENDAR.jday }} {{ post.CALENDAR.jmonth_name }} {{ post.CALENDAR.jyear }}</h5>
      <h5>{{ post.CALENDAR.day_name }} {{ post.CALENDAR.day }} {{ post.CALENDAR.month_name }} {{ post.CALENDAR.year }}</h5>
      <p>{{ post.body.less }}</p>
      <br>
      <a href="{{ url }}#more">Continue...</a>
      <hr>
    {{ END }}
    </td>
<!-- sidebar -->
    <td width="30%">
    </td>
    </tr>
<!-- pagination -->
    <tr>
      <td width="30%">
      {{ IF PAGE.prev }}
        <a href="{{ PAGE.prev.url }}">prev: page {{ PAGE.prev.title }}</a>
      {{- END }}
        | page {{ PAGE.number }} of {{PAGE.total}} |
      {{ IF PAGE.next }}
            <a href="{{ PAGE.next.url }}">next: page {{ PAGE.next.title }}</a>
      {{- END }}
      </td>
    </tr>   
    </table>
</body>
</html>

از آنجا که بدنه اصلی کدهای تشکیل دهنده‌ی index، archive و post تقریبا یکی است، در مورد این کدها بعد از ساختن قالب post بیشتر توضیح می‌دهیم. و توضیحات تکمیلی‌تر را هم بعد از ساختن atom.tt2 با هم مرور می‌کینم.

archive template

فایل archive.tt2 حاوی قالب ساخت تمام صفحات آرشیو است، برای مثال این صفحه‌ها:

/blog/category/anime/
/blog/archive/1395/08/
/en/tags/Promise/

فایل archive.tt2 را برای ویرایش باز کنید و کدهای زیر را در آن کپی کنید:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
    <meta charset="utf-8">
    <meta name="description" content="{{ DESCRIPTION }}">
    <meta name="author" content="{{ MainAUTHOR }}">
    <link rel="shortcut icon" href="{{ MAIN.author_image }}">
    <title>{{ PageTITLE }}</title>
    <style>
    entry img {
    max-width: 100% !important;
    }
    </style>
</head>
<body>
<body>
    <center>
    <img src="{{ MAIN.logo }}">
    <h1>{{ TITLE }}</h1>
    <h2>{{ ArchiveTITLE }}</h2>
    </center>
    <hr>
    <table>
    <tr>
<!-- Content -->
    <td width="70%">
    {{ FOREACH post IN POSTS }}
      <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
    {{ END }}
    </td>
<!-- sidebar -->
    <td width="30%">
    </td>
    </tr>
<!-- pagination -->
    <tr>
      <td width="30%">
      {{ IF PAGE.prev }}
        <a href="{{ PAGE.prev.url }}">prev: page {{ PAGE.prev.title }}</a>
      {{- END }}
        | page {{ PAGE.number }} of {{PAGE.total}} |
      {{ IF PAGE.next }}
            <a href="{{ PAGE.next.url }}">next: page {{ PAGE.next.title }}</a>
      {{- END }}
      </td>
    </tr>   
    </table>
</body>
</html>

اگر به قالب‌های index و archive دقت کنید، تقریبا شبیه به هم هستند و تفاوت‌ها جزیی است، البته در index خلاصه متن را با {{ post.body.less }} فراخوانی کردیم، یا تاریخ‌ها را با برچسب‌های {{ post.CALENDAR }}، اما در قالب archive ما این برچسب‌ها نیستند، که به صورت اختیاری حذف شده‌اند و اگر نیازی داشته باشید می‌توانید از تمامشان استفاده کنید، تنها تفاوت بین این دو قالب {{ ArchiveTITLE }} است که در index یک برچسب نامعتبر به حساب می‌آید.

post template

فایل post.tt2 برای ساختن قالب تکی پست‌ها و نوشته در آدرسی است که در فیلد permalink در تنظیمات سایت مشخص کرده‌ایم استفاده می‌شود.

در این مثال، آدرس‌های زیر با استفاده از این قالب ساخته می‌شوند:

address.com/blog/category/year/month/day/post_title.html
address.com/en/year/month/day/post_title/
address.com/linux/author/post_title/
address.com/story/category/post_title/

اگر به قالب‌های index و archive یک بار دیگر نگاه بیندازید میبینید که پست ها را با استفاده از یک حلقه {{ FOREACH post IN POSTS }} لود کردیم، در مورد post اما استفاده از این حلقه اجباری نیست، یعنی اگر از آن استفاده نکنیم باز هم post مقدار معتبری دارد.

هر دو کد زیر برای استفاده در post معتبر هستند: {{ Foreach post IN POSTS }} {{ post.title }} {{ END }}

<td>
    {{ post.title }}
</td>

در post.tt2 استفاده از حلقه POSTS زمانی مفید است که بخواهید با متغیر دیگری به جز post مقادیر را فراخوانی کنید، مثلا:

<td>
{{ Foreach entry IN POSTS }}
    {{ entry.title }}
{{ END }}
</td>

به جز این مورد تقریبا تمام برچسب‌های دیگر بین archive، post و index شبیه به هم هستند و معتبر. پس میتوانیم عینا از قالب index برای post هم استفاده کنیم، اما عملا این کار برای قالبی که در حال ساخت آن هستیم مفید نیست، چرا که در قالب index خلاصه نوشته ها را برای نمایش در نظر گرفتیم و نه متن کامل یا در index و archive جزییات زیادی از هر پست را لود نکردیم، مثلا در سایت آموزش لینوکس هر نوشته نام نویسنده‌ی متفاوتی داشت، یا دسته بندی‌هایی که انجام داد بودیم، مثل tag ها در وبلاگ ها یا keywordها در داستان و عکس اختصاصی که برای نوشته‌های وبلاگ فارسی و آموزش لینوکس داشتیم و category ها. البته تمام این موارد را میشود در قالب‌های index یا archive هم نمایش داد، اما برای ساده بودن قالب از آن‌ها چشم پوشی شده.

اما نحوه‌ی اضافه کردن، تمام مشخصات هر نوشته که در هدر به آن نسبت داده شده مثل تاریخ، category، tag و ... در حلقه POSTS قابل بازیابی است، مثلا {{ post.category }}، البته برای لود کردن مقادیر گروهی یا آرشیوها باید از یک حلقه‌ها جدید داخل حلقه قبلی استفاده کنیم:

{{ FOREACH kw IN post.keywords }}
    {{ kw }}
{{ END }}

و اگر مقداری که فراخوانی میکنیم را قبلا آرشیو کرده باشیم، یعنی مقدارش را در فایل تنظیمات به فیلد lists وارد کرده باشیم:

{{ FOREACH tag IN post.tags.values }}
    <a href="{{ tag.url }}">{{ tag.name }}</a>
{{ END }}

از آنجا که برای تمام سایت‌ها میخواهیم از یک قالب استفاده کنیم و لیست‌های آرشیو و فیلدهای سربرگ که برای هرکدام در نظر گرفتیم با دیگران متفاوت است، از عبارت شرطی {{ IF }} برای تست اینکه آیا فیلد مورد نظر در این پست وجود دارد یا نه کمک میگیریم، مثلا پست‌های وبلاگ داستان فیلد tags را در سربرگ نداشتند.

{{ IF tags }}
{{ FOREACH tag IN post.tags.values }}
    <a href="{{ tag.url }}">{{ tag.name }}</a>
{{ END }}
{{ END }}

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

image
description
author
category
tags
categories
keywords
suggests

که به جز keywords و suggests، در story و image در آموزش لینوکس و وبلاگ فارسی، مابقی را به عنوان لیست آرشیو برای سایت‌هایشان هم در نظر گرفته بودیم. با توجه به تمام توضیحاتی که دادیم قالب post را به این صورت می‌سازیم، کدهای زیر را در post.tt2 کپی کنید:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
    <meta charset="utf-8">
    <meta name="description" content="{{ DESCRIPTION }}">
    <meta name="author" content="{{ MainAUTHOR }}">
    <link rel="shortcut icon" href="{{ MAIN.author_image }}">
    <title>{{ PageTITLE }}</title>
    <style>
    img {
    max-width: 100% !important;
    }
    </style>
</head>
<body>
<body>
    <center>
    <img src="{{ SITE.author_image }}">
    <h1>{{ TITLE }}</h1>
    <h2>{{ DESCRIPTION }}</h2>
    </center>
    <hr>
    <table>
    <tr>
<!-- Content -->
    <td width="70%">
    {{ FOREACH post IN POSTS }}
      <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
      <h5>{{ post.CALENDAR.jday_name }} {{ post.CALENDAR.jday }} {{ post.CALENDAR.jmonth_name }} {{ post.CALENDAR.jyear }}</h5>
      <h5>{{ post.CALENDAR.day_name }} {{ post.CALENDAR.day }} {{ post.CALENDAR.month_name }} {{ post.CALENDAR.year }}</h5>
      {{ IF post.description }}description: {{ post.description }}{{ END }}<br>
      {{ IF post.image }}<img src="{{ post.image }}">{{ END }}
      {{ IF post.author }}
      author: {{ FOREACH author IN post.author.values }}<a href="{{ author.url }}">{{ author.name }}</a>{{ END }}<br>
      {{ END }}
      <p>{{ post.body.more }}</p>
      {{ IF post.category }}
      category: {{ FOREACH cat IN post.category.values }}<a href="{{ cat.url }}">{{ cat.name }}</a>{{ END }}<br>
      {{ END }}
      {{ IF post.tags }}
      tags: {{ FOREACH tag IN post.tags.values }}<a href="{{ tag.url }}">{{ tag.name }}</a>/{{ END }}<br>
      {{ END }}
      {{ IF post.categories }}
      categories: {{ FOREACH cat IN post.categories.values }}<a href="{{ cat.url }}">{{ cat.name }}</a>/{{ END }}<br>
      {{ END }}
      {{ IF post.keywords }}
      keywords: {{ FOREACH kw IN post.keywords }}{{ kw }}/{{ END }}<br>
      {{ END }}
      <hr>
    {{ END }}
    </td>
<!-- sidebar -->
    <td width="30%">
    </td>
    </tr>
<!-- pagination -->
    <tr>
      <td width="30%">
      {{ IF PAGE.prev }}
        <a href="{{ PAGE.prev.url }}">prev: {{ PAGE.prev.title }}</a>
      {{- END }}
        |
      {{ IF PAGE.next }}
            <a href="{{ PAGE.next.url }}">next: {{ PAGE.next.title }}</a>
      {{- END }}
      </td>
    </tr>   
    </table>
</body>
</html>

نکته:
پیش از این در قسمت تنظیمات گفته شد که هر فیلدی که در تنظیمات اختصاصی سایت نباشد، مقدارش برابر با مقداری است که در فایل تنظیمات عمومی وجود دارد، اگر به یاد داشته باشید برای همین هم در تنظیم سایت دنباله دار، فیلد لیست را به صورت خالی وارد کردیم.

حالا خطوط ۷ و ۱۷ قالب post را ببینید، در تنظیمات هیچ‌کدام از سایت‌ها فیلدی به نام author_image وجود نداشت این فیلد را تنها در تنظیمات عمومی نوشته بودیم، اما در خط ۱۷ به جای MAIN که متعلق به تنظیمات عمومی است، با SITE که برای تنظیمات سایت‌هاست، آن را لود کرده‌ایم و مقدار معتبری بر میگرداند.
البته استفاده از این تگ منطقی نیست و فقط برای مثال و درک بهتر کارکرد فیلدها در تنظیمات به این صورت نوشته شده.

feed template

آخرین فایل atom.tt2 که برای ساختن فید مطالب هر سایت به کار می‌رود، البته میتوانید با هر یک از استانداردهای مورد قبول که دوست دارید فید خود را بسازید و الزامی به atom بودن آن نیست، نهایتا خروجی این فایل، فایل feed.xml در شاخه اصلی هر سایت خواهد بود.

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>{{ TITLE }}</title>
    <description>{{ DESCRIPTION }}</description>
    <link>{{ URL }}</link>
    <atom:link href="{{ URL }}/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>{{ Build.date }}</pubDate>
    <lastBuildDate>{{ DATE }}</lastBuildDate>
    <generator>mira</generator>
    {{ FOREACH post IN POSTS }}
        <item>
          <title>{{ post.title }}</title>
          <description>{{ post.body.more | html }}</description>
          <pubDate>{{ post.date }}</pubDate>
          <link>{{ post.url }}</link>
          <guid isPermaLink="true">{{ post.url }}</guid>
    {{- FOREACH list IN SITE.lists -}}
        {{ IF post.$list }}
        <{{ list }}>
           {{- FOREACH arch IN post.$list.values -}}
            {{- arch.name -}}
            {{- IF (loop.index != loop.max) -}},{{- END -}}
           {{- END -}}
        </{{ list }}>
        {{ END }}
    {{- END -}}
        </item>
    {{ END }}
  </channel>
</rss>

نکته: در این قالب چند نکته جدید را می‌بینید، یکی برچسب BUILD که اطلاعات زمان اجرای فرمان build را در خود دارد، مانند CALENDAR برای هر پست

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

{{- FOREACH list IN SITE.lists -}}
        {{ IF post.$list }}
    ...
    ...
       {{- FOREACH arch IN post.$list.values -}}

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

حلقه‌ی بالا برای نمایش دادن تمام لیست‌های آرشیو موجود در هر سایت است، یعنی مثلا اگر category در هدر باشد، مقدار یا مقدارهای آن‌را به نمایش در می‌آورد، اما ممکن است بپرسید چرا در قالب post از این روش استفاده نکردیم و با استفاده از IF و FOREACH جدا جدا هر لیست را لود کردیم؟!

جواب ساده است، برای اینکه کنترل بیشتری بر روی مکان هر آرشیو داشته باشیم، میخواستیم ترتیب لیست‌ها و مکان قرار گیریشان در قالب دقیقا تحت کنترل خودمان باشد، مثلا نام نویسنده را قبل از بدنه محتوا قرار بدهیم و دسته بندی ها را بعد از آن. اما برای feed نیازی به این مورد نداشتیم، فقط نیاز داریم همه‌ی لیست‌ها دقیقا بعد از متن نمایش داده شوند.

همچنین از یک شرط جدید هم استفاده شده:

{{- IF (loop.index != loop.max) -}},{{- END -}}

با استفاده از loop میتوانیم مشخصات حلقه‌ی در حال اجرا را چک کنیم، loop.index می‌گوید که مرتبه چندم از اجرای حلقه هستیم و loop.max، حداکثر دفعاتی که یک حلقه FOREACH با توجه به سایز لیستی که لود کرده خواهد داشت.

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

بدون این شرط، برچسب زیر vimrc,terminal,vimrc bank,ترمینال,vim

به شکل زیر، بعد از vim یک کامای اضافه نمایش داده خواهد شد:

<tags>vimrc,terminal,vimrc bank,ترمینال,vim,</tags>

و نکته‌ی آخر، بعضی از خط ها بعد و قبل از استفاده از جفت آکولادها {{ }} از یک خط تیره - استفاده شده {{- -}}، آکولادها قبل و بعد از خود یک کاراکتر خط جدید را هم به نمایش در می‌آورند. البته برای ساختن قالب‌های html چندان اهمیتی ندارند، چرا که در html تا از
یا

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

ساختن یک ساید بار

حالا وقت آن رسیده که با ساختن یک ساید بار آرشیوهایی که برای هر سایت را داشتیم را هم به نمایش درآوریم، برای این کار قبلا در میانه‌های قالب‌های index، archive و post یک قسمت را آماده گذشاته بودیم:

<!-- sidebar -->
<td width="30%">
</td>

حالا زمان آن را رسیده که آن را تکمیل کنیم. برای نمایش لیست‌های آرشیو دو راه حل داریم، یکی به شکل کلی تمام آرشیوهای موجود را لود کنیم، مانند کاری که در انتهای قالب atom کرده بودیم، و یکی هم مثل قالب post، روشی که به ما امکان میدهد هر لیست را جدا و در جایی که میخواهیم نمایش دهیم.

روش اول، لود کردن همه چیز:

{{ FOREACH archive IN ARCHIVES.pairs }}
  <h5>{{ archive.key }}</h5><!-- archive name, like tags or dates ... -->
  <hr>
  {{ FOREACH item IN archive.value.values.sort('name').sort('number') }}
    <a href="{{ item.url }}">{{ item.name }}</a>
    {{ IF (archive.key == 'categories') }}<br>{{ END }}
    {{ IF (archive.key == 'date') or (archive.key == 'jdate') }}<br>{{ END }}
    {{ IF (archive.key == 'author') }}<br>{{ END }}
    {{ IF (loop.index != loop.max) and (archive.key == 'tags') }}&nbsp;-&nbsp;{{ END }}
    {{ IF (archive.key == 'category') }}
    <br>
    {{ FOREACH utid IN item.posts }}
        &nbsp;&nbsp;-&nbsp;<a href="{{ ENTRIES.$utid.url }}">{{ ENTRIES.$utid.title }}</a><br>
    {{ END }}
    {{ END }}
  {{- END }}
  <br>
{{- END }}

توضیح:

ابتدا یک جفت کلید-مقدار از آرشیوها را در متغیری به نام archive لود کردیم archive IN ARCHIVES.pairs، کلید با نام key حاوی نام آرشیو است، مثل category یا tag یا هر چیز دیگری {{ archive.key }}.

مقدار یا value حاوی یک لیست از اطلاعات مربوط به آن آرشیو است archive.value، که این لیست شامل این اطلاعات است: نام، آدرس لینک هر آرشیو، و utid پست‌هایی که در این آرشیو هستند. مثل همیشه، برای نمایش دادن لیست‌ها از FOREACH استفاده می‌کینم.

{{ FOREACH item IN archive.value.values.sort('name').sort('number') }}

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

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

خطوط ۱۰ تا ۱۵: گفتیم که مقدار هر آرشیو لیستی است که utid پست‌هایی که در آن دسته بندی هستند را هم در خود دارد، بین این خطوط مشخص کردیم تیتر و لینک تمام نوشته‌هایی که در دسته بندی هستند، زیر نام آن دسته بندی نمایش داده شوند.با استفاده از ENTRIES.$utid تمام کارهایی که برای نمایش پست ها با POSTS انجام میدادیم را میتوان انجام داد، مثلا خلاصه‌ی متن را لود کرد:

ENTRIES.$utid.body.less

روش دوم، نمایش دادن با ترتیب دلخواه

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

{{ IF CATEGORIES_ARCHIVE }}
<h3>categories archive</h3>
{{ FOREACH cat IN CATEGORIES_ARCHIVE }}
  <a href="{{ cat.url }}">{{ cat.name }}</a> - <small>{{ cat.posts.size }}</small><br>
{{ END }}
{{ END }}
<hr>

نکته‌: همانطور که در مثال قبل هم گفتیم، لیست‌های آرشیو علاوه بر نام و آدرس، پست‌هایی که در دسته بندیشان قرار میگیرد را هم در خود دارند، در مثال قبل با استفاده از posts مقدار utid ها را به دست آوردیم و در ENTRIES لود کردیم، اینجا فقط تعدادشان را گرفتیم و مشخص کردیم در هر دسته بندی چه تعداد نوشته داریم. {{ cat.posts.size }}

برای نمایش کامل تمام آرشیوها در این مثال باید از کد زیر استفاده کرد، در این مثال هم در قسمت category تمام پست ها را با استفاده از utid نمایش می‌دهیم:

{{ IF CATEGORIES_ARCHIVE }}
<h3>categories archive</h3>
{{ FOREACH cat IN CATEGORIES_ARCHIVE }}
   <a href="{{ cat.url }}">{{ cat.name }}</a> - <small>{{ cat.posts.size }}</small><br>
{{ END }}<hr>
{{ END }}

{{ IF CATEGORY_ARCHIVE }}
<h3>category archive</h3>
{{ FOREACH cat IN CATEGORY_ARCHIVE }}
  <a href="{{ cat.url }}">{{ cat.name }}</a> - <small>{{ cat.posts.size }}</small><br>
    <br>
    {{ FOREACH utid IN cat.posts }}
        &nbsp;&nbsp;-&nbsp;<a href="{{ ENTRIES.$utid.url }}">{{ ENTRIES.$utid.title }}</a><br>
    {{ END }}
{{ END }}
<hr>
{{ END }}

{{ IF TAGS_ARCHIVE }}
<h3>categories archive</h3>
{{ FOREACH tag IN TAGS_ARCHIVE }}
  <a href="{{ tag.url }}">{{ tag.name }}</a> - <small>{{ tag.posts.size }}</small><br>
{{ END }}
<hr>
{{ END }}

{{ IF AUTHOR_ARCHIVE }}
<h3>author archive</h3>
{{ FOREACH author IN AUTHOR_ARCHIVE }}
  <a href="{{ author.url }}">{{ author.name }}</a> - <small>{{ author.posts.size }}</small><br>
{{ END }}
<hr>
{{ END }}

{{ IF DATE_ARCHIVE }}
<h3>date archive</h3>
{{ FOREACH date IN DATE_ARCHIVE }}
  <a href="{{ date.url }}">{{ date.name }}</a> - <small>{{ date.posts.size }}</small><br>
{{ END }}
<hr>
{{ END }}

{{ IF JDATE_ARCHIVE }}
<h3>jalali archive</h3>
{{ FOREACH date IN JDATE_ARCHIVE }}
  <a href="{{ date.url }}">{{ date.name }}</a> - <small>{{ date.posts.size }}</small><br>
{{ END }}
<hr>
{{ END }}

یکی از دو روش بالا را انتخاب کنید، سپس کدهای نوشته شده را در قالب‌های post, index و archive کپی کنید

<!-- sidebar -->
<td width="30%">
   >>> اینجا کپی کنید
</td>

در فایل‌های مثال که برای دانلود کردن آماده شده از روش اول در قالب archive و روش دوم برای index و post استفاده شده.

تکمیل کردن قالب post

زمانی که داشتیم سربرگ‌ها را تنظیم می‌کردیم برای سایت داستان ها یا همان دنباله دار، یک فیلد به نام suggests برای نمایش دادن داستان‌های مشابه تعریف کردیم که تا اینجا از آن استفاده نکردیم، حالا وقت آن رسیده که این فلد را هم به قالبمان اضافه کنیم.

در فایلی که برای محتوا دانلود کردید، به این شاخه‌ی story بروید و این دو فایل را باز کنید:

~/mira/content/story/1394-12-11-the-selfish-gene.md
~/mira/content/story/1395-2-27-sleep.md

در فایل sleep در فیلد suggests آدرس ایستای دو داستان دیگر وارد شده، برای نمایش دادن آن می‌توان از کدی شبیه به این استفاده کرد:

{{ FOREACH suggest IN post.suggests }}
    {{ FOREACH entry IN ENTRIES.values }}
        {{ IF entry.url == suggest }}
            <a href="{{ entry.url }}">{{ entry.title }}</a><br>
        {{ END }}
    {{ END }}
{{ END }}

در یک حلقه مقدار هر آدرس را در suggest لود کردیم، سپس در حلقه‌ی درونی تمام پست‌ها را گشتیم، اگر پستی که آدرس مشابه با suggest داست، نام و آدرس آن را نمایش دادیم.

در فایل the-selfish-gene اما utid دو داستان را برای suggests وارد کردیم، برای نمایش دادنشان از کدهای زیر می‌توان استفاده کرد:

{{ FOREACH suggest IN post.suggests }}
    {{ IF ENTRIES.$suggest.url }}
        <a href="{{ ENTRIES.$suggest.url }}">{{ ENTRIES.$suggest.title }}</a><br>
    {{ END }}
{{ END }}

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

برای اینکه از هر دو روش همزمان در قالب استفاده کنیم، یک بار دیگر فایل post.tt2 را برای ویرایش کردن باز کنید، این چند خط را پیدا کنید:

{{ IF post.keywords }}
keywords: {{ FOREACH kw IN post.keywords }}{{ kw }}/{{ END }}<br>
{{ END }}

کد زیر را بعد از آن اضافه کنید:

{{ IF post.suggests }}
    <hr/>
<p>suggests:</p>
{{ FOREACH suggest IN post.suggests }}
    {{ IF ENTRIES.$suggest.url }}
        <a href="{{ ENTRIES.$suggest.url }}">{{ ENTRIES.$suggest.title }}</a><br>
    {{ END }}
    {{ FOREACH entry IN ENTRIES.values }}
    {{ IF entry.url == suggest }}
            <a href="{{ entry.url }}">{{ entry.title }}</a><br>
        {{ END }}
    {{ END }}
{{ END }}
{{ END }}

مرتب کردن چیدمان

اگر تا این مرحله دستور build را اجرا نکردید، حتما یک بار آن را امتحان کنید

mira build

و بعد یک پیش نمایش از سایت را برای خود اجرا کنید:

mira view

حالا به این آدرس بروید:

127.0.0.1:5000/blog/

می‌بینید که همه نوشته‌ها چپ به راست نوشته شده‌اند و اصلا برای نمایش زبان فارسی مناسب نیستند.

همانطور که در تنظیم پیکربندی دیدید، در تنظیم هر سایت یک فیلد به نام lang را ساخته بودیم، حالا زمان استفاده از آن است.

برای راست‌چین کردن محتوای فارسی از یک شرط IF و مقدار فیلد lang در فایل config اختصاصی هر سایت استفاده میکنیم.

استفاده از مقدار فایل‌های config اختصاصی طبقات در قالب main و سایر قالب‌ها با هم متفاوت است. برای اینکه از این مقادیر در main استفاده کنیم، حتما باید داخل حلقه‌ی FLOORS باشیم، اما در سایر قالب‌ها در هر جای قالب که باشیم قابل دسترسی هستند.

برای اینکه تنوع استفاده و روش‌های متفاوت استفاده از بلوک‌های شرطی IF را ببینید، با دو روش متفاوت این مثال را پیش می‌بریم. انتخاب روش دلخواه با خود شماست.

یک بار دیگر فایل main.tt2 را باز کنید و به حلقه‌ی FOREACH FLOORS این کدها را اضافه کنید:

{{ IF site.SITE.lang == 'fa' }}
   <div dir="rtl">
{{ ELSE }}
   <div>
{{ END }}

حالا باید نتیجه چیزی شبیه به این شده باشد:

{{ FOREACH site IN FLOORS.values.sort('name') }}
  <td style="border-right: 1px solid black; width: 25%;" valign="top">
     {{ IF site.SITE.lang == 'fa' }}   <!-- add -->
    <div dir="rtl">                <!-- add -->
     {{ ELSE }}                        <!-- add -->
    <div>                          <!-- add -->
     {{ END }}                         <!-- add -->
  <h2><a href="{{ site.root }}">{{ site.name }}</a></h2>
  <p>{{ site.description }}</p>
  <hr>
  <ul>
  {{ FOREACH post IN site.posts }}
    <li><h4><a href="{{ post.url }}">{{ post.title }}</a><h4></li>
    {{ post.body.less }}
  {{ END }}
  </ul>
     </div>                            <!-- add -->
  </td>
{{ END }} 

حالا فایل‌های post.tt2، archive.tt2 و index.tt2 را باز کنید و این شرط را در قسمت head سایت به style اضافه کنید:

{{ IF SITE.lang == 'fa' }}
body {
   direction: rtl;
}
{{ END }}
{{ IF SITE.lang == 'en' }}
body {
   direction: ltr;
}
{{ END }}

حالا head باید به این شکل در آمده باشد:

<head>
    <meta charset="utf-8">
    <meta name="description" content="{{ DESCRIPTION }}">
    <meta name="author" content="{{ MainAUTHOR }}">
    <link rel="shortcut icon" href="{{ MAIN.author_image }}">
    <title>{{ PageTITLE }}</title>
    <style>
    entry img {
    max-width: 100% !important;
    }
    {{ IF SITE.lang == 'fa' }}
    body {
       direction: rtl;
    }
    {{ END }}
    {{ IF SITE.lang == 'en' }}
    body {
       direction: ltr;
    }
    {{ END }}
    </style>
</head>

نکته: برای استفاده از IF به جز ELSE از ELSIF هم می‌توانید استفاده کنید.

پوسته‌های بیشتر برای هر قالب و تغییر آدرس

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

پوسته‌های متفاوت برای هر آرشیو

برای داشتن پوسته‌ی متفاوت برای هر آرشیو، کافی است هم‌نام با آن آرشیو یک فایل در دایرکتوری قالب‌مان داشته باشیم.

برای مثال اگر بخواهیم پوسته‌ی آرشیو category با سایر آرشیوها مثل tags یا آرشیوزمانی و... متفاوت باشد، تنها کافی است در دایرکتوری قالب، یک فایل جدید به نام category.tt2 بسازیم، از این به بعد در هر سایت که آرشیوی به این نام وجود داشت، به جای استفاده از archive.tt2، با استفاده از category.tt2 خروجی آن تولید می‌شود.

پوسته‌های متفاوت برای پست ها

گاهی اوقات نیاز داریم آدرس ثابت یک نوشته با سایر نوشته‌ها متفاوت باشد، مثلا برای ساختن page ها یا هر دلیل دیگر. برای این‌که به میرا بگوییم به جای post.tt2 از پوسته‌ی دیگری برای ساختن خروجی یک پست استفاده کند، باید در سربرگ آن پست به فیلد _layout مقدار بدهیم. برای مثال:

_layout: custom_post_template

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

تغییر آدرس

همچنین می‌توان آدرس انتشار یک پست را از فرمت تعیین شده در فایل کانفیگ اختصاصی سایتی که در آن منتشر می‌شود جدا کرد. برای مثال در فایل blog-fa.yml به فیلد permalink این مقدار را داده بودیم:

:year/:month/:day/:title.html

اما اگر در سربرگ هر کدام از پست‌ها فیلد _permalink را مقدار دهی کنیم، این مسیر تنها برای آن پست تغییر میکند:

_permalink: :year/:title/
یا
_permalink: /:title/
یا
_permalink: some/thing/else/:title.php

گام هفتم: شخصی سازی بیشتر

ساختن صفحات

برای ساختن صفحات ثابت جدا از روند اصلی سایت، مثل صفحه درباره یا تماس و ... با اضافه کردن فیلد type و مقدار page در هدر هر پست، آن پست را به عنوان صفحه ثابت به میرا معرفی می‌کنیم، این کار باعث میشود که پست مورد نظر از لیست‌های مطالب برای نمایش در صفحه اول یا سایر صفحه‌های سایت و page.next و page.prev برای حرکت بین پست‌ها حذف شده و تنها با وارد کردن آدرس مستقیم آن نمایش داده شود.

در وبلاگ فارسی یک پست جدید بسازید:

mira new -t 'about me' -f blog-fa

حالا آن را ویرایش کنید:

---
utid: 20170328195013
title: درباره من
_index: about
_type: page
_layout: page
_permalink: /:title/
---
این صفحه در باره من است، اینجا مقداری در مورد خودم توضیح می‌دهم

حالا در شاخه‌ی قالب my-theme یک فایل جدید به نام page بسازید:

~/mira/template/my-theme/page

و مقادیر زیر را در آن کپی کنید:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="description" content="{{ DESCRIPTION }}">
    <meta name="author" content="{{ MainAUTHOR }}">
    <link rel="shortcut icon" href="{{ MAIN.author_image }}">
    <title>{{ PageTITLE }}</title>
    <style>
    img {
    max-width: 100% !important;
    }
    {{ IF SITE.lang == 'fa' }}
    body {
       direction: rtl;
    }
    {{ END }}
    {{ IF SITE.lang == 'en' }}
    body {
       direction: ltr;
    }
    {{ END }}
    </style>
</head>
<body>
    <center>
    <img src="{{ SITE.author_image }}">
    <h1>{{ post.title }}</h1>
    </center>
    <hr>
    <table>
    <tr>
    <td>
      <p>{{ post.body.more }}</p>
    </td>
    </tr>
    </table>
</body>
</html>

این پست در صفحه اصلی یا هیچ‌کجای دیگر سایت نمایش داده نخواهد شد، تنها راه دسترسی به آن دادن لینک مستقیم به این صفحه در این آدرس است:

/blog/about/

آدرس‌های تکراری

همیشه این امکان وجود دارد که دو نوشته شما یک آدرس مشابه به خود بیرند، مخصوصا وقتی که در سیستم آدرس‌دهی برای هر نوشته، به جز تیتر آن هیچ شرط دیگری مثل تاریخ یا دسته بندی و... را ذکر نمی‌کنید، مثل کاری که در این مثال برای انتشار داستان‌ها کردیم.

به هر حال همیشه این احتمال وجود دارد که دو پست آدرس یکسیانی به ود بگیرند، فرض کنیم که در فایل کانفیگ سایت فیلد permalink را به این شکل ساخته باشیم:

permalink: :year/:month/:day/:title/

و در یک روز دو پست را با این مشخصات نوشته باشیم: post1:

---
utid: 20170325151121
date: 2017/03/25
title: آزمایش
_index: test
category: آموزش
tags:
 - یک
 - دو
---

post2:

---
utid: 20170325162308
date: 2017/03/25
title: test
category: learn
tags:
 - one
 - two
---

هر دو پست دقیقا در یک روز منتشر شده‌اند، اولی _index با مقدار test دارد و دومی هم که index ندارد، از تیتر test استفاده کرده، پس با توجه به مقدار permalink در کانفیگ، آدرس هر دو پست این آدرس خواهد بود:

/2017/03/25/test/

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

post1: >  /2017/03/25/test/
post2: >  /2017/03/25/test/2/

در صورتی هم که permalink به جای آدرس خالص، از نام فایل در آن استفاده شده باشد، مثل:

permalink: :year/:month/:day/:title.html

آدرس‌ها به این صورت ساخته خواهند شد:

post1: >  /2017/03/25/test.html
post2: >  /2017/03/25/2/test.html

اما اگر نخواهید میرا برای شما آدرس‌ها را بسازد، مثلا بخواهید به جای 2 از 'second edition' در آدرس استفاده کنید، می‌توانید در هدر همان پست فیلد _permalink ار مقدار دهی کنید، برای مثال میتوانیم دو پست را به این شکل داشته باشیم:

post1:

---
utid: 20170325151121
date: 2017/03/25
title: آزمایش
_index: test
category: آموزش
tags:
 - یک
 - دو
---

post2:

---
utid: 20170325162308
date: 2017/03/25
title: test
_permalink: :year/:month/:day/:title/second-edition/
category: learn
tags:
 - one
 - two
---

یا حتی از یک فرمول به جز فرمول کانفیگ سایت استفاده کنیم:

_permalink: :category/:title/second-edition/
یا
_permalink: :year/second-edition/:title/
یا
_permalink: :title/

اگر فایل‌های این مثال را دانلود کرده باشید، در وبلاگ فارسی و داستان، دو مطلب تکراری وجود دارد که آدرس مشابه میگیرند، آن‌ها را هر طور که دوست دارید اصلاح کنید.

تغییر آدرس آرشیو‌ها

دیدیم که در تنظیم کردن هر سایت برای آدرس‌دهی به هر پست می‌توانیم از مشخصات آن پست استفاده کنیم، برای مثال:

permalink: :category/:title.html
یا
permalink: :author/:year/:title

حالا ممکن است دسته بندی موضوعی به نام آموزشی داشته باشیم، آدرس ثابت با استفاده از مدل اول این خواهد بود:

SITE_ADDRESS.com/آموزش/post-title.html

و اگر آرشیوی بر اساس category ساخته باشیم هم آدرس مطالب دسته بندی آموزشی این خواهد بود:

SITE_ADDRESS.com/category/آموزش/

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

SITE_ADDRESS.com/محمد-محمدی/post-title/

و آدرس آرشیو این نویسنده:

SITE_ADDRESS.com/author/محمد-محمدی/

یا اینکه یک دسته بندی با نام طولانی داشته باشیم، مثلا نام دسته بندی این نام باشد: learn use vim in gnu linux systems
آدرسذها این شکلی خواهتد بود:

SITE_ADDRESS.com/learn-use-vim-in-gnu-linux-systems/post-title.html
و 
SITE_ADDRESS.com/category/learn-use-vim-in-gnu-linux-systems/

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

حالا برای تمرین این مثال، در وبلاگ فارسی یک نوشته جدید به جود بیاورید و در قسمت category مقدار آزمایش را وارید کنید.

---
utid: 20170326160744
date: 2017-03-26 16:07:44
title: فضای نام
_index: namespace
category: آزمایش
---

آدرسی که به این پست اختصاص داده می‌شود:

YOUR_ADDRESS.COM/آزمایش/a2017/03/26/namespace.html

حالا اگر میخواهید از فضای نام‌ها تمام سایت‌ها به شکل عمومی استفاده کنند در فایل config.yml و اگر میخواهید تنها در وبلاگ فارسی این فضای نام فعال باشد در فایل config/blog-fa.yml فیبدی به نام namespace را به این شکل به وجود بیاورید:

namespace:
  آزمایش: test
  آموزش: learn
  کتاب: book
  شخصی: personal
  عمومی: general
  محمد محمدی: mohamad mohamadi

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

YOUR_ADDRESS.COM/test/2017/03/26/namespace.html
و آدرس آرشیو:
SITE_ADDRESS.com/category/test/

یا اگر دسته بندی کتاب داشته باشیم:

YOUR_ADDRESS.COM/book/2010/10/10/post-title.html
SITE_ADDRESS.com/category/book/

اضافه کردن لینک شبکه‌های اجتماعی

برای افزودن لینک خودمان در شبکه‌های اجتماعی به جایی مثل ساید باز هم میرویم سراغ کانفیگ‌ها و اضافه کردن چند خط به هرکدامشان

فرض میکنیم لینکی که می‌خواهیم برای شبکه‌های اجتماعی در نظر بگیریم در تمام سایت‌ها ثابت نیست و برای هر سایت یک کانال، یا اکانت جدا در شبکه‌های اجتماعی و یک کانال در پیام رسان تلگرام را ساخته‌ایم.

از اینجای مثال فقط برای وبلاگ فارسی همه چیز را در نظر می‌گیریم، اما می‌توانید برای سه سایت دیگر هم به همین شکل کار را انجام دهید یا کلا این همه چیز را به جای تنظیم اختصاصی هر سایت در تنظیم‌های عمومی بگنجانید و در همه‌ی سایت‌ها از همان تنظیم استفاده کنید.

آدرس ها را هم این‌ها در نظر میگیریم:

وبلاگ فارسی:

twitter.com/@MY_FA_BLOG_MIRA telegram.me/MY_FA_BLOG_MIRA

حالا به blog-fa.yml کدهای زیر را اضافه می‌کنیم:

~/mira/config/blog-fa.yml

socials:
 -
  name: twitter
  url: https://twitter.com/MY_FA_BLOG_MIRA
 -
  name: instagram
  url: https://instagram.com/MY_FA_BLOG_MIRA
 -
  name: github
  url: https://github.com/MY_FA_BLOG_MIRA

به فاصله‌ها دقت کنید، هر بخش که داخل رفتیم، یک خط فاصله اضافه شده است، socials در ابتدای خط است، قبل از هر خط تیره - یک space وجود دارد و یک مرحله فرورفتگی ایجاد شده و بعد، قبل از name و url دو خط فاصله یا همان space هست، یعنی دو مرحله فرورفتگی.

حالا در my-theme فایل index.tt2 را باز می‌کینم و هر کجا که خواستیم شبکه‌های اجتماعی را نمایش دهیم این کدها را به آن اضافه می‌کنیم، مثلا در بالاترین قسمت sidebar:

<td width="30%" valign="top">
{{ IF SITE.socials }}
    <h3>socials</h3>
    {{ FOREACH social IN SITE.socials }}
        <a href="{{ social.url }}">{{ social.name }}</a>>ذق<
    {{ END }}
{{ END }}

برای هر کدام از چهار سایت دیگر هم می‌توان همین کار را تکرار کرد، یا اینکه برای همه سایت‌ها از یک آدرس مشترک در شبکه‌های اجتماعی استفاده کنیم و همه اطلاعات را در config.yml وارد کنیم، در این حالت برای نمایش لینک‌ها در سایت، به جای SITE.socials باید از MAIN.socials استفاده کرد.

افزودن مشخصات نویسنده مطلب

اگر به یاد داشته باشید در سایت آموزش لینوکس، بیشتر از یک نویسنده برای مطالبمان داشتیم، حالا میخواهیم یک اطلاعات کلی از هرکدام را به سایدبار در زیر آرشیو نام‌هایشان اضافه کنیم، ابتدا linux-learn.yml را ویرایش میکنیم و خطوط زیر را در آن می‌نویسیم:

authors:
 -
  name: farbodgame
  desc: توضیحاتی در مورد کاربر
  twitter: twitter.com/TWITTER_USER_NAME
 -
  name: MrNull
  desc: توضیحاتی در مورد کاربر
  twitter: twitter.com/TWITTER_USER_NAME
 -
  name: rmasoumvand
  desc: توضیحاتی در مورد کاربر
  twitter: twitter.com/TWITTER_USER_NAME

به فاصله‌ها دقت کنید، هر بخش که داخل رفتیم، یک خط فاصله اضافه شده است، authors در ابتدای خط است، قبل از هر خط تیره - یک space وجود دارد و یک مرحله فرورفتگی ایجاد شده و بعد، قبل از name، desc و twitter دو خط فاصله یا همان space هست، یعنی دو مرحله فرورفتگی.

بعد قالب index.tt2 را باز کنید و در sidebar، بلوک کد {{ IF AUTHOR_ARCHIVE }} را پیدا کنید و به جای آن کدهای زیر را کپی کنید:

{{ IF AUTHOR_ARCHIVE }}
<h3>author archive</h3>
{{ FOREACH author IN AUTHOR_ARCHIVE }}
  <a href="{{ author.url }}">{{ author.name }}</a> - <small>{{ author.posts.size }}</small>
<!-- این قسمت به کد اضافه شده است -->
  {{ IF SITE.authors }}
  {{ FOREACH auth IN SITE.authors }}
  {{ IF author.name == auth.name }}
    <ul>
    <li>{{ auth.desc }}</li>
    <li><a href="{{ auth.twitter }}">twitter</a></li>
    </ul>
  {{ END }}
  {{ END }}
  {{ END }}
<!-- تا اینجا -->
{{ END }}
<hr>
{{ END }}

تغییر آدرس انتشار سایت‌ها

در تنظیمات دیدیم که ریشه‌ی اصلی سایت را برای یک صفحه‌ی مشترک بین تمام سایت‌ها در نظر گرفتیم و بعد برای هر سایت یک آدرس در لول پایینتر مشخص کردیم:

your-address.com/          >    صفحه مشترک بین هر چهار سایت
your-address.com/blog/     >    وبلاگ فارسی
your-address.com/en/       >    وبلاگ انگلیسی
your-address.com/story/    >    داستان‌ها
your-address.com/linux/    >    آموزش لینوکس

اما شاید بخواهید ریشه اصلی سایت را برای وبلاگ فارسی در نظر بگیرید و صفحه‌ی مشترک را در زیر آدرس دیگری بسازید، مثل این:

your-address.com/main/     >    صفحه مشترک بین هر چهار سایت
your-address.com/          >    وبلاگ فارسی

برای این منظور config.yml و config/blog-fa.yml را ویرایش کنید و url و root را تغییر دهید:

config.yml

url: your-address.com/main
root: /main

config/blog-fa.yml

url: your-address.com/
root: /

یا شاید اصلا نخواهید صفحه‌ی مشترک را داشته باشید، برای اینکار url و root را در config.yml با مقدار url و root در config/blog-fa.yml یکی قرار دهید. در صورت مساوی شدن مقدار این دو فیلد بین main و طبقات، اولویت با طبقات است. در این صورت دیگر صفحه مشترکی نخواهید داشت. میتوانید main.tt2 را هم از قالبتان پاک کنید.

config.yml

url: your-address.com/
root: /

config/blog-fa.yml

url: your-address.com/
root: /

گام هشتم: انتشار

انتخاب محل انتشار

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

می‌توانید از یکی از سرویس‌هایی که فایل‌های استاتیک را برای انتشار پشتیبانی می‌کنند مثل گیت‌هاب، استفاده کنید و یک دامین روی همان سرویس‌ها انتخاب کنید، یا از یک دامین شخصی و فضای ارايه شده توسط سرویس‌ها استفاده کنید، یا کلا از فضا و دامنه شخصی استفاده کنید.

در این قسمت سعی می‌کنیم برای انتخاب کردن هر یک از سه راه بالا، یک راه‌حل پیدا کنیم.

پیش نیاز: قبل از ادامه این بخش:

۱- اگر گیت را روی کامپیوترتان نصب نکرده‌اید، آن‌را نصب کنید، دانلود گیت

۲- اگر روی گیت‌هاب اکانت ندارید، یک اکانت بسازید. GitHub

انتشار روی فضای شخصی

اگر فضای میزبانی یا همان هاست شخصی خودتان را دارید، کار زیادی لازم نیست انجام بدهید، محتوای دایرکتوری public را پس از ساخته شدن به public_html یا www یا هر دایرکتوری دیگری که برای انتشار محتوای سایتتان مشخص کرده‌اید منتقل کنید.

اگر از سرور خودتان استفاده می‌کنید و میرا را روی سرور اجرا می‌کنید، آدرس همین دایرکتوری public را به عنوان root در تنظیمات سرور مشخص کنید.

یا اینکه mira view را روی هر portی که می‌خواهید اجرا کنید و مشخصات listen را برای سایتتان با port میرا یکی کنید.

این قسمت ادامه خواهد داشت، برای تعییر فایل‌های تنظیم سرور و... که در بالا در موردشان صحبت شد چند مثال و توضیح، در آینده اضافه خواهد شد.

استفاده از گیت‌هاب برای انتشار

هدف در این بخش از راهنما شرح دادن چگونگی منتشر کردن سایتی که با میرا ساخته‌اید بر روی گیت هاب است. برای بهتر متوجه شدن این قسمت نیاز به یک آشنایی حداقلی با گیت‌هاب و چگونگی ساختن مخازن جدید در آن و دانستن مفاهیم و تفاوت‌های مخزن (repository یا repo) با شاخه یا انشعاب یا همان branch دارید.

برای آشنایی بیشتر با صفحات گیتهاب میتوانید مستندات آنرا در این لینک بخوانید: User, Organization, and Project Pages

گیت‌هاب برای استفاده از سرویس pages، راه‌های متفاوتی ارائه می‌کند.

۱- استفاده از دایرکتوری docs در branch master

۲- استفاده از branch فرعی با نام gh-pages

۳- انتشار محتوای ذخیره شده در master

در زیر به شکل کلی در مورد این سه روش می‌خوانیم و در ادامه برای استفاده از هرکدام به شکل اختصاصی برای استفاده در میرا یک راه حل و مثال را پیاده می‌کنیم.

انتشار با استفاده از دایرکتوری /docs در شاخه‌ی master

بر اساس راهنمای صفحات گیت هاب، در صفحات گیت‌هاب با استفاده از docs می‌توان دست به انتشار محتوا زد، راه حل داشتن یک دایرکتوری به نام docs در شاخه‌ی master هر مخزن است.

اگر خواستید از این روش استفاده کنید، باید دایرکتوری public را به docs تغییر نام دهید. برای این‌که هربار که سایت‌تان را با کمک میرا می‌سازید، نیاز به تغییر نام شاخه public نداشته باشید، تنها کافی است در config.yml این خط را اضافه کنید:

publishDIR: docs

از این به بعد، پس از هر باز اجرا کردن mira build، به جای public، میرا خروجی تولید شده را در دایرکتوری docs ذخیره می‌کند.

شاخه‌ی master را push کنید به مخزن remote و در قسمت setting پروژه در گیت هاب، مشخص کنید که از دایرکتوری docs برای انتشار صفحات استفاده می‌کنید:

Settings -> GitHub Pages -> Source -> Select master branch /docs folder

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

git init
git remote add origin git@github.com:USER/YOUR-SITE-mira.git
git add --all
git commit -m 'start'
git push origin master

از این به بعد، پس از هر بار اجرا کردن mira build و ساخته شدن سایتتان، تغییرات را به گیت اضافه و publish کنید.

mira build
git add --all
git commit -m 'add new content and publish'
git push origin master

از حالا به بعد اگر آدرس مخزنی که روی گیت هاب ساخته بودید چیزی شبیه به این آدرس بود:

github.com/USER/YOUR-SITE-mira.git

محتوای شما در آدرسی شبیه به این آدرس با استفاده از فایل‌های قرار گرفته در دایرکتوری docs منتشر خواهد شد:

USER.github.io/YOUR-SITE-mira

و اگر می‌خواهید از نام دامین اختصاصی خودتان برای نمایش محتوا استفاده کنید، فایلی به نام CNAME را در docs بسازید و نام دامنه‌ی خودتان را در آن بنویسید

echo YOUR_DOMAIN_NAME.com > CNAME

انتشار به وسیله‌ی شاخه‌ی gh-pages

راه دیگر انتشار محتوا به وسیله‌ی یک شاخه‌ی جدا به نام gh-pages در مخزن گیت است. آماده سازی آن نسبت به استفاده از شاخه‌ی docs پیچیده‌تر است، اما در مقابل مزایای بیشتری هم دارد.

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

توجه کنید: اگر چندان با گیت آشنا نیستید و دقیقا می‌خواهید قدم به قدم با مثال‌های گیت این راهنما پیش بروید، مخازنی را که در گیت‌هاب می‌سازید، کاملا خالی باشند، هنگام ساختن مخزن در گیت‌هاب، اجازه ساخته شدن فایل README یا gitignore و... را ندهید.

آماده سازی:

توضیح: این قسمت را تنها نیاز داریم یک بار انجام دهیم، در طول توضیحات فرض این است که نام remote که استفاده میکنیم origin است، اگر از نام دیگری استفاده میکنید، آن‌ را با origin جایگزین کنید.

قبل از شروع هرکاری، دایرکتوری public را پاک می‌کنیم.

rm -rf public

یا اگر در ویندوز باشیم

rd public /s /q

اول گیت را پیکربندی می‌کنیم و دایرکتوری public را به gitignore اضافه میکنیم:

git init
echo "public" > .gitignore
git add --all
git commit -m 'start'

آدرس مخزنی که در گیت‌هاب ساخته‌اید را به عنوان remote به پروژه اضافه می‌کنیم و شاخه‌ی master را push می‌کنیم.

git remote add origin git@github.com:USER/YOUR-SITE-mira.git
git push origin master

سپس شاخه‌ی gh-pages را می‌سازیم و به شکل خالی مقداردهی می‌کنیم و به مخزن remote هم آن‌را اضافه میکنیم.

git checkout --orphan gh-pages
git reset --hard
git commit --allow-empty -m "Initializing gh-pages"
git push origin gh-pages

به شاخه‌ی master بر می‌گردیم

git checkout master

و دایرکتوری public را به عنوان worktree برای شاخه‌ی gh-pages مشخص می‌کنیم.(دقت کنید که دایرکتوری public را پاک کرده باشید و هنگام اجرای این دستور وجود نداشته باشد)

git worktree add -B gh-pages public origin/gh-pages

انتشار:

اگر همه مراحل بالا بدون اشکال پیش رفته باشد، حالا همه چیز آماده است. از این به بعد بعد از هر بار اضافه کردن محتوا یک بار مخزن را به روز کنید و بعد از هر build کردن سایت هم یک بار دیگر. ترتیب دستورها چیزی شبیه به این خواهد بود:

mira new -t 'post title' -f blog
ویرایش و تولید محتوا و قرار دادن عکس یا سایر ضمیمه‌ها در شاخه استاتیک
mira build
git add .
git commit -m 'add content'
cd public
git add .
git commit -m 'publish'
cd ..
به روز کردن مخزن گیت‌هاب پروژه
git push origin master gh-pages

از حالا به بعد اگر آدرس مخزنی که روی گیت هاب ساخته بودید چیزی شبیه به این آدرس بود:

github.com/USER/YOUR-SITE-mira.git

محتوای شما در آدرسی شبیه به این آدرس با استفاده از فایل‌های قرار گرفته در دایرکتوری public منتشر خواهد شد:

USER.github.io/YOUR-SITE-mira

و اگر می‌خواهید از نام دامین اختصاصی خودتان برای نمایش محتوا استفاده کنید، فایلی به نام CNAME را در public بسازید و نام دامنه‌ی خودتان را در آن بنویسید

echo YOUR_DOMAIN_NAME.com > CNAME

استفاده از یک اسکریپت:

برای اتومامتیک انجام شدن تمام مراحل بالا، این اسکریپت را دانلود کنید.

اسکریپت gh-pages.pl

حالا یا آن را در دایرکتوری ریشه‌ی میرا کپی کنید، یا در مسیری که در path شما باشد، مثلا دایرکتوری bin در home، و آن را اجرایی کنید chmod +x gh-pages.pl البته اگر آن را در مسیر میرای خودتان کپی کردید بدون اجرایی کردن آن هم مشکلی نخواهید داشت.

این اسکریپت دو عملکرد دارد، init و push، دقیقا مثل توضیحات بالا که همه چیز را خودمان انجام میدادیم، init را فقط کافی است یک بار اجرا کنید و بعد از آن فقط از push استفاده میکنیم.

اگر آن‌را اجرایی نکرده باشید:

~/mira$> perl gh-pages.pl --init

و اگر اجرایی شده باشد:

~/mira$> gh-pages.pl --init

شاخه‌ی gh-pages ساخته شد و دایرکتوری public به عنوان worktree آن معرفی شد.

حالا یک مخزن remote خالی در github می‌سازیم و به پروژه اضافه می‌کنیم:

git remote add origin git@github.com:USER/REPO_NAME.git

آماده سازی تمام شد، از این به بعد با اجرای دستور زیر:

~/mira$> perl gh-pages.pl --push
یا
~/mira$> gh-pages.pl --push

تمام مراحل add و commit و push به طور خودکار برای هر دو شاخه انجام می‌شود، محتویات تمام دایرکتوری‌های میرا به جز public به شاخه master و محتویات public به شاخه‌ی gh-pages اضافه می‌شوند و دستور push برای هر دو شاخه اجرا می‌شود.

یک نکته: اسکریپت فوق یک سوییچ دیگر هم دارد --worktree | -w اگر زمانی خواستید شاخه‌ی دیگری به جز public به عنوان worktree برای شاخه‌ی gh-pages استفاده شود، میتوانید این سوییچ را هم مورد استفاده قرار دهید.

~/mira$> perl gh-pages.pl --init -w public/other
~/mira$> gh-pages.pl --push -w other/path/

اگر مقدار سوییچ worktree با / شروع بشود، اسکریپت اتوماتیک مسیر را در دایرکتوری public در نظر می‌گیرد:

~/mira$> gh-pages.pl --push --worktree='/path/other'
برابر است با
~/mira$> gh-pages.pl --push -w public/path/other

اگر نمی‌خواهید هر سری سوییچ -w را استفاده کنید، اسکریپت را ویرایش کنید و در خط ۱۷ مقدار پیش‌فرض را از public به آدرس مورد نظرتان تغییر دهید:

worktree => 'public'
تغییر دهید به
worktree => 'public/deep/path/'
یا
worktree => 'doc'
worktree => 'another/path'

انتشار در USER.github.io

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

  • در آدرسی که با نام کاربری شما در گیت هاب ساخته شده قابل انتشار هستند: USER.github.io
  • محتوا تنها از شاخه‌ی master در مخزنی با نام USER.github.io برای انتشار استفاده می‌شود.

پس برای استفاده از این راه، تنها کافی است دایرکتوری public را به عنوان شاخه master در مخزن USER.github.io معرفی کنید.

ابتدا در گیت هاب مخزنی را با مشخصات اشاره شده بسازید و بعد در دایرکتوری public این کدها را وارد کنید:

~/mira/public$> git init
~/mira/public$> git add .
~/mira/public$> git commit -m 'publish'
~/mira/public$> git remote add origin git@github.com:USER/USER.github.io.git
~/mira/public$> git push origin master

تکمیل

البته یک ایراد وجود دارد، در این حالت فایل‌های محتویات و تنظیمات و تاریخچه آن‌ها و... را در هیچ مخزنی نداریم. برای حل این مشکل از یک راه حل دیگر استفاده می‌کنیم:

  • دایرکتوری public را کاملا پاک کنید rm -rf public
  • روی گیت هاب مخزنی با نام کاربری خود برای انتشار محتوا بسازید: USER.github.io
  • روی گیت هاب مخزنی با نام سایت خود بسازید، مثلا YOUR-SITE-mira
  • گیت را در دایرکتوری ریشه‌ای که میرا را در آن استفاده می‌کنید، پیکربندی کنید و مخزن YOUR-SITE-mira-content را به عنوان remote به پروژه اضافه کنید.

دستورهایی که باید وارد کنید چیزی شبیه به این‌ها خواهد بود:

~/mira$> git init
~/mira$> git remote add origin git@github.com:USER/YOUR-SITE-mira-content.git
~/mira$> git add .
~/mira$> git commit -m 'start'

در آخر public را به عنوان یک ساب ماژول به این مخزن معرفی میکنیم:

git submodule add -b master git@github.com:USER/USER.github.io.git public

تمام شد، حالا بعد از هر بار mira build، یک بار در شاخه اصلی و یک بار در شاخه public همه چیز را به گیت اضافه کنید و push کنید

~/mira$> cd public
~/mira/public$> git add .
~/mira/public$> git commit -m 'publish'
~/mira/public$> git push origin master
~/mira/public$> cd ..
~/mira$> git add .
~/mira$> git commit -m 'add content'
~/mira$> git push origin master