اسناد میرا

میرا

آشنایی

معرفی

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

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

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

میرا سه هدف اصلی دارد

  1. سادگی

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

  2. انعطاف

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

  3. کاربردی بودن

چرا استاتیک

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

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

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

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

ویژگی‌ها

ویژگی‌ها

از ویژگی‌های میرا می‌توان این موارد را نام برد:

  • با پرل نوشته شده است.
  • مانند دستورات عمومی خط فرمان در دسترس خواهد بود.
  • تولید محتوا با چندین زبان نشانه گذاری(markup language) امکان پذیر است.
  • برای تولید یک محتوای جدید مثل یک سایت جدید یا صفحه راهنمای یک پروژه نیازی به نصب و پیکربندی مجدد یک شاخه جدید ندارد، در یک شاخه‌ی پیکربندی‌شده می‌توان بی‌نهایت گروه محتوای جدید را مدیریت کرد.
  • پوسته‌ها را با استفاده از tt2 از Template::Toolkit تولید و تفسیر می‌کند.
  • تنظیمات و سربرگ‌ها از فرمت YAML پیروی می‌کنند.

نصب

پرل

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

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

perl -v

اگر پرل از قبل نصب شده باشد متنی شبیه به این را خواهید دید که ورژن پرل نصب شده را به شما نشان خواهد داد

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

اگر پرل را ندارید راهنمای نصب مربوط به سیستم عامل خود را بررسی کنید.

دریافت

برای نصب میرا می‌توان آن را از روی سور کد نصب کرد یا از مخازن cpan استفاده کرد.

اگر بخواهید کدهای آن‌را دانلود کنید و از روی آن‌ها میرا را نصب کنید، می‌توانید از این‌جا آ‌نها را دانلود کنید:

میرا روی گیت‌هاب

سپس این دستور‌ها را وارد کنید:

perl Makefile.PL
make
make test
make install

یا آن‌را از روی مخازن cpan نصب کنید.

cpanm Mira

نصب پرل و میرا

ویندوز

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

cpanm Mira

سیستم‌های شبه یونیکس

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

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

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

sudo cpanm Mira

یا بدون استفاده از cpanm و مستقیم از طریق perl shell میرا را نصب کیند:

$ sudo perl -MCPAN -e shell
> install Mira

استفاده

خط فرمان

دستورهای عمومی

میرا پس از نصب چهار سوییچ متفاوت در اختیار شما قرار می‌دهد

  1. init
  2. new
  3. build
  4. view

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

init با استفاده از init میرا در دایرکتوری جاری پیکربندی می‌شود mira init

new سوییچ new یک محتوا یا نوشته جدید را در طبقه‌ی مورد نظر تولید می‌کند

mira new -t post_title -f blog
mira new -t "post title" -f handbook
mira new --title "post title" --floor projectX

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

mira build
mira build -f blog

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

mira view
mira view -o 127.0.0.25 -p 5000
mira view --host 127.0.0.25 --port 5000

پیکربندی

پیکربندی

پس از ایجاد یک دایکتوری خالی و ورود به آن، با استفاده از دستور mira init میرا در آن دایرکتوری پیکر بندی خواهد شد:

mkdir my_mira
cd my_mira
my_mira$> mira init

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

my_mira/
.
│
├── config
├── config.yml
├── content
├── public
├── statics
├── structure
└── template

فایل config.yml فایل اصلی تنظیمات میرا است که تنظیمات عمومی در آن ذخیره خواهد شد.

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

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

mira new -t "your post title" -f floor_name
    -t or --title: post title
    -f or --floor: floor name

برای تنظیم کردن هرسایت هم‌نام با نام دایرکتوری آن در دایرکتوری config یک فایل با پسوند .yml میتوان داشت که معرف تنظیمات اختصاصی آن سایت است. همچنین هم‌نام با نام دایرکتوری طبقه، بدون هیچ پسوندی، در شاخهstructure اگر فایلی را بسازید، میتوانید هدر اختصاصی برای نوشته‌ها آن سایت یا طبقه به میرا معرفی کنید.

دایرکتوری statics به عنوان دایکتوری نگهداری فایل‌های ثابت عمومی مثل استایل‌شیت پوسته استفاده میشود و به آدرسی که برای فیلد static در فایل config.yml معرفی کنید منتقل خواهد شد

تنظیمات

پیکربندی عمومی و اختصاصی

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

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

فیلدهای قابل تنظیم

title

تیتر یا عنوان سایت

description

توضیح در مورد سایت

author

نام پیش فرض نویسنده یا نویسنده‌ها
در پوسته به عنوان فیلد AUTHOR قابل دسترسی است

email

آدرس ایمیلی که برای ارتباط با نویسنده یا نویسندگان سایت در نظر گرفته شده.

url

آدرس انتشار سایت
url: mysite.com/floor_name

root

شاخه‌ی انتشار سایت
/floor_name

static

محل انتقال محتویات دایرکتوری statics
/my_statics

imageurl

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

publishDIR

نام دایرکتوری که فایل‌های خروجی به آن منتقل می‌شود. پیش فرض: public

post_num

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

archive_post_num

تعداد نوشته‌هایی که در صفحات آرشیو نمایش داده می‌شود، یا یک عدد باید باشد یا گزینه‌ی all

feed_post_num

تعداد نوشته‌هایی که در خوراک یا feed سایت نمایش داده می‌شود، یا یک عدد باید باشد یا گزینه‌ی all

post_sort

میرا نوشته‌ها را به صورت پیش فرض از آخر به اول بر اساس عدد utid هر نوشته مرتب می‌کند. اما میتوان با دادن مقدار reverse به این فیلد ترتیب را معکوس نمود.
post_sort: reverse

feed_output

نام فایل خوراک یا feed سایت پیش فرض feed.xml است اما میتوان خروجی را به مقدار دادن به این فیلد تغییر داد.

feed_template

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

default_floor

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

permalink

مسیری که آدرس هر نوشته بر اساس آن ساخته خواهد شد.

:year
سال انتشار پست
:month
ماه انتشار
:day
روز انتشار
:title
عنوان پست
:FIELD_NAME
نام هر فیلدی که محتوای تک خطی داشته باشد(لیست نباشد) و در هدر فایل پست با مقدار معتبر وجود داشته باشد

/some/thing/else
هرچیزی که بخواهید به آدرس شما اضافه شود

مثال:

/a/:year/abcd/:month/:chapter/wxyz/:day/else/:title
که در اصل هر نوشته در آدرسی شبیه به آدرس زیر منتشر خواهد شد:
mysite.com/a/2017/abcd/02/session_4/wxyz/25/else/post_title_or_index/

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

/:year/:month/:day/:category/:title.html
که در اصل هر نوشته در آدرسی شبیه به آدرس زیر منتشر خواهد شد:
mysite.com/2017/02/25/daily/post_title_or_index.html

default_markup

زبان نشانه‌گذاری که برای نوشته‌های سایتتان در نظر گرفته‌اید.

 - markdown -or- md
 - mmd   (mira markdown parser based on multimarkdown 2.0.b6)
 - bbcode
 - textile
 - text -or- txt   just add \<br> in enlines
 - html

گزینه‌ی mmd در حال تکمیل است اما اگر میخواهید markdown با طعمی شبیه به گیت‌هاب را داشته باشید از این گزینه استفاده کنید.

default_extension

پسوند پیش فرض برای فایل‌هایی که با دستور mira new ایجاد شده‌اند، به شکل پیش‌فرض مقدار .md در میرا مورد استفاده قرار می‌گیرد.

output_extension

پسوند فایل‌های خروجی، مقدار پیش فرض html می‌باشد

template

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

lists

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

lists:
  - categories
  - tags
  - author

هر فیلدی را میتوان در میرا آرشیو کرد و محدودیتی وجود ندارد.

namespace

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

namespace:
  veryverylongarchivename : vlan
  آموزش: learn
  کتاب: book
  درباره: about
  شخصی: personal
  ترمینال: terminal

اگر در tag های خود از آموزش استفاده کنید آدرس آن به این صورت خواهد بود yoursite/FLOOR/tag/آموزش/index.html اما اگر در namespace کلید و مقدار

آموزش: learn

را اضافه کرده باشید این آدرس به این صورت تغییر خواهد کرد yoursite/FLOOR/tag/learn/index.html

plugins

نام پلاگین‌هایی که میخواهید فعال باشند

plugins:
  - Jdate

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

time_zone

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

t_start_tag

شروع کننده‌ی برچسب‌های پوسته، پیش فرض }}

t_end_tag

