برای سالها بود که از Handlebars توسعه اپلیکیشنهای مبتنی بر نودجیاس و سیستم Template Engine استفاده میکردم اما اخیرا با مشکلاتی مواجه شدم که دیگر نمیتوانستم از آنها چشم بپوشم. Handlebars عالیست اما ویژگیهای منطقی که یک Template Engine باید داشته باشد را به خوبی ارائه نمیکند و همین موضوع کمی آزاردهنده است. با این حال زمانی که تصمیم گرفتم تا وبسایتم را دوباره بازسازی کنم سعی در ایجاد یک Template Engine اختصاصی نموده و یک سیستم مناسب را ایجاد کردم.
البته این سیستم از نظرهایی شباهت بسیار زیادی با Handlebars دارد اما در کل کارایی بالاتری داشته و امکانات بیشتری نیز دارد.
نقشه من برای طراحی این سیستم که آن را Moe-JS نامیدم آن بود که بتوانم ویژگیهای زیر را در آن پیادهسازی کنم:
- سینتکسی مشابه با Handlebars
- پشتیبانی از قرار دادن جاوااسکریپت به صورت مستقیم
- کامپایل شدنی و سریع
- پشتیبانی از async
- قابلیت گسترشپذیری
سینتکسی مشابه با Handlebars
هدف من از انجام چنین کاری آن بود که توسعهدهندگان مجبور به یادگیری یک سینتکس جدید نشده و با همان سینتکس قدیمی و البته سازگار کارهایشان را انجام دهند. از طرفی دیگر من کدهایی را قبلا نوشته بودم و دوست نداشتم یک بار دیگر آنها را با یک سینتکس متفاوت بنویسم. بنابراین اگر شما با Handlebars آشنایی داشته باشید مطمئنا قطعه کد زیر برایتان آشنا خواهد بود:
<h1>{{model.title}}</h1>
{{#each item in model.items}}
{{#if item.price != 0}}
<p>{{item.name.toUpperCase()}} - {{{helpers.formatPrice(item.price)}}}</p>
{{/if}}
{{/each}}
پشتیبانی از قرار دادن جاوااسکریپت به صورت مستقیم
Moe-JS به صورت پیشفرض از عبارات جاوااسکریپتی پشتیبانی میکند. همچنین شما میتوانید قطعه کدهای جاوااسکریپتی مورد نظرتان را به صورت مستقیم در آن قرار دهید. برای مثال:
{{#code}}
function doSomething(value)
{
...
}
{{/code}}
{{doSomething(99)}}
کامپایل شدنی و سریع
برای سادگی و بهینه بودن از نظر کارایی Moe-JS به گونهای ساخته شده که به صورت مستقیم به جاوااسکریپت تبدیل میشود. همچنین برای جلوگیری از ایجاد هرگونه قابلیت داینامیک که منجر به کاهش کارایی یک سیستم میشود من قابلیت ارجاع مستقیم را در آن پیادهسازی کردم. بنابراین بجای اینکه به صورت زیر به مقدار title دسترسی داشته باشیم:
<p>{{title}}</p>
به این صورت عمل میکنیم:
<p>{{model.title}}</p>
در زمان تعریف حلقه و پیمایش روی یک مقدار نیز درست به همین صورت عمل خواهیم کرد:
{{#each u in model.Users}}
{{#each r in u.roles}}
<p>Name: {{u.name}} Role: {{r}}</p>
{{/each}}
{{/each}}
پشتیبانی از async
اگر به صورت ادغام شده از Moe-js در کنار Express استفاده کنید به صورت پیشفرض از قابلیتهای async پشتیبانی میشود. اما به صورت کلی میتوانید از کلمات کلیدی Async و Await به صورت زیر استفاده نمایید:
<p>Data: {{await model.callSomeAsyncMethod()}}</p>
البته میتوان از حالت عادی یا همان sync نیز استفاده کنید.
گسترشپذیری آسان
یکی از دغدغههای اصلی من قابلیت گسترشپذیری این Template Engine بود که برای آن نیز نقشه خوبی را در نظر گرفتم. با استفاده از moe.helpers من قابلیتی را ایجاد کردم که به سادگی میتوانستید از توابع ایجاد شده در Templateها استفاده کنید. برای مثال من یک تابع را به صورت زیر ایجاد میکنم:
moe.helpers.FormatPrice = function (val)
{
if (val == 0)
return "-";
else
return "$" + val.toFixed(2);
}
و حال به صورت زیر در Template آن را فراخوانی میکنم:
<p>Price: {{helpers.FormatPrice(item.price)}}</p>
ویژگیهای دیگر
جدای از این موارد Moe-JS از موارد دیگری نیز پشتیبانی کرده که در زیر میتوانید آنها را مشاهده کنید:
- پشتیبانی از Partials و Layouts
- قابلیت ادغامسازی با Express View Engine
- ارسال خروجی Template به یک متغیر
- مستقل از ابزارهای دیگر
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید