menu

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

Pug

جمعه 26 شهریور 1395

در ادامه، ما با یکی از HTML PreProccessor ها قراره آشنا بشیم. HTML PreProccessor هم به اون معنا هست که ما کدهای خودمون را به زبان خاصی که اون PreProccessor در اختیار ما قرار میده مینویسیم (با امکاناتی که داره مثل حلقه ها و شرط ها و متغیر ها و توابع و....) و در نهایت، به صورت Back-end کدهای ما پردازش میشه و خروجی HTML معمولی به ما میده

یکی از معروف ترین HTML PreProccessor هایی که قراره امروز باهاش کار کنیم، اسمش Pug هست. (اسم این PreProccessor قبلا Jade بود و من هم همش میخوام بهش بگم Jade ! اما سر یه سری مشکلات که سر اسمشون پیش اومد، اسمشون را به Pug تغییر دادند. البته نظر شخصی خودم را هم اینجا وارد کنم، از سگ ها اصلا خوشم نمیاد! حالا هر مدلی که میخواد باشه. البته الان که دارم دقیق تر فکر میکنم میبینم از هیچ حیوونی خوشم نمیاد!)

اول از همه، یه سری با سایتشون اینجا میزنیم؛ بد هم نیست که یه سری به Syntax های اینجا بزنید

در واقع، ابزار هایی مثل Pug یه جور Template Engine هستند که توسط سرویس های Server side برای ساخت Template و محتوا استفاده میشند (و البته از اونجایی که Pug بر اساس node نوشته شده، بیشترین کاربرد Pug به عنوان Nodejs Template Engine هست)

البته یه نکته ای را هم اضافه کنم، با اومدن Pug 2، کل پروژه اسمش به طور کامل از Jade به Pug تغییر کرد، ولی تغییر فقط منحصر به تغییر اسم نبود. یه سری از Syntax ها هم تغییر کردند و البته اسم فایل ها. یعنی شما قبلا برای اینکه یه پروژه ی جدید بسازید، پسوند jade به فایل هاتون میدادید، ولی الان باید پسوند pug به فایل هاتون بدید، و البته یه کمی هم Syntax ها عوض شده. من Syntax هام را طبق نسخه ی Pug 2 مینویسم و اینجا مینویسم، ولی شاید شما ببینید که توی سایت ها و منابع دیگه، Syntax ها کمی فرق داشته باشه

و در نهایت، میریم سراغ نصب Pug

گفتم که Pug بر اساس Node نوشته شده، پس ما هم باید برای نصبش از NPM استفاده کنیم

npm install -g pug

ولی این پکیج برای استفاده از Pug کافی نیست!

در واقع با نصب این پکیج، برای ما هسته ی اصلی pug را نصب میکنه، ولی چون ما میخواهیم که فایل های pug خودمون را کامپایل کنیم و خروجی html بگیریم (چون ما فعلا نمیخواهیم صفحه مون را کامل با nodejs بنویسیم، پس نمیخواهیم که مستقیم از pug به عنوان template Engine استفاده کنیم)، نیاز به بسته ی دیگه هم داریم، پس بسته ی زیر را هم نصب میکنیم

npm install -g pug-cli

در واقع با نصب pug-cli ، ما این امکان را داریم که دقیقا عین Less و Sass، با زدن یه کد، فایل pug خودمون را کامپایل کنیم و خروجی HTML ازش بگیریم

pug-cli، آپشن های زیادی در اختیار ما میزاره که میتونید اینجا ببینیدشون، ولی ما فعلا مثل همیشه از ساده ترین آپشن اون استفاده میکنیم

pug --version

و pug خودمون را Version Control میکنیم

(یه بسته ی دیگه هم که من نصب کردم، بسته ی pug-lint بود که هم روی npm نصبش کردم و هم روی sublime خودم دارم که میتونید درباره ی اون اینجا بخونید. البته برای Syntax highlight و اینای خودم توی Sublime خودم پلاگین pug را هم نصب کرده ام)

بریم شروع کار با Pug خودمون. برای شروع، من یه دایرکتوری ساخته ام به اسم Pug و یه فایل index.pug دارم توش که خب pug هم فرمت pug هست!

برای شروع، بهتره یه کد توی pug بزنیم و اون را کامپایل کنیم

من کد زیر را میزنم

h1

به همین سادگی، هیچ نیازی به علامت ها <> هم نیست. (البته از نظر من Syntax اون خیلی شبیه به Syntax ی هست که توی markdown استفاده میکردیم)

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

pug index.pug

و با زدن کد بالا، به ما خروجی html در قالب فایل index.html میده. اضافه کنم که دستور بالا را pug-cli انجام میده و pug-cli آپشن های خیلی زیاد تری در اختیار ما میزاره. مثلا در این حالت، ما الان فقط فایل index.pug را کامپایل کردیم، ولی میتونستیم به جای این کار، کل پوشه ی pug را کامپایل کنیم!

pug pug

با این کار تمام فایل های pug که داخل یه پوشه باشند کامپایل میشند