پایان دهنده‌ی برچسب‌های پوسته، پیش فرض {{

t_outline_tag

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

محتوا

محتوا در میرا

معرفی محتوا در میرا

هر دایرکتوری فرعی در content یک سایت مجزا یا یک طبقه به حساب می‌آید و هر فایل در این طبقات در صورتیکه مقدار utid تکراری نداشته باشد و پسوند .draft نداشته باشد یک نوشته مستقل شمرده می‌شود.

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

/content/blog/_post_image
منتقل میشود به:
mysite.com/blog/post_image

یا

/content/blog/more/deep/_static
منتقل میشود به:
mysite.com/blog/more/deep/static

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

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

برای مثال اگر آدرس هر نوشته سایت برای انتشار در آدرسی مثل این تنظیم شده‌باشد /:year/:title/ و تیتر انتشار نوشته post title باشد، این فایل در هریک از مسیرهای زیر و با هرکدام از این‌نام‌ها باشد:

/blog/2017-01-14-post_title.md
/blog/2017/post_title.abcd
/blog/deep/post_title.md
/blog/deep/more/deep/post_title.extension
/blog/more/deep/my-post.ext

نهایتا این نوشته در این آدرس منتشر خواهد شد:

mysite.com/blog/2017/post-title/

تولید و مدیریت محتوا

ساختن نوشته‌های جدید

برای تولید محتوای جدید از دستور new با فرمت زیر استفاده می‌شود:

mira new -t "YOUR POST TITLE" -f "blog"

یا

mira new --title="YOUR POST TITLE" --floor="blog"

پیامی شبیه به این نمایش داده خواهد شد:

.../content/blog/2017-2-15-YOUR_POST_TITLE.md created

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

در صورتیکه فایلی هم‌نام با نام دایرکتوری طبقه در دایرکتوری structure وجود داشته باشد، سربرگ براساس آن فایل ساخته خواهد شد، در غیر اینصورت از فایل Default در همان دایرکتوری استفاده می‌شود. اگر هیچ‌کدام وجود نداشت، تنها فیلدهای utid-title-date در یربرگ نمایش داده میشود.

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

---
HEDER
FIELDS
---
CONTENT BODY
CONTENT BODY
CONTENT BODY
more...
more...
more...

سربرگ

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

utid

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

کلمه‌ی utid در اصل مخفف unique time ID میباشد، همانطور که از نام فیلد هم میتوان دریافت، این فیلد یک مشخصه یکتا است که براساس زمان تولید شده.

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

همچنین هنگامی که آدرس ایستای یک محتوا تولید میشود در صورتیکه دو محتوا نام یکسانی به خود بگیرند، اولویت دریافت نام با نویسه‌ای است که utid کوچکتری داشته باشد و پست‌های بعدی در آدرس، پیشوند ۲، ۳،... میگیرند برای مثال اگر دو پست با شناسه‌های 20170203040506 و 20171213141516 اما با تیتر یکسان hello داشته باشیم و فرمت تولید نام های خروجی را هم

:year/:title

تعیین کرده باشیم، خروجی چیزی شبیه به این خواهد بود

YOURSITE.com/blog/2017/hello/          > utid 20170203040506
YOURSITE.com/blog/2017/hello/2/        > utid 20171213141516

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

s1-c3/p145(l3)

هنگام پردازش، میرا آن را به این صورت خواهد خواند

131453

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

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

date

تاریخ تولید فایل محتوا

با یکی از این دو فرمت قابل قبول است

YYYY-MM-DD HH:MM:SS
YYYY-MM-DDTHH:MM:SS

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

YYYY-MM-DD 00:00:00

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

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

title

تیتر یا عنوان هر نوشته

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

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

title: 3rd Hel-lo World :)
:year/:month/:title

در نهایت آدرس یکتای این پست این خواهد بود:

mysite.COM/FLOOR/2017/02/3rd-hel-lo-world/

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

_index

جایگزین title برای تولید آدرس نوشته‌ها در فیلد permalink

در صورت مقدار داشتن این فیلد، در permalink که در تنظیمات مشخص کرده‌اید برای ساختن آدرس ثابت آن نوشته به جای :title مقدار این فیلد در نظر گرفته می‌شود.

برای مثال اگر عنوان پست شما چیزی شبیه به این باشد:

یک تیتر خیلی خیلی طولانی در مورد هتل‌های ۵* در سفر به آسیا

آدرس نهایی چیزی شبیه به این خواهد بود

ADDRESS.COM/FLOOR/2017/02/یک-تیتر-خیلی-خیلی-طولانی-در-مورد-هتل‌های-۵-در-سفر-به-آسیا/

حالا اگر به _index مقداری شبیه به این بدهیم:

_index: 5start hotels

آدرس به این صورت تغییر خواهد کرد

ADDRESS.COM/FLOOR/2017/02/5star-hotels/

این فیلد در صورت عدم نیاز میتواند خالی بماند یا حذف شود

توجه: اگر صفحات شما در الگویی که تنها حاوی نام تیتر است تولید می‌شوند:

/:title/

از این نام‌ها برای تیتر یا ایندکس استفاده نکنید

archives
page
نام هر فیلدی که در لیست‌های آرشیو مشخص کرده اید، مثل
categories, tags...

_permalink

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

_type

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

استفاده از این فیلد و فیلدهای layout و permalink برای ساختن صفحات در سایت مفید هست، برای مثال برای ساختن یک صفحه به نام «درباره من» که قرار نباشد در صفحات سایت به صورت سریالی بین سایر نوشته‌ها نمایش داده شود، میتوان از تنظیماتی شبیه به این در هدر استفاده کرد:

title: درباره من
_index: about
_type: page
_layout: customized_about_layout.tt2
_permalink: /:title/

_layout

پوسته اختصاصی برای هر نوتشه

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

_markup

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

فیلدهای انتخابی

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

image: address.com/img/image.jpg
source: other.com/post.html

از این فیلدها در پوسته در زیر مجموعه‌ی حلقه‌ی POSTS با برچسب‌هایی هم نام همین فیلدها میتوانید استفاده کنید

{{ FOREACH post IN POSTS }}
    <a href="{{ pots.url }}#more>{{ pots.title }}</a>
    {{ pots.author }}
    <img src="{{ pots.image }}">
    <a href ="{{ pots.source }}">منبع</a>
    <div class="content">
        {{ pots.body.less}}
    </div>
{{ END }}

لیست‌ها در سربرگ

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

نام فیلد، دونقطه، اینتر، فاصله، خط تیره، فاصله، مقدار

categories:
 - cat1
 - cat2

tags:
 - tag1
 - tag2
 - tag3
 - tag4

تعیین فیلدهای پیش‌فرض

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

my_mira/structure/blog
محتوای این فایل را ویرایش می‌کنیم:
categories:
 -
tags:
 -
image:
author:

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

بدنه اصلی هر پست

بدنه قسمت اصلی محتواست، برای نوشتن بدنه می‌توان از Mrkup Language هایی که میرا پشتیبانی میکند، کدهای html یا متن‌های خالص استفاده کرد.

بدنه هنگام پردازش به دو قسمت less و more تقسیم میشود، less خلاصه یا توضیحی از متنی است که مینویسید و more شامل تمام متن نوشته شده می‌شود

به شکل پیش فرض میرا ۶۰۰ حرف ابتدایی هر متن را بعد از حذف کردن تمام کدهای HTML که ممکن است در آن نوشته شده باشد و نادیده گرفتن تمام قواعد MarkUP، به عنوان less مشخص می‌کند، اما می‌توان مقدار less را در خود نوشته مشخص کرد، برای این‌کار میتوان در پایان هر پاراگراف از بدنه که به عنوان خلاصه یا پیش‌نمایش نوشته در نظر گرفته شده از این برچسب استفاده کرد:

<!-- more -->

تعداد فاصله ها مهم نیستند، میتواند اینطور نوشته شود

<!--        more               -->

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

خلاصه‌ای از متن
یا همان
less
در این قسمت نوشته شده

<!--     more     -->

ادامه متن
را در این قسمت
مینویسیم
کل متن قبل و بعد از نشانه گذار
به عنوان
more
شناخته خواهد شد



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

{{ post.body.less }}
{{ post.body.more }}

فایل‌های ضمیمه

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

برای مثال این دایرکتوری‌ها:

/my_mira/content/blog/_images
/my_mira/content/project_x/deep/_dir
/my_mira/content/floor_name/more/depp/_attach

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

mysite.com/blog/images/
mysite.com/project_x/deep/dir/
mysite.com/floor_name/more/depp/attach/

پوسته

پوسته

معرفی اجزای تشکیل دهنده پوسته

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

اجزای اصلی تشکیل دهنده هر پوسته، این پنج فایل هستند

/template/THEME/
.
├── archive.tt2
├── atom.tt2
├── index.tt2
├── main.tt2
└── post.tt2

همچنین دایرکتوری به نام include هم در شاخه‌ی پوسته، هنگام پردازش نهایی دیده میشود و اگر بخواهید ماژول‌هایی مانند header یا sidebar در نظر داشته باشید میتوانید در این شاخه آن‌ها را ذخیره کنید. به جز include از هر تعداد دایرکتوری دیگر نیز میتوان استفاده کرد، تنها تفاوت این است که در صورت استفاده از include نیازی به نام بردن از آن برای لود کردن ندارد، اما سایر دایرکتوری‌ها برای لود شدن نیاز به ذکر نام در پوسته را دارند.

/template/THEME/
.
├── archive.tt2
├── atom.tt2
├── include
│   ├── footer
│   ├── header
│   ├── navbar
│   ├── sidebar
│   ├── some
│   ├── thing
│   └── else
├── partial
│   ├── date
│   ├── post
│   │   ├── title.part
│   │   ├── body
│   │   └── meta
│   ├── image
│   └── other
├── index.tt2
├── main.tt2
└── post.tt2

در حالت پیش‌فرض بالا برای نمایش اجزا باید به اینصورت عمل کرد

{{ INCLUDE footer }}
{{ INCLUDE prtial/date }}
{{ INCLUDE prtial/post/title.part }}

همانطور که دیدید برای لود کردن footer به خاطر قرار گرفتن در دایرکتوری include نیازی به نام بردن از دایرکتوری نبود، اما date و title.part با ذکر آدرس لود شده‌اند.

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

اما این پنج فایل چه هستند و چه میکنند؟

فایل‌های پایه‌ی هر پوسته

main

الگویی است که صفحه‌ی مشترک بین تمام طبقات براساس آن ساخته میشود، یا همان صفحه اصلی که زمان باز کردن سایت در شاخه‌ی پیش فرض دیده میشود. اگر در فایل config.yml مقدار url را برابر SITE.com قرارداده باشید و root را مساوی / تنظیم کنید، main در این صفحه تشکیل میشود:

SITE.com/index.html

index

الگوی سازنده‌ی صفحات اول هر طبقه و صفحات ادامه‌ی صفحه‌ی اصلی، در root هر طبقه ساخته خواهد شد
اگر root در فایل config/blog.yml مساوی با /blog تنظیم شده باشد، index.tt2 الگوی سازنده‌ی این صفحات است

Site.com/blog/
Site.com/blog/page/2/
Site.com/blog/page/3/
Site.com/blog/page/...

archive

الگوی عمومی برای ساختن صفحات آرشیو

آرشیو زمانی و هر نوع آرشیو دیگری که در فیلد lists در فایل تنظیمات مشخص کرده باشید بر اساس این فایل ساخته می‌شوند. برای مثال اگر در سربرگ نوشته‌هایتان فیلد date موجود باشد و در فایل تنظیمات این آرشیو‌ها را مشخص کرده باشید

lists:
 - categories
 - tags
 - author

این الگو این صفحات را خواهد ساخت

Site.com/blog/archive/2017
Site.com/blog/archive/2017/01/
Site.com/blog/archive/2017/02/
Site.com/blog/archive/...

Site.com/blog/author/kiavash/
Site.com/blog/author/...

Site.com/blog/categories/CAT1/
Site.com/blog/categories/CAT2/
Site.com/blog/categories/CAT3/
Site.com/blog/categories/....

Site.com/blog/tagss/TAG1/
Site.com/blog/tagss/TAG2/
Site.com/blog/tagss/TAG3/
Site.com/blog/tagss/...

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

template/THEME/categories.tt2

از این به بعد آرشیو موضوعی categories به جای archive.tt2 از الگویی که در categories.tt2 تنظیم کرده‌اید برای ساختن خروجی استفاده خواهد کرد.

post

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

_index: 5start hotels
_permalink: :year/:title

خروجی آن در این آدرس تولید میشود

/blog/2017/5star-hotels/

تمام آدرس‌های ثابت محتوای تولید شده از الگویی که در فایل post.tt2 تعریف کرده‌اید برای ساخت استفاده میکنند

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

_layout: custom_page.tt2
یا
_layout: other_custom_page

اگر در شاخه‌ی پوسته فایل custom.tt2 یا other_custom_page موجود باشد، به جای post.tt2 از آن استفاده خواهد شد.

atom

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

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

الگوها

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

هر یک از این برچسب ها برای لود شدن باید بین دوآکولاد باز و بسته شوند، (الگوی آکولاد در تنظیمات قابل تغییر است).

{{ ROOT }}
{{ TITLE }}
{{ SomeThingElse }}
...

مقادیر معتبر این برچسب‌ها در پوسته‌های مختلف تفاوت‌های کوچکی با هم دارند

main.tt2

برچسب‌های معتبر در این پوسته و مقادیرشان.

{{ MainTITLE }}
{{ MainDESCRIPTION }}
{{ MainURL }}
{{ MainROOT }}
{{ MainSTATIC }}
{{ MainIMAGEURL }}
{{ MainAUTHOR }}
{{ MainEMAIL }}
{{ PageTitle }}
   main title
{{ IS_MAIN }} : boolean (true)

{{ FLOORS }}

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

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

این حلقه تنها به اندازه‌ی مقداری که در فیلد post_num در فایل config.yml مشخص کرده‌اید از محتوای هر طبقه را در خود ذخیره می‌کند. نحوه‌ استفاده:

{{ FOREACH site IN FLOORS.values }}
  {{ site.name }}
  {{ site.description }}

  {{ FOREACH post IN site.posts }}
    <h2><a href="{{ post.url }}">{{ post.title }}</a><h2>
    <h4>{{ post.CALENDAR.day }}-{{ post.CALENDAR.month_name }}-{{ post.CALENDAR.year }}</h4>
    <p>{{ post.body.less }}</p>
  {{ END }}

  {{ IF site.SITE.language == 'farsi' }}
    <a href="{{ site.url }}">ورود به صفحه اصلی</a>
  {{ ELSE }}
    <a href="{{ site.url }}">Main page</a>
  {{ END }}

{{ END }}

و برچسب UTIDS

{{ UTIDS }}

کلید نام تمام محتوای موجود در سایت مرتب شده بر اساس مقدار utid هر پست، برابر با utid هر پست، در UTIDS ذخیره شده، برای لود کردن محتوا در برچسب ENTRIES قابل استفاده است.

تمام محتوای تولید شده، نمایش داده خواهند شد، تمام محتوا، اگر در میرا پنج سایت(طبقه) ساخته باشید و در هرکدام ۱۰۰ پست باشد، این کد تمام ۵۰۰ نوشته‌ی شما را به ترتیب مقدار عددی utid نمایش خواهد داد.
برای محدود کردن نمایش تعداد پست‌ها میتوان از کدهای کنترل کننده حلقه استفاده کرد، مثال:

{{ FOREACH id IN UTIDS }}
   do any thing
   {{ ENTRIES.$id.title }}
   {{ LAST IF loop.count == 10 }}
{{ END }}
بعد از ۱۰ بار تکرار حلقه تمام خواهد شد.

index.tt2

به جز برچسب UTIDS تمام برچسب‌های main.tt2 در index و atom feed با همان مقادیر معتبر هستند

{{ MianTITLE }}
{{ MianDESCRIPTION }}
{{ MianURL }}
{{ MianROOT }}
{{ MianSTATIC }}
{{ MainIMAGEURL }}
{{ MianAUTHOR }}
{{ MianEMAIL }}

{{ PageTITLE }}
   site title

{{ TITLE }}
{{ DESCRIPTION }}
{{ URL }}
{{ ROOT }}
{{ STATIC }}
{{ IMAGEURL }}
{{ AUTHOR }}
{{ EMAIL }}

{{ ARCHIVES }} :
برای اطلاعات کامل‌تر در مورد آرشیو ها قسمت اول بخش پوسته ها را ببینید، این برچسب مناسب برای نمایش در سایدبار و امثال آن است. برای ساختن صفحات آرشیو، archive.tt2 جهت نمایش محتوا، از POSTS استفاده می‌شود، کارکرد این برچسب با صفحات archive متفاوت است.

{{ ENTRIES }}
{{ FLOORS }}
{{ POSTS }}
{{ IS_INDEX }} :(boolean) true

{{ MAIN }}
{{ SITE }}
{{ BUILD }}
{{ PAGE }}

feed

به شکل پیش‌فرض از پوسته atom.tt2 برای ساخته شدن خوراک سایت استفاده می‌شود، اما می‌توانید نام این پوسته را در تنظیمات تغییر دهید.

به جز برچسب UTIDS تمام برچسب‌های main.tt2 در index و feed با همان مقادیر معتبر هستند

{{ MianTITLE }}
{{ MianDESCRIPTION }}
{{ MianURL }}
{{ MianROOT }}
{{ MianSTATIC }}
{{ MainIMAGEURL }}
{{ MianAUTHOR }}
{{ MianEMAIL }}

{{ PageTITLE }}
   site title

{{ TITLE }}
{{ DESCRIPTION }}
{{ URL }}
{{ ROOT }}
{{ STATIC }}
{{ IMAGEURL }}
{{ AUTHOR }}
{{ EMAIL }}

{{ ARCHIVES }}

{{ ENTRIES }}
{{ FLOORS }}
{{ POSTS }}
{{ IS_FEED }} :(boolean) true

{{ MAIN }}
{{ SITE }}
{{ BUILD }}

archive.tt2

به جز برچسب UTIDS تمام برچسب‌های main.tt2 و index.tt2 در archive با همان مقادیر معتبر هستند

{{ MainTITLE }}
{{ MainDESCRIPTION }}
{{ MainURL }}
{{ MainROOT }}
{{ MainSTATIC }}
{{ MainIMAGEURL }}
{{ MainAUTHOR }}
{{ MainEMAIL }}

{{ PageTITLE }}
   title - YYYY/MM     :if dae archive
   title - field name  :if field archive

{{ TITLE }}
{{ DESCRIPTION }}
{{ URL }}
{{ ROOT }}
{{ STATIC }}
{{ IMAGEURL }}
{{ AUTHOR }}
{{ EMAIL }}

{{ ArchiveTITLE }} :
   YYYY/MM    :if dae archive
   field name :if field archive

{{ ENTRIES }}
{{ FLOORS }}
{{ POSTS }}

{{ MAIN }}
{{ SITE }}
{{ BUILD }}
{{ PAGE }}

{{ IS_ARCHIVE }}      :(boolean) true for field archives
{{ IS_DATE_ARCHIVE }} :(boolean) true for date archives

{{ ARCH }} : مشخصات آرشیوی که در حال ساخته شدن است
برای آرشیو زمانی:
   {{ ARCH.name }}       : october 2014   -    اردیبهشت 95
   {{ ARCH.year }}
   {{ ARCH.month }}
   {{ ARCH.month_name }}
   {{ ARCH.number }}     : year - month     2014 - 07         1395 - 11
   {{ ARCH.url }}        : float url      /site/archive/
   {{ ARCH.furl }}       : full url        http://example.org/site/archive/
برای آرشیو ساخته شده از فیلدهای پست:
   {{ ARCH.name }}
   {{ ARCH.showname }} : namespace
   {{ ARCH.url }}
   {{ ARCH.furl }}

post.tt2

{{ MianTITLE }}
{{ MianDESCRIPTION }}
{{ MianURL }}
{{ MianROOT }}
{{ MianSTATIC }}
{{ MainIMAGEURL }}
{{ MianAUTHOR }}
{{ MianEMAIL }}

{{ PageTITLE }}
   "post title - site title"

{{ PostTITLE }}
   "post title"

{{ TITLE }}
{{ DESCRIPTION }}
{{ URL }}
{{ ROOT }}
{{ STATIC }}
{{ IMAGEURL }}
{{ AUTHOR }}
{{ EMAIL }}

{{ ARCHIVES }} :
برای اطلاعات کامل‌تر در مورد آرشیو ها قسمت اول بخش پوسته ها را ببینید، این برچسب مناسب برای نمایش در سایدبار و امثال آن است. برای ساختن صفحات آرشیو، archive.tt2 جهت نمایش محتوا، از POSTS استفاده می‌شود، کارکرد این برچسب با صفحات archive متفاوت است.

{{ ENTRIES }}
{{ FLOORS }}
{{ POSTS }}

{{ IS_POST }} :(boolean) true

if _type: page then:
{{ IS_POST }} :(boolean) false
{{ IS_PAGE }} :(boolean) true

{{ MAIN }}
{{ SITE }}
{{ BUILD }}
{{ PAGE }}

{{ post.* }}

در الگوی post.tt2 یا الگوی شخصی سازی شده صفحه‌ها نیازی به فراخوانی حلقه‌ی FOREACH POSTS نیست، تمام مقادیر مورد نیاز در {{ post }} از پیش لود شده است. اما در صورت نیاز میتوانید این حلقه را هم لود کنید. مقادیر زیر در این الگو برابر هستند:

1: با لود کردن حلقه
<div class="content">
{{ FOREACH entry IN POSTS }}
  <div class="title">{{ entry.title }}</div>
  {{ entry.body.more }}
{{ END }}
</div>

2: بدون لود کردن حلقه
<div class="content">
  <div class="title">{{ post.title }}</div>
  {{ post.body.more }}
</div>

متغیرهای موجود

MainTITLE

تیتر اصلی سایت ذخیره شده در فایل تنظیمات مرکزی یا همان config.yml نحوه‌ استفاده:

{{ MainTITLE }}

MainDESCRIPTION

توضیحات اصلی سایت ذخیره شده در فایل تنظیمات مرکزی یا همان config.yml نحوه‌ استفاده:

{{ MainDESCRIPTION }}

MainURL

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

{{ MainURL }}

MainROOT

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

{{ MainROOT }}

MainSTATIC

شاخه فایل‌های ثابت سایت ذخیره شده در فایل تنظیمات مرکزی مقدار بازگشتی برای مثال: /statics نحوه‌ استفاده:

{{ MainSTATIC }}

MainIMAGEURL

شاخه فایل‌های ثابت سایت ذخیره شده در فایل تنظیمات مرکزی مقدار بازگشتی برای مثال: /statics/images نحوه‌ استفاده:

{{ MainIMAGEURL }}

MainAUTHOR

نام نویسنده ذخیره شده در فایل تنظیمات مرکزی نحوه‌ استفاده:

{{ MainAUTHOR }}

MainEMAIL

ایمیل نویسنده نحوه‌ استفاده:

{{ MainEMAIL }}

PageTITLE

تیتر صفحه، در صورتیکه از ماژولی شبیه به header برای لود کردن قسمت بالایی صفحات html به شکل ثابت در تمام صفحات استفاده کنید این برچسب کمک بسیاری برای تگ <title> خواهد کرد، برای مثال در main.tt2 مقداری برابر TITLE و در index.tt2 مساوی FloorTITLE خواهد داشت نحوه‌ استفاده:

{{ PageTitle }}

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

main:
تیتر ذخیره شده در فیلد title در فایل config.yml

index , feed:
تیتر ذخیره شده در فیلد title در فایل پیکربندی اختصاصی در دایرکتوری config

field archive:
تیتر اختصاصی سایت - نام فیلد آرشیو شده

date archive:
تیتر اختصاصی سایت - سال / ماه

post:
تیتر نوشته - تیتر طبقه انتشار ذخیره شده دایرکتوری config
"post_title-site_title"

PostTITLE

تنها در الگوی post معتبر است و تیتر نوشته‌ی در حال نمایش را برمیگرداند.

FLOORS

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

مقادیر موجود در این برچسب:

name
description

posts (list)

فیلد posts شامل تعداد مشخص از آخرین ارسال‌های شماست، تعداد ارسال‌های موجود در این کلید از config.yml و فیلد post_num برداشت میشود.
تمام مقادیری که برای POSTS که در قسمت‌های بعد توضیح داده میشود در مورد لیست posts در Floors نیز قابل استفاده است

نحوه‌ استفاده:

{{ FOREACH site IN FLOORS.values }}
  {{ site.name }}
  {{ site.description }}

  {{ FOREACH post IN site.posts }}
    <h2><a href="{{ post.url }}">{{ post.title }}</a><h2>
    <h4>{{ post.CALENDAR.day }}-{{ post.CALENDAR.month_name }}-{{ post.CALENDAR.year }}</h4>
    <p>{{ post.body.less }}</p>
  {{ END }}

{{ END }}

ENTRIES

کلید-مقداری از تمام محتوای تولید شده در سایت، کل نوشته‌ها و صفحات، برای نمایش پست‌ها نیاز به مقدار utid آن دارید، در مورد کارکرد این برچسب، توضیحات UTIDS را بخوانید

UTIDS

کلید نام تمام محتوای موجود در سایت مرتب شده بر اساس مقدار utid هر پست، برابر با utid هر پست، برای لود کردن محتوا در برچسب Entries قابل استفاده است.

این برچسب تنها مختص به main.tt2 میباشد

تمام مقادیر معتبر برای POSTS در زیر این برچسب با اضافه کردن ENTRIES.$id نیز قابل استفاده هستند نحوه‌ی استفاده به همراه ENTRIES

{{ FOREACH id IN UTIDS }}
   <h2><a href="{{ ENTRIES.$id.url }}">{{ ENTRIES.$id.title }}</a><h2>
   <h4>{{ ENTRIES.$id.CALENDAR.day }}-{{ ENTRIES.$id.CALENDAR.month_name }}-{{ ENTRIES.$id.CALENDAR.year }}</h4>
   <p>{{ ENTRIES.$id.body.less }}</p>
{{ END }}



TITLE

تیتر اصلی طبقه، ذخیره شده در فایل تنظیمات طبقه
نحوه‌ استفاده:

{{ TITLE }}

DESCRIPTION

توضیحات طبقه، ذخیره شده در فایل تنظیمات طبقه
نحوه‌ استفاده:

{{ DESCRIPTION }}

URL

آدرس سایتی که طبقه در آن منتشر میشود، ذخیره شده در فیلد url فایل تنظیمات طبقه.

نحوه‌ استفاده:

{{ URL }}

ROOT

آدرس شاخه‌ی ریشه، ذخیره شده در فایل تنظیمات طبقه
نحوه‌ استفاده:

{{ ROOT }}

AUTHOR

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

{{ AUTHOR }}

EMAIL

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

{{ EMAIL }}

BUILD

اطلاعات زمان ساختن آخرین نسخه از سایت، یا تاریخ زمانی که mira build را اجرا میکنید.

{{ BUILD.date }} : 2017-03-25 18:44:03
{{ BUILD.year }}
{{ BUILD.month }}
{{ BUILD.month_name }}
{{ BUILD.month_abbr }}
{{ BUILD.day }}
{{ BUILD.day_name }}
{{ BUILD.day_abbr }}
{{ BUILD.hour }}
{{ BUILD.minute }}
{{ BUILD.second }}

PAGE

در الگوهای index, archive مقادیری حاوی آدرس و شماره صفحه‌ی بعد، شماره‌ی صفحه‌ای که در آن هستیم و تعداد کل صفحات را برمیگرداند.

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

معتبر در تمام الگوها:

{{ Page.next.url }}
{{ Page.next.title }}
{{ Page.prev.url }}
{{ Page.prev.title }}

معتبر در الگوهای archive و index:

{{ PAGE.number }}
{{ PAGE.total }}

ARCHIVES

تمام آرشیوهای موجود در طبقه یا همان سایت

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

مقدار این برچسب چیزی شبیه به این است:

'categories' => {
          "CAT1" => {
                'name' => "CAT1",
                    'url' => "/FLOOR/categories/CAT1namespace/",
                    'posts' => [
                               '20170210173327',
                               '20170210173313',
                               '20170210174503',
                               '20170210172431',
                               '20170210173319'
                             ]
              },
          "CAT2" => {
                'name' => "CAT2",
                    'url' => "/FLOOR/categories/CAT2namespace/",
                    'posts' => [
                               '20170210173327',
                               '20170210173313',
                               '20170210174503',
                               '20170210172431',
                               '20170210173319'
                             ]
             }
},
'date' => {
      '201702' => {
              'year' => '2017',
              'month' => '02',
              'url' => '/fa/archive/2017/02/',
              'name' => 'February 2017',
              'number' => '2017 - 02',
              'posts' => [
                         '20170210173327',
                         '20170210173313',
                         '20170210174503',
                         '20170210172431',
                         '20170210173319'
                       ]
              }
}

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

نحوه استفاده:

{{ FOREACH archive IN ARCHIVES.pairs }}
  {{ archive.key }} نام آرشیو
  <hr>
  {{ FOREACH item IN archive.value.values }}
    <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 (archive.key == 'tags') }}&nbsp;-&nbsp;{{ END }}
  {{- END }}
  <br>
{{- END }}

