این یک راهنمای قدم به قدم برای شروع به کار با میراست، در این راهنما، در کنار هم میرا را نصب میکنیم، آن را در یک شاخهی جدید پیکربندی میکنیم، سپس چهار سایت را با مشخصات متفاوت تعریف میکینم، آنها را تنظیم میکنیم و گام به گام شروع به ساختن آنها در کنار هم میکنیم.
میرا برای نصب به پرل نسخه 5.12 به بالا نیاز دارد
برای تست این که پرل را روی سیستم خود از قبل نصب شده دارید یا نه، terminal یا command line را باز کنید و تایپ کنید perl -v
اگر پرل از قبل نصب شده باشد متنی شبیه به این را خواهید دید که ورژن پرل نصب شده را به شما نشان خواهد داد
This is perl 5, version 24, subversion 1 (v5.24.1)
اگر پرل را ندارید از این طریق آنرا نصب کنید:
اگر از ویندوز استفاده میکنید Strawberry Perl یا «پرل توت فرنگی» را ابتدا نصب کنید
توت فرنگی cpan minus را به شکل توکار همراه خود دارد، برای نصب میرا تایپ کنید:
cpanm Mira
اکثر این توزیعها به شکل توکار پرل را در خود دارند، اما اگر نیاز به نصب مجدد یا نصب نسخهی بالاتری که در توزیع شما نصب نیست دارید به این صفحه مراجعه کنید 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
حالا باید مشخص کنیم هر کدام از این سایتها را میخواهیم در چه آدرسی و به چه شکل منتشر کنیم، بدنه اصلی نوشتههایمان را چگونه بنویسیم، آدرس نهایی برای هر پست به چه شکلی باشد و …
برای مشخص کردن خصوصیات عمومی و خصوصی ساختمان و طبقات میرا، باید از فایلهای 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
ابتدا چند فرض عمومی را در نظر میگیریم:
فرض میگیریم تمام این موارد برای هر چهار سایت مقدار یکسانی باید داشته باشند:
میخواهیم مقادیر بالا برای هر چهار سایت یکسان و ثابت باشند، مگر اینکه در هدر هر پست تغییر کنند(مثل قسمت آموزش لینوکس که مطالب ممکن بود نویسنده جدا داشته باشند)
برای قالب انتشار هر چهار سایت را با استفاده از یک قالب منتشر میکنیم، میخواهیم در ادامه قالب خودمان را با نام my-theme بسازیم، فعلاً فقط به مقداردهی اولیه اکتفا میکنیم و فیلد template را مقدار دهی میکنیم. این قالب را در ادامه همراه هم به وجود میآوریم.
در گام پنجم در مورد فیالهای ضمیمه و static کاملتر و با چند مثال صحبت خواهیم کرد.
فایل 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
میخواهیم هر کدام از این چهار سایت را در این آدرسها منتشر کنیم:
برای این منظور باید فیلدهای url و root را مقدار دهی کنیم.
در مورد آدرس نهایی هر پست:
به یاد داشته باشید آدرسها میتوانند به شکل پوشه یا فایل تولید شوند، برای دیدن تفاوت این دو مورد، در پایان گام تنظیمات، تفاوت فیلد permalink در فایلهای تنظیمات وبلاگ فارسی با سایر سایتها را ببینید.
لیستهای آرشیوی مورد نظرمان:
برای اینکار باید فیلد 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
برای اینکه مثالهای کاملتری داشته باشیم، محتوای سایتهایمان را با استفاده از تعدادی از نوشتههای سایتهای زیر تکمیل میکنیم.
توضیح: مثالهایی که در ادامه این بخش میخوانید در این فایل موجود نیستند، بهتر است برای کپی کردن این مثالها در سایت آزمایشیتان، تا آخر این گام صبر کنید و پس از خواندن این بخش و ساختن فایلهای مثال خودتان، محتویات را جایگزین کنید.
اگر به یاد داشته باشید، برای ساختن فایلهای استراکچر در سربرگ هر سایت، فیلدی به نام 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
فایلهای ضمیمه فایلهای ثابتی هستند که در محتوا از آنها استفاده میکنیم اما نیازی به پردازش توسط برنامهی میرا ندارند، مثل عکسها یا فایلهای 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/
در پوشهی محتوای هر سایت در شاخهی 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 }}
میباشد.
در تنظیمات یک فیلد دیگر را به نام 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
میتوانید قالبی را که در ادامه به ساختن آن میپردازیم را از این جا دانلود کنید:
فایل 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
یک سرور برای پیش نمایش اجرا میکینم.
حالا به این آدرس بروید:
فایل 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.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.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 معتبر هستند:
<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 که برای تنظیمات سایتهاست، آن را لود کردهایم و مقدار معتبری بر میگرداند.
البته استفاده از این تگ منطقی نیست و فقط برای مثال و درک بهتر کارکرد فیلدها در تنظیمات به این صورت نوشته شده.
آخرین فایل 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 با توجه به سایز لیستی که لود کرده خواهد داشت.
آیتمهایی که نمایش داده میشوند را با یک کاما بعد از هر کدام از هم جدا کردیم، اما نمیخواستیم که کاما بعد از آخرین آیتم هم نمایش داده شود، پس چک کردیم که اگر در آخر حلقه هستیم دیگر کاما نمایش داده نشود.
بدون این شرط، برچسب زیر
به شکل زیر، بعد از vim یک کامای اضافه نمایش داده خواهد شد:
<tags>vimrc,terminal,vimrc bank,ترمینال,vim,</tags>
و نکتهی آخر، بعضی از خط ها بعد و قبل از استفاده از جفت آکولادها {{ }} از یک خط تیره - استفاده شده {{- -}}، آکولادها قبل و بعد از خود یک کاراکتر خط جدید را هم به نمایش در میآورند. البته برای ساختن قالبهای html چندان اهمیتی ندارند، چرا که در html تا از
یا
حالا وقت آن رسیده که با ساختن یک ساید بار آرشیوهایی که برای هر سایت را داشتیم را هم به نمایش درآوریم، برای این کار قبلا در میانههای قالبهای 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') }} - {{ END }}
{{ IF (archive.key == 'category') }}
<br>
{{ FOREACH utid IN item.posts }}
- <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 }}
- <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 استفاده شده.
زمانی که داشتیم سربرگها را تنظیم میکردیم برای سایت داستان ها یا همان دنباله دار، یک فیلد به نام 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
حالا به این آدرس بروید:
میبینید که همه نوشتهها چپ به راست نوشته شدهاند و اصلا برای نمایش زبان فارسی مناسب نیستند.
همانطور که در تنظیم پیکربندی دیدید، در تنظیم هر سایت یک فیلد به نام 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 میتوان دست به انتشار محتوا زد، راه حل داشتن یک دایرکتوری به نام 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 در مخزن گیت است. آماده سازی آن نسبت به استفاده از شاخهی docs پیچیدهتر است، اما در مقابل مزایای بیشتری هم دارد.
توجه کنید: اگر چندان با گیت آشنا نیستید و دقیقا میخواهید قدم به قدم با مثالهای گیت این راهنما پیش بروید، مخازنی را که در گیتهاب میسازید، کاملا خالی باشند، هنگام ساختن مخزن در گیتهاب، اجازه ساخته شدن فایل 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
برای اتومامتیک انجام شدن تمام مراحل بالا، این اسکریپت را دانلود کنید.
حالا یا آن را در دایرکتوری ریشهی میرا کپی کنید، یا در مسیری که در 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'
در راهنمای صفحات گیت هاب، در کنار ساختن صفحات پروژه، یکی دیگر از راههایی که به آن اشاره شده ساختن صفحات شخصی است. قاعده کلی این صفحات به این صورت است:
پس برای استفاده از این راه، تنها کافی است دایرکتوری 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
البته یک ایراد وجود دارد، در این حالت فایلهای محتویات و تنظیمات و تاریخچه آنها و... را در هیچ مخزنی نداریم. برای حل این مشکل از یک راه حل دیگر استفاده میکنیم:
rm -rf public
دستورهایی که باید وارد کنید چیزی شبیه به اینها خواهد بود:
~/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