یا میتونیم از آپشن w هم استفاده کنیم! این همون آپشن watch ما هست که توی Sass و Stylus هم بود. با زدن این آپشن، به محظ تغییر توی فایل pug ما، به طور خودکار برای ما اون را کامپایل میکنه و فایل html ما را آپدیت میکنه. من کل دایرکتوری pug خودم را watch میزنم تا نیاز نباشه هر دفعه بیام توی ترمینال کامپایل کنم فایل هام را و فقط توی Sublime کدهام را بزنم

pug -w pug

البته یه آپشن دیگه هم هست به اسم P ( حرف P بزرگ هست). pug به طور پیش فرض، فایل های html خروجی ما را به طور فشرده در میاره و خروجی میده (تمام المنت ها و تگ ها توی یه خط پشت سر هم). این کار برای داشتن یه خروجی واسه ی نمایش روی وب خیلی خوب هست، به خاطر حجم پایینش. ولی چون ما فعلا میخواهیم برای تست و نمایش کد روش بزنیم، کد های ما خوانایی لازم را نداره. برای این که کدهامون مرتب و تمیز و خوانا نمایش داده بشه، از این آپشن هم استفاده میکنم

pug -w -P pug

بریم سراغ کار کردن و Syntax های Pug

الف) استفاده از تگ ها

برای استفاده از تگ ها توی Pug، فقط کافیه که اسم اون تگ را بنویسید، به همین راحتی. هیچ نیازی هم به <> نیست. حتی به نوشتن تگ پایانی با استفاده از / هم نیازی نیست. خود Pug پس از پردازش علامت های <> را بهش اضافه میکنه. مثلا برای داشتن یه H1 فقط کافیه بنویسیم

h1

و خروجیش میشه

<h1></h1>

ب) استفاده از محتوا

ولی مهم تر از نوشتن یه تگ، اینه که داخل اون تگ محتوا قرار بدی. مثلا همون تگ h1 بالا، اگه متنی توش نباشه که به درد نمیخوره. برای نوشتن متن درون یه تگ، کافیه که از Space استفاده کنیم!

مثلا کد زیر

h1 Heading 1

نتیجه اش میشه

<h1>Heading 1</h1>

یا مثلا کد زیر

p My Paragrahp

چنین خروجی خواهد داشت

<p>My Paragrahp</p>

پ) استفاده از class و id

class و id به درد بخور نیستند، تا وقتی که پای CSS بیاد وسط و از اونجایی که یه سایت بدون CSS خیلی بی ریخت میشه، پس حتما به Class و id هم نیاز میشه. برای تعریف یه Class و id مثل بیشتر سیستم های دیگه، کافیه از # و . استفاده کنیم.

مثلا

h1.myclass.secondclass#myId Heading 1

توی Pug ما چنین خروجی را در بر خواهد داشت

<h1 class="myclass secondclass" id="myId">Heading 1</h1>

ت) المنت های تو در تو (child Element)

شاید شما بخواهید برای یه تگ، یه تگ فرزند تعیین کنید. مثلا فرض کنید که یه تگ p داریم که میخواهیم داخل اون یه تگ span داشته باشیم. برای این که این المنت های تو در تو را بسازیم، کافیه از اینتر و tab استفاده کنیم. هر خط جدید و Tab نشان گر یه المنت داخل المنت قبلی هست. مثلا

ul
	li Some List Item

به صورت

<ul>
  <li>Some List Item</li>
</ul>

پردازش خواهد شد.

ث) خصیصه ها

همه ی تگ ها با محتوا و id شناخته نمیشند. خیلی از تگ ها مثل a و یا img بدون داشتن href و src و خصیصه های این شکلی عملا بی معنا هستند. برای استفاده از این خصیصه ها، توی Pug کافیه که از () استفاده کنیم.

img(src='http://noisy.ir/img/navbar.jpg')

که خروجی زیر را به ما میده

<img src="http://noisy.ir/img/navbar.jpg"/>

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

img(src='http://noisy.ir/img/navbar.jpg', Title='My picture')

یعنی با استفاده از یه کاما، چند تا خصیصه را از هم جدا میکنیم. البته این Syntaxt مال Pug 1 هست که همون Syntax مربوط به Jade هست. توی Pug 2 برای این کار ما میتونیم از طریق زیر هم عمل کنیم

img(
	src='http://noisy.ir/img/navbar.jpg'
	Title='My picture'
)

یعنی باز هم با استفاده از Enter و tab، خیلی شبیه به آرایه ها، خصیصه های مختلف خودمون را تعیین کنیم.

و در هر دو صورت، خروجی ما این میشه

<img src="http://noisy.ir/img/navbar.jpg" Title="My picture"/>

ج) نظر گذاری (Comment)

توی Pug ما دو نوع Comment داریم. Comment ی که خروجیش توی HTML خواهد بود و Comment ی که خروجی نمیده

نوع اول، به این شکل هست

//This will be shown in HTML

و خروجیش توی HTML ما این شکلیه

<!--This will be shown in HTML-->

و نوع دوم Comment ما هم که خروجی به ما نمیده، تفاوتش با نوع اول توی یه - هست

//-Silent Comment