سایر برچسب‌ها برای آرشیو

میرا برای هر آرشیو، همنام با همان آرشیو، مقداری برای پوسته تولید میکند، برای مثال اگر در فایل تنظیمات برای آرشیو ها فیلد categories را به عنوان آٰشیو مشخص کرده باشید، حلقه‌ای به نام CATEGORIES_ARCHIVE نیز در پوسته قابل استفاده خواهد بود، یا برای tags، میتوانید از TAGS_ARCHIVE استفاده کنید.

اطلاعات موجود در هرکدام از این مقادیر، شبیه به این خواهند بود

CATEGORIES_ARCHIVE = [
          {
            'name' => "CAT1",
            'url' => "/FLOOR/categories/CAT1namespace/",
            'posts' => [
                         '20170210172431',
                         '20170210174503',
                         '20170210173327',
                         '20170210173313',
                         '20170210173319'
                       ]
          },
          {
            'name' => "CAT2",
            'url' => "/FLOOR/categories/CAT2namespace/",
            'posts' => [
                         '20170210172431',
                         '20170210174503',
                         '20170210173327',
                         '20170210173313',
                         '20170210173319'
                       ]
          },
        ]

برای استفاده از این برچسب‌ها باید در حلقه‌ای که با FOREACH تولید میکنید از آن‌ها استفاده کنید

نحوه استفاده برای فیلد فرضی categories

{{ FOREACH CATEGORIES_ARCHIVE }}
  <a href="{{ url }}">{{ name }}</a> - <small>{{ posts.size }}</small><br>
{{ END }}

یا

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

همانطور که مشخص است در posts، تمام utid ها برگشت داده شده، پس برای نمایش تک تک فایل‌های موجود در هر دسته میتوان از ENTRIES کمک گرفت

{{ FOREACH cat IN CATEGORIES_ARCHIVE.values }}
  <a href="{{ cat.url }}">{{ cat.name }}</a> - <small>{{ cat.posts.size }}</small><br>
  {{ FOREACH id IN cat.posts.sort }}
    <h5><a href="{{ ENTRIES.$id.url }}">{{ ENTRIES.$id.title }}</a></h5>
  {{ END }}
{{ END }}

مثلما به جای id و $id از هر نام دیگری که بخواهید میتوانید استفاده کنید.

نمایش نوشته‌ها با حلقه‌ی POSTS

جهت نمایش نوشته‌ها از حلقه‌ای که اجزای POSTS را لود میکند میتوان استفاده کرد

{{ FOREACH entry IN POSTS }}
    ...
{{ END }}

از این حلقه در صفحات index و archive میتوان استفاده کرد، همچنین در صفحه‌ی هر پست در پوسته post.tt2 نیز استفاده از این حلقه به شکل اختیاری معتبر است. در post.tt2 اگر این حلقه لود نشود هم تمام مقادیر با استفاده از کلید post معتبر هستند.