که با اجرای این کد Pug، میبینید که هیچ خروجی توی HTML نخواهید داشت.

 

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

doctype
html(lang="fa")
	head
		title PUG!
		script(src='script.js')
	body
		h1 Hello My Pug!!

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

<!DOCTYPE html>
<html lang="fa">
  <head>
    <title>PUG!</title>
    <script src="script.js"></script>
  </head>
  <body>
    <h1>Hello My Pug!!</h1>
  </body>
</html>

خیلی راحت، با استفاده از Pug میتونیم صفحات خودمون را بسازیم

چ) استفاده از فایل های دیگر

چیزی که تقریبا توی همه ی Template Engine ها و PreProccessor ها وجود داره، استفاده از فایل های دیگه است. این کار باعث میشه که ما بتونیم صفحاتمون را ماژولار بنویسیم و از نوشتن کدهای اضافه هم جلوگیری میکنه. مثلا فرض کنید که 5 تا صفحه داریم، که میخواهیم توی همه ی اون 5 تا صفحه، یه قسمت به اسم "اشتراک در خبرنامه" داشته باشیم. واقعا بصرفه نیست که بیایم این قسمت را توی هر 5 تا صفحه مون جداگانه بنویسیم. میتونیم یه بار بنویسیم توی یه فایل جداگانه و از اون توی صفحات مختلف خودمون استفاده کنیم و یه سایت ماژولار داشته باشیم

برای این کار، Pug دستور include را در اختیار ما قرار میده. خیلی راحت من یه فایل به اسم myblock.pug میسازم و کد زیر را توش میزنم

h2 This will be my Block
p some another text

و از این بلاکی که ساخته ام، توی فایل index.pug خودم استفاده میکنم

include myblock

و میبینید که توی فایل index.html خودم خروجی زیر را خواهم داشت

<h2>This will be my Block</h2>
<p>some another text</p>

یه چیز جالب دیگه که این دستور include داره، اینه که فقط فایل های pug را وارد نمیکنه. شما میتونید باهاش فایل های txt و ... هم وارد صفحه تون کنید. فقط دقت کنید که اگه میخواهید فایل pug وارد صفحه کنید نیازی به وارد کردن پسوند فایل نیست، ولی اگه میخواهید فایل txt وارد کنید باید همراه با اسم فایل، پسوند اون را هم وارد کنید. (فرمت فایل را باید همراه اسمش وارد کنید)

ح) extends

یکی دیگه از مفاهیمی که خیلی شبیه به include هست توی Pug، مفهوم Extend و block هست. فرض کنید ما یه صفحه داریم که دقیقا مطالبش عین یه صفحه ی دیگه است. برای اینکار میتونیم یکی را extend یکی دیگه بکنیم. مثلا فرض کنید فایل page1.pug را داریم با محتوای زیر

doctype
html
	head
	body
		h1 header of page 1
		p some text here
		p and some text here

و میخواهیم که محتوای فایل page2.pug ما هم دقیقا همین باشه. حالا برای این کار به جای copy و paste کردن میتونیم از extend استفاده کنیم. پس توی فایل page2.pug میزنیم

extend page1.pug

و بعد از کامپایل میبینیم که یکی وابسته به دیگری شده و محتوا ها شبیه به هم هستند. ولی صبر کنید. یکم ضایع شد. ما توی h1 فایل page1.pug داریم header of page1. نمیشه که توی page2.pug ما هم همین باشه. پس باید تغییرش بدیم. یعنی یه قسمتی باشه که با وجود extend شدن، قابلیت تغییر هم داشته باشه

برای این کار، کافیه از block استفاده کنیم. پس توی فایل page1.pug کدمون را اینطوری تغییر میدیم

doctype
html
	head
	body
		block header
			h1 header of page 1
		p some text here
		p and some text here

و الان توی فایل page2.pug میتونیم با استفاده از block ها، روی block مورد نظرمون کنترل داشته باشیم. مثلا متنش را عوض کنیم

extend page1.pug
block header
	h2 header of page 2

یا حتی یه محتوا به انتهای محتوای قبلی اون block اضافه کنیم

extend page1.pug
block append header
	h2 header of page 2

یا یه محتوا به ابتدای محتوای قبلی اضافه کنیم

extend page1.pug
block prepend header
	h2 header of page 2

تا به اینجای کار، معرفی Pug ما تموم شد. البته باید متوجه شده باشید که Pug واقعا یه ابزار فوق العاده است و توی یه پست به این کوتاهی نمیشه اون را اون جور که شایسته ی این ابزار هست معرفی کرد. امکاناتی مثل Mixin (توابع) و استفاده از Case ها و شرط ها و متغیر ها و خیلی چیزهای دیگه هست که توی این فصل فرصت نشد بهش پرداخته بشه. پس حتما حتما به اینجا یه سری بزنید و از Pug لذت ببرید

در نهایت، میبینید که استفاده از Pug مزایای خیلی زیادی میتونه واسه ی ما داشته باشه. استفاده از فرمت هایی مثل minified و همچنین Syntax ساده ی اون باعث میشه که حجم صفحات ما کم بشه و کدهای ما خوانا تر باشند.