{{ FOREACH post IN posts }}
   {{ post.title }} تیتر
   {{ post.url }} آدرس شناور
   {{ post.furl }} آدرس مطلق
   {{ post.body.less }} خلاصه متن
   {{ post.body.more }} متن کامل
   {{ post.date }} تاریخ کامل انتشار
   {{ post.CALENDAR.year }} سال انتشار
   {{ post.CALENDAR.month }} ماه انتشار به شکل عددی
   {{ post.CALENDAR.month_name }} نام ماه
   {{ post.CALENDAR.month_abbr }} خلاصه نام ماه
   {{ post.CALENDAR.day }} روز انتشار به شکل عددی
   {{ post.CALENDAR.day_name }} نام روز
   {{ post.CALENDAR.day_abbr }} خلاصه نام روز
   اگر از پلاگین jdate هم استفاده کرده باشید
   {{ post.jdate }}
   {{ post.CALENDAR.jyear }} سال انتشار
   {{ post.CALENDAR.jmonth }} ماه انتشار به شکل عددی
   {{ post.CALENDAR.jmonth_name }} نام ماه
   {{ post.CALENDAR.jday }} روز انتشار به شکل عددی
   {{ post.CALENDAR.jday_name }} نام روز
   سایر فیلدها
   {{ post.other }}
   {{ post.another }}
   در صورتیکه فیلدهایی را به صورت لیستی نوشته باشید، مثلا نام منابع در صورتیکه نوشته بیش از یک منبع داشته باشد:
   {{ FOREACH source in post.sources }}
      {{ source }}
   {{ END }}
   اگر فیلدی را آرشیو کرده باشید، چه آن فیلد لیست باشد چه نباشد باید در حلقه لود شود
   {{ FOREACH cat in post.categories }}
    {{ cat.url }} آدرس شناور
    {{ cat.furl }} آدرس مطلق
    {{ cat.name }} نام آرشیو
    {{ cat.showname }} namespace
   {{ END }}

نمایش فیلدهای استفاده شده در config عمومی و اختصاصی

تمام مقادیری که در config ذخیره شده‌اند در پوسته قابل استفاده هستند. مقادیر موجود در config.yml با استفاده از برچسب {{ MAIN }} در تمام قسمت‌ها قابل دسترسی است و فایل‌های پیکربندی ذخیره شده در دایرکتوری config هنگام ساخته شدن صفحات هر طبقه با برچسب {{ SITE }} در دسترس هستند. تمام برچسب‌هایی که به شکل پیش فرض در میرا هستند و از مقادیر config استفاده میکنند با استفاده از این برچسب نیز قابل مشاهده هستند، مانند {{ MainTITLE }} که برابر {{ MAIN.title }} است یا {{ TITLE }} که با {{ SITE.title }} نیز قابل دسترسی است.

{{ MAIN.title }}
{{ MAIN.other }}
{{ SITE.author }}
{{ SITE.language }}

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

/config/blog.yml:

faves:
 - icecream
 - football
 - cinema

این لیست در پوسته به این صورت قابل دسترسی است:

{{ FOREACH fave IN SITE.faves }}
   {{ fave }}
{{ END }}

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

social:
 - name: twitter
   link: https://twitter.com/NAME
   desc: Follow me on

 - name: github
   link: https://github.com/NAME
   desc: Fork me on

 - name: instagram
   url: https://instagram.com/NAME
   desc: Follow me on

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

{{ FOREACH social IN MAIN.social }}
   {{ social.desc }} <a href={{ social.link }}>{{ social.name }}</a>
{{ END }}

قالب

دستور زبان

برچسب‌های ابتدا و انتها

در tt2 هر دستور بین یک برچسب شروع کننده و پایان دهنده قرار میگیرد، این برچسب‌ها در میرا به شکل پیش فرض آکولاد هستند، اما بر حسب نیاز یا علاقه می‌توان آن‌ها را در config تغییر داد. {{}}

برچسب‌های outline

همچنین می‌توان این دستورها را با استفاده از برچسب‌های outline نیز نوشت، outline tag ها به شکل پیش فرض %% هستند

مثلا به جای

{{ IF some.list.size -}}
  <ul>
  {{ FOREACH item IN some.list -}}
    <li>{{ item.html }}</li>
  {{ END -}}
  </ul>
{{ END -}}

می‌توان نوشت:

%% IF some.list.size
  <ul>
%%   FOREACH item IN some.list
    <li>{{ item.html }}</li>
%%   END
  </ul>
%% END

تنها دقت داشته باشید برچسب‌های outline حتما باید در ابتدای خط باشند و از ساختن فرورفتگی برای آن‌ها خودداری کنید.

کامنت‌ها

برای کامنت گذاشتن می توان از # در کنار برچسب ابتدایی استفاده کرد:

{{# this entire directive is ignored no
matter how many lines it wraps onto
}}

حذف کردن یا افزودن خطوط سفید

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

{{ FOREACH tag IN TAGS_ARCHIVE }}
   {{- tag.name -}},
{{ END }}

tag1,tag2,tag3,tag4, ...

{{ FOREACH tag IN TAGS_ARCHIVE }}
   {{- tag.name +}},
{{ END }}

tag1
,tag2
,tag3
,...

مدیریت کردن خطوط سفید برای ساختن خروجی‌های html‌ چندان مهم نیست چراکه مرورگرها خطوط جدید را تنها با تفسیر دستوراتی مثل br یا p یا سایر برچسب‌های شناخته شده به وجود می‌آورند، اما برای ساختن feed یا تغییر خروجی از Html به pdf, odf یا امثالهم بسیار مفید می‌باشند.

دستور زبان مستقیم و بلوکی

دستور زبان tt2 را میتوان به دو مجموعه‌ی دستوهای تک خطی یا مستقیم و دستورهای بلوکی تقسیم کرد

دستورهای تک خطی مثل {{ TITLE }} تنها با نوشتن برچسب‌هایشان اجرا یا جایگزین می‌شوند. از دیگر دستورهای مستقیم میتوان به include, prccess, get, set, last, next و ... اشاره کرد.

دستورهای بلوکی مثل حلقه‌ها یا شرط ها دستوراتی هستند که در پایان خود نیاز به یک برچسب پایان دهنده‌ی END هم دارند.

{{ FOREACH ... }}
   ...
{{ END }}

ذخیره کردن خروجی بلوک‌ها در متغیرها

خروجی هر بلوک را میتوان به جای نمایش مستقیم در متغیرهای جدید ذخیره کرد، برای مثال ذخیره کردن یک متن چند خطی

{{ poem = BLOCK }}
   The boy stood on the burning deck,
   His fleece was white as snow.
   A rolling stone gathers no moss,
   And Keith is sure to follow.
{{ END }}

یا مقدار دادن به متغیر var با استفاده از شرط‌ها در سه حالت زیر با هم برابر است:

(فاصله‌ها و خطوط جدید برای وضوح کدها اضافه شدند)

{{ SET var = 'value' IF some_condition }}

{{ var = IF some_condition }}
   value
{{ END }}

{{ IF some_condition }}
   {{ var = 'value' }}
{{ END }}

فیلترها

فیلترها از دوراه قابل دسترسی هستند: با استفاده از برچسب مستقیم FILTER یا با استفاده از کاراکتر خط عمود | در سایر دستورات

{{ FILTER html }}
   HTML text may have < and > characters embedded
   which you want converted to the correct HTML entities.
{{ END }}   
خروجی:
HTML text may have &lt; and &gt; characters embedded
which you want converted to the correct HTML entities.

یا

{{ FILTER repeat(3) }}blah {{ END }}
خروجی:
blah blah blah

یا با استفاده از لوله‌ها یا همان خطوط عمودی |

{{ post.body.more | html }}

همچنین می‌توان فیلترها را به صورتی گروهی نیز مورد استفاده قرار داد

{{ post.body.more | ucfirst | html | truncate(75, 'More...') }}

بلوک‌های مستقیم

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

{{ IF title }}
   {{ INCLUDE header }}
{{ ELSE }}
   {{ INCLUDE other/header  title="Some Other Title" }}
{{ END }}

این بلوک را می‌توان به این شکل نیز نوشت:

{{ IF title;
     INCLUDE header;
   ELSE;
     INCLUDE other/header  title="Some Other Title";
END }}

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

متغیرها

اسکالرها

به متغیرهای اسکالر با استفاده ساده از نامشان میتوان همواره دسترسی داشت.

{{ foo = 10 }}
{{ bar = 'ten' }}

foo is {{ foo }}   # foo is 10
bar is {{ bar }}   # bar is ten

foo is $bar        # foo is ten
foo is ${bar}      # foo is ten

لیست‌ها

لیست‌ها مجموعه ای از متغیرها هستند که در یک لیست ذخیره شده‌اند. برای مقدار دادن به لیست‌ها از []\ یا مقدار دادن مستقیم به اندیس‌های عددی استفاده میشود. برای دستیابی به مقادیر ذخیره شده در هر لیست از اندیس عددی آن می‌توان استفاده کرد.

{{ colors = ['red', 'blue', 'green'] }}
یا
{{ colors.0 = 'red' }}
{{ colors.1 = 'blue' }}
{{ colors.2 = 'green' }}

first color is : {{ colors.0 }}   # first color is red
first color is : ${colors.0}      # first color is red

{{ FOREACH color IN colors }}
   color name is: {{ color }}
{{ END }}
خروجی:
color name is red
color name is blue
color name is green

یا به شکل مستقیم داخل حلقه
{{ FOREACH c IN ['red', 'blue', 'green'] }}
   {{ c }}
{{ END }}

یا

{{ n = [ 1 .. 4 ] }}    # n is [ 1, 2, 3, 4 ] 

{{ x = 4
   y = 8
   z = [x..y]           # z is [ 4, 5, 6, 7, 8 ]
}}

هش‌ها (hashes)

هش‌ها لیست‌های کلید-مقدار هستند با استفاده از {} یا . بین کلید و مقدار می‌توان یک هش را تعریف کرد.

{{ product = {
     id    = 'XYZ-2000'
     desc  = 'Bogon Generator'
     price = 576
   }
}}
یا کمی شبیه‌تر به پرل
{{ product = {
     id    => 'XYZ-2000',
     desc  => 'Bogon Generator',
     price => 576,
   }
}}
یا
{{ product.id    = 'XYZ-2000' 
   product.desc  = 'Bogon Generator'
   product.price = 576 
}}

و برای دسترسی به هر مقدار:

دسترسی مستقیم

product id is : {{ product.id }}   # product id is : XYZ-2000
product id is : ${product.id}      # product id is : XYZ-2000

دسترسی با کلیدواژه‌ی keys

{{ FOREACH item IN product.keys }}
   {{ item }} is {{ product.$item }}
}}
خروجی:
id is XYZ-2000
desc is Bogon Generator
price is 576

دسترسی با کلیدواژه‌ی pairs

{{ FOREACH item IN product.pairs }}
   {{ item.key }} is {{ item.value }}
}} 

هش ها هیچ ترتیبی برای ذخیره شدن ندارند، برای ترتیب چیده شدن آن‌ها از کلیدواژه‌ی sort می‌توان استفاده کرد:

{{ FOREACH item IN product.keys.sort }}
   {{ item }} is {{ product.$item }}
}}

در یافت اندازه‌ی هش با کلیدواژه‌ی size

{{ product.size }}  # 3

در صورتیکه بخواهیم یک هش را بدون استفاده از کلیدواژه‌های key یا pairs لود کنیم می‌توان:

{{ users = {
     tom   => 'Thomas',
     dick  => 'Richard',
     larry => 'Lawrence',
   }
}}

{{ FOREACH u IN users }}
   * {{ u.key }} : {{ u.value }}
{{ END }}

خروجی:

* dick : Richard
* larry : Lawrence
* tom : Thomas

ترکیب هش‌ها و لیست‌ها

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

متدهای شبیه‌سازی و درونیابی

{{ mylist = [ 'foo', 'bar', 'baz' ] }}
{{ newlist = mylist.sort }}

{{ foo = 'html' }}
{{ FILTER $foo }}   # {{ FILTER html }}

{{ first  = 'hello' }}
{{ second = 'world' }}
{{ third  = "$first $second" }}

{{ utid = '123456789' }}
{{ ENTRIES.$utid.title }}

{{ post = {
   utid = '123456789',
   title = 'test',
   }
}}
{{ ENTRIES.${post.utid}.title }}

تنظیم، دسترسی، تغییر متغیرها

GET

با استفاده از get میتوان مقدار یک متغیر را دریافت کرد و نمایش داد

{{ GET post.body.title }}

استفاده از GET در این برچسب اختیاری است.

{{ post.body.title }}

SET

با استفاده از set میتوان به یک متغیر مقدار داد

{{ SET foo = 'hello' }}

استفاده از SET اختیاری است.

{{ foo = 'hello' }}

DEFAULT

در صورتیکه متغیری مقدار نداشته باشد به آن مقدار می‌دهد. اگر متغیر مقدار از پیش تعیید شده داشته باشد از مقدار دادن به آن چشم پوشی می‌شود.

{{ id = 'jodo' }}
{{ DEFAULT
    name = 'John Doe'
    id   = 'jdoe'
}}
نتیجه:
name = 'John Doe'
id   = 'jodo'

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

INSERT

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

{{ INSERT myfile.txt }}

فایل وارد شده توسط INSERT حتما باید در دایرکتوری یا زیردایرکتوری‌های موجود در پوسته باشد.

{{ INSERT foo }}            # looks for YOUR_MIRA/template/YOUR_THEME/foo
{{ INSERT bar/foo }}            # looks for YOUR_MIRA/template/YOUR_THEME/bar/foo
{{ INSERT /etc/passwd }}    # file error: ABSOLUTE not set
{{ INSERT ../secret }}      # file error: RELATIVE not set

از متدهای درون‌یابی نیز می‌توان استفاده کرد:

{{ language = SITE.language
   file = 'SITE.about' 
}}

{{ INSERT "$language/$file" }}  # en/file.txt

INCLUDE

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

{{ INCLUDE hedar }}
{{ INCLUDE body }}
{{ INCLUDE footer }}

همچنین می‌توان هنگام INCLUDE به متغیرها عدد داد یا از متغیرهای از پیش تعریف شده استفاده کرد.

فایلی با نام header در زیر دایرکتوری partial از پوسته را در نظر بگیرید

<html lang="{{ my_lang }}">
<head>
   <title>{{ my_title }}</title>
</head>

که به این شکل وارد پوسته شود:

{{ my_lang = "Fa" }}
{{ INCLUDE partial/headr my_title="Mira" }}
<body>
...

خروجی:

<html lang="Fa">
<head>
   <title>Mira</title>
</head>
<body>
...

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

{{ foo = 10 }}

foo is originally {{ foo }}
{{ INCLUDE bar }}
foo is still {{ foo }}

{{ BLOCK bar }}
   foo was {{ foo }}
   {{ foo = 20 }}
   foo is now {{ foo }}
{{ END }}

خروجی:

foo is originally 10
   foo was 10
   foo is now 20
foo is still 10

PROCESS

همانند INCLUDE عمل می‌کند، اما متغیرهایی که با استفاده از PROCESS تغییر می‌کنند به شکل عمومی در تمام پوسته مقدارشان تغییر می‌نماید.

{{ foo = 10 }}

foo is {{ foo }}
{{ PROCESS bar }}
foo is {{ foo }}

{{ BLOCK bar }}
   {{ foo = 20 }}
   changed foo to {{ foo }}
{{ END }}

خروجی:

foo is 10
   changed foo to 20
foo is 20

BLOCK

کلیدواژه‌ی BLOCK یک دستور از نوعی بلوک میباشد که بین BLOCK و END تعریف می‌شود

{{ BLOCK tabrow }}
<tr>
  <td>{{ name }}<td>
  <td>{{ email }}</td>
</tr>
{{ END }}

از این بلوک کد در هرکجا از پوسته با استفاده از PROCESS یا INCLUDE می‌توان استفاده کرد.

<table>
  {{ PROCESS tabrow  name='Fred'  email='fred@nowhere.com' }}
  {{ PROCESS tabrow  name='Alan'  email='alan@nowhere.com' }}
</table>

شرط‌ها

IF/UNLESS/ELSIF/ELSE

برچسب‌های IF و UNLESS برای بررسی یک شرط و اجرا یا چشم پوشی از کدهای تعریف شده‌ی درونی خود دارند. IF در صورتیکه که شرط درست باشد اجرا می‌شود و UNLESS در صورتیکه شرط اشتباه باشد.

{{ IF post.image }}
   <img src="{{ post.image }}">
{{ END }}

{{ UNLESS post.image }}
   {{ INCLUDE text_mode }}
{{ END }}

تعداد شرط‌های بررسی شونده را با استفاده از ELSIF و ELSE می‌توان افزایش داد.

{{ IF IS_MAIN }}
   you are in main page
{{ ELSIF IS_ARCHIVE }}
   you are in archives page
{{ ELSE }}
   you are in index, feed or post
{{ END }}

و یا

{{ IF age < 10 }} {{# > }}
   Hello, does your mother know you're using her account?
{{ ELSIF age < 18 }} {{# > }}
   Sorry, you're not old enough to enter 
   (and too dumb to lie about your age)
{{ ELSE }}
   Welcome.
{{ END }} 

برای کنترل شرط این کنترل‌کننده‌ها در دسترس هستند:

== != < <= > >= && || ! and or not

مقادیر and, or, not و && || ! با هم برابر هستند و هیچ اولویتی نسبت به یکدیگر ندارند.

{{ IF (name == 'admin' || uid <= 0) && mode == 'debug' }}
   I'm confused.
{{ ELSIF more > less }}
   That's more or less correct.
{{ END }}

SWITCH/CASE

برای بررسی شرط‌ها از SWITCH/CASE نیز می‌توان استفاده کرد. SWITCH مقداری که باید مورد بررسی قرار بگیرد را دریافت می‌کند و در هر CASE درستی شرط بررسی می‌شود.

{{ SWITCH SITE.language }}
   {{ CASE 'Farsi' }}
      {{ message = "خوش آمدید" }}
   {{ CASE 'English' }}
      {{ message = "welcome" }}
{{ END }}

حلقه‌ها

FOREACH

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

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

{{ FOREACH post IN POSTS }}
   {{ post.title }}
   ...
{{ END }}
یا
{{ FOREACH entry IN POSTS }}
   {{ entry.body.more }}
   ...
{{ END }}

یا کلا از کلید چشم پوشی شود:

{{ FOREACH POSTS }}
   {{ title }}
   {{ body.more }}
   ...
{{ END }}

WHILE

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

{{ totla = 200 }}
{{ WHILE total > 100 }}
   total is : {{ total }}
   {{ total = total - 1 }}
{{ END }}

کنترل حلقه FOREACH

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

{{ FOREACH post IN POSTS }}
  {{ IF loop.first }}
     {{ post.body.more }}
  {{ ELSE }}
     {{ post.body.less }}
  {{ END }}
{{ END }}

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

first

در صورتیکه حلقه در اولین اجرای خود باشد مقدار صحیح را باز می‌گرداند.

last

در صورتیکه حلقه در آخرین اجرای خود باشد مقدار صحیح را باز می‌گرداند.

size

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

count

شماره‌ی حلقه‌ای که در حال تکرار شدن است را باز می‌گرداند.

prev

امکان دسترسی به مقادیر تکرار پیشین حلقه.

{{ FOREACH post IN POSTS }}
   {{ IF loop.prev.CALENDAR.year != post.CALENDAR.year }}
      {{ post.year }}
   {{ END }}
   {{ post.title }}
{{ END }}

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

next

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

parity

به ترتیب برای هربار لود شدن حلقه مقادیر odd و even را باز میگرداند.

<table>
{{ FOREACH name IN ['Arthur', 'Ford', 'Trillian'] -}}
  <tr class="{{ loop.parity }}">
    <td>{{ name }}</td>
  </tr>
{{ END }}
</table>

خروجی:

<table>
  <tr class="odd">
    <td>Arthur</td>
  </tr>
  <tr class="even">
    <td>Ford</td>
  </tr>
  <tr class="odd">
    <td>Trillian</td>
  </tr>
</table>

odd

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

even

با هر بار تکرار شدن حلقه مقادیر 0 و 1 را به نوبت برای تکرار های فرد و زوج حلقه باز می‌گرداند. به عبارت دیگر برای تکرارهای دوم، چهارم، ششم، ... حلقه مقدار 1 یا صحیح را برمیگر‌داند.

NEXT

{{ FOREACH user IN users }}
   {{ NEXT IF user.isguest }}
   Name: {{ user.name }}    Email: {{ user.email }}
{{ END }}

LAST

{{ FOREACH user IN users }}
   Name: {{ user.name }}    Email: {{ user.email }}
   {{ LAST IF some.condition }}
{{ END }}

فیلترها

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

{{ FILTER html }}
   HTML text may have < and > characters embedded
   which you want converted to the correct HTML entities.
{{ END }}   
خروجی:
HTML text may have &lt; and &gt; characters embedded
which you want converted to the correct HTML entities.

و یا در سایر دستورها

{{ INCLUDE mytext | html | url }}
{{ post.title FILTER url }} 
{{ post.body.more | xml }}

format

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

{{ FILTER format('<!-- %-40s -->') }}
   This is a block of text filtered 
   through the above format.
{{ END }}

خروجی:

<!-- This is a block of text filtered        -->
<!-- through the above format.               -->

uper

تمام حروف را با حروف بزرگ جایگزین می‌کند.

lower

تمام حروف را با حروف کوچک جایگزین می‌کند.

ucfirst

اولین حرف رشته را با حروف بزرگ باز می‌گرداند.

lcfirst

اولین حرف رشته را با حروف کوچک باز می‌گرداند.

collapse

{{ FILTER collapse }}

   The   cat

   sat    on

   the   mat

{{ END }}

خروجی:

The cat sat on the matter

html

کاراکترهای < و > و & و " را به مقادیر html باز میگرداند.

{{ FILTER html }}
Binary "<=>" returns -1, 0, or 1 depending on...
{{ END }}

خروجی:

Binary "&lt;=&gt;" returns -1, 0, or 1 depending on...

xml

ماند فیلتر html اما ' نیز به آن افزوده شده است.

html_para

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

{{ FILTER html_para }}
The cat sat on the mat.

Mary had a little lamb.
{{ END }}

خروجی:

<p>
The cat sat on the mat.
</p>

<p>
Mary had a little lamb.
</p>

html_break / html_para_break

مانند html_para با این تفاوت که پاراگراف‌ها را با br از هم جدا می‌کند.

{{ FILTER html_break }}
The cat sat on the mat.

Mary had a little lamb.
{{ END }}

خروجی:

The cat sat on the mat.
<br>
<br>
Mary had a little lamb.

html_line_break

این فیلتر هر کاراکتر خط جدید را با یک br جایگزین می‌کند

{{ FILTER html_line_break }}
The cat sat on the mat.
Mary had a little lamb.
{{ END }}

خروجی:

The cat sat on the mat.<br>
Mary had a little lamb.<br>

uri

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

{{ path  = 'http://tt2.org/example'
   back  = '/other?foo=bar&baz=bam' 
   title = 'Earth: "Mostly Harmless"'
}}
<a href="{{ path }}?back={{ back | uri }}&title={{ title | uri }}">

خروجی:

<a href="http://tt2.org/example?back=%2Fother%3Ffoo%3Dbar%26baz%3Dbam&title=Earth%3A%20%22Mostly%20Harmless%22">

برای آدرس از این فیلتر اصلی نکنید، از url استفاده کنید.

url

این فیلتر هر متن ورودی را به کاراکترهای مجاز برای آدرس همانطور که در RFC 2396 مشخص شده تبدیل می‌نماید.

indent

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

{{ FILTER indent('ME> ') }}
blah blah blah
cabbages, rhubard, onions 
{{ END }}

خروجی:

ME> blah blah blah
ME> cabbages, rhubard, onions

truncate(length,dots)

به اندازه‌ی مشخص شده در length کاراکتر از ابتدای متن نمایش می‌دهد، در صورتیکه dots مقدار داشته باشد، با الگوی مشخص شده مابقی متن جایگزین می‌شود.

{{ FILTER truncate(21) }}
I have much to say on this matter that has previously 
been said on more than one occasion.
{{ END }}

خروجی:

I have much to say...

در صورتیکه نخواهید از ... استفاده کنید، میتوانید این الگو را تغییر دهید:

{{ FILTER truncate(26, 'CONTINUE+++OTHER') }}
I have much to say on this matter that has previously 
been said on more than one occasion.
{{ END }}

خروجی:

I have much to say CONTINUE+++OTHER;

repeat

به تعداد مشخص یک الگو را تکرار میکند.

{{ FILTER repeat(3) }}
We want more beer and we want more beer,
{{ END }}
We are the more beer wanters!

خروجی:

We want more beer and we want more beer,
We want more beer and we want more beer,
We want more beer and we want more beer,
We are the more beer wanters!

remove

الگوی مشخص شده را از متن حذف می‌کند. در الگوی مورد نظر از regex میتوانید استفاده کنید.

{{ "The  cat  sat  on  the  mat" FILTER remove('\s+') }}

خروجی:

Thecatsatonthemat

replace

الگوی مورد نظر را در متن با الگوی مشخص شده جایگزین میکند.

{{ "The  cat  sat  on  the  mat" | replace('\s+', '_') }}

خروجی:

The_cat_sat_on_the_mat

$FarsiNum

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

{{ post.CALENDAR.year | $FarsiNum }}     # ۲۰۱۷

ماکروها و پرل

MACRO

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

{{ MACRO header IF frames }}
   {{ INCLUDE frames/header }}
{{ ELSE }}
   {{ INCLUDE header }}
{{ END }}

{{ header }}

یا

{{ MACRO number(n) GET n.chunk(-3).join(',') }}
{{ number(1234567) }}    # 1,234,567

PERL

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

{{ PERL }}
   print "hello world \n";
   print "personal post" if $post->{category} eq "personal";
{{ END }}

سایر کنترل کننده‌ها

NEXT

{{ FOREACH user IN users }}
   {{ NEXT IF user.isguest }}
   Name: {{ user.name }}    Email: {{ user.email }}
{{ END }}

LAST

{{ FOREACH user IN users }}
   Name: {{ user.name }}    Email: {{ user.email }}
   {{ LAST IF some.condition }}
{{ END }}

RETURN

Before
{{ INCLUDE half_wit }}
After

{{ BLOCK half_wit }}
This is just half...
{{ RETURN }}
...a complete block
{{ END }}