در طول استفاده از کوارتز، به مرور زمان تغییرات و اصلاحات مختلفی برای سفارشیسازی سایت انجام دادم. در این یادداشت فهرستی از این تغییرات را مستند کردم. این موارد نخست به عنوان یک مرجع شخصی عمل میکند تا در صورت نیاز بتوانم به راحتی تنظیمات قبلی را ویرایش کنم. از طرف دیگر میتواند راهنمای مفیدی باشد برای کسانی که تمایل دارند مشابه آن را روی سایت خود پیادهسازی کنند.
۱. متادادههای یادداشت
متاداده اطلاعات مربوط به یک یادداشت است که بعد از عنوان اصلی نمایش داده می شود. مثل تاریخ انتشار زمان تقریبی مطالعه. من ترجیح دادم تنظیمات زیر را به آن اضافه کنم:
زمان تقریبی مطالعه
بنا به دلایلی1 زمان تقریبی مطالعه را غیر فعال کردم. یک ویرگول هم برای جدا سازی این اطلاعات بین آن ها قرار میگرفت که آن را هم مخفی کردم. با اضافه کردن دستور زیر به فایل quartz.layout.ts نمایش این دو مورد غیرفعال میشود.
به طور پیشفرض کوارتز فقط یک تاریخ را به کاربر نشان میدهد که نهایتا می توانید زمان آن را روی تاریخ انتشار یا تاریخ آخرین آپدیت تنظیم کنید. من تمایل داشتم علاوه بر تاریخ انتشار، تاریخ آخرین بهروزرسانی هم برای کاربر قابل مشاهده باشد. با این دستور درصورتی که تاریخ انتشار و آخرین بهروزرسانی یکسان نباشد علاوه بر تاریخ انتشار، تاریخ آخرین بهروزرسانی هم به کاربر نمایش داده میشود.
برای تاریخ انتشار باید از پراپرتی date و برای تاریخ آخرین به روزرسانی باید از پراپرتی lastmod در یادداشت خود استفاده کنید.
quartz/components/ContentMeta.tsx
if (text) { const segments: (string | JSX.Element)[] = [] if (fileData.frontmatter) { const created = fileData.frontmatter.date ? formatDate(new Date(fileData.frontmatter.date), cfg.locale) : null const lastmod = fileData.frontmatter.lastmod ? formatDate(new Date(fileData.frontmatter.lastmod), cfg.locale) : null if (created) { segments.push(` 📅 انتشار: ${created} `) } if (lastmod && created !== lastmod) { segments.push(` 🔄 بهروزرسانی: ${lastmod} `) } }
این کد را از سایت کوانتوم گاردن گرفتم و کمی تغییر دادم. از اینجا میتوانید کدهای اصلی را مشاهده کنید.
وضعیت رشد
یکی از مواردی که در روش یادداشت برداری دیجیتال گاردن استفاده میشود مشخص کردن میزان رشد و پیشرفت یادداشت است. 🌱نهال، 🌿درختچه، 🌳همیشهسبز و 🍂زودگذر مواردی هستند که برای علامت گذاری وضعیت نوشته استفاده میکنم. در حالت عادی اگر پراپرتی خاصی را در یادداشت وارد کنید اتفاقی نمی افتد و چیزی در سایت نمایش داده نمی شود. پس ابتدا لازم است این پراپرتی را به کوارتز معرفی کنیم تا آن را شناسایی کرده و اطلاعات آن را نمایش دهد. با اضافه کردن کد زیر به فایل ContentMeta.tsx این تنظیم اعمال می شود.
ContentMeta.tsx
const status = fileData.frontmatter?.status || "نامشخص"; if (status !== "نامشخص") { segments.push(` ${status} `) }
این دستور نوشتهها را بررسی میکند اگر دارای پراپرتی با عنوان status باشند محتوای آن را نمایش می دهد.
---status: 🌱نهال---
استایل
برای این بخش یک بکگراند خاکستری روشن اضافه کردم که ظاهر بهتر و متمایزی داشته باشد.
طبیعتا صفحه اول نیاز به نمایش این اطلاعات ندارد. برای مخفی کردن این موارد از صفحه اول باید کد زیر را به فایل ContentMeta.tsx اضافه کنید. باید بعد از const text = fileData.text قرار بگیرد.
ContentMeta.tsx
if (fileData.slug === "index") { return <></>}
نمایش عنوان صفحه هم ضرورتی ندارد برای حذف آن کد بالا را به فایل quartz/components/ArticleTitle.tsx اضافه کنید. باید بعد از const title = fileData.frontmatter?.title قرار بگیرد. (+)
اضافه کردن تصویر شاخص
یکی از مواردی که معمولا در سایت ها استفاده می شود استفاده از تصویر شاخص برای یادداشت هاست. در کوارتز قابلیتی برای این مورد وجود ندارد. البته میتوان به صورت دستی یک تصویر را ابتدای یادداشت اضافه کرد. اما من بنا به دلایلی2 ترجیح دادم یک پراپرتی با عنوان image اضافه کنم و تصویر شاخص را در این پراپرتی وارد کنم.
با اضافه کردن کد زیر این قابلیت به کوارتز اضافه می شود. این کد باید بعد از const segmentsElements و قبل از } else { قرار بگیرد.
البته از آنجایی که شکست صفحه از سمت چپ انجام می شود در حالت موبایل یک مشکل ایجاد می شود. عنوان صفحه به انتهای صفحه منتقل شده و گراف ویو ابتدای صفحه قرار می گیرند. برای حل این مشکل کافیست در فایل custom.scss کد زیر را وارد کنیم:
البته راه حل دیگری هم وجود دارد. اینکه از هر مورد یک کپی بگیریم و با عبارت MobileOnly و DesktopOnly مشخص کنیم که در حالت موبایل یا دسکتاپ کدام سمت قرار بگیرد. منتها برای بعضی موارد مشکل ایجاد می شود. مثلا گراف ویو فقط در دستکتاپ کار میکند و در موبایل کار نمیکند، فقط باکس آن نمایش داده می شود و با کلیک روی آیکون آن گلوبال گراف هم باز نمی شود. برای جستجو هم همین اتفاق میافتاد.
۳. فارسی سازی
خوشبختانه کوارتز از زبان فارسی پشتیبانی میکند. و با ویرایش فایل fa-IR.ts میتوان از معادل فارسی کلمات استفاده کرد. اما چند مورد وجود دارد که که فارسی سازی نشده:
کلمه Home در Breadcrumbs
کلمه home در Breadcrumbs (مسیر راهنمای سایت) به فارسی تبدیل نشده. با اضافه کردن دستور زیر به فایل quartz.layout.ts می توانید کلمه آن را تغییر دهید:
Component.Breadcrumbs({rootName: "خانه",}),
نتیجه جستجو
اگر در باکس جستجو عبارتی را سرچ کنید و آن کلمه در سایت نباشد این متن را نمایش می دهد:
با ویرایش فایل search.inline.ts میتوانید آن را اصلاح کنید.
quartz\components\scripts\search.inline.ts
if (finalResults.length === 0) { results.innerHTML = `<a class="result-card no-match"> <h3>نتیجهای یافت نشد</h3> <p>عبارت دیگری را امتحان کنید</p> </a>`}
عنوان footnote
اگر از پاورقی استفاده کنید به طور پیشفرض یک عنوان با عبارت footnote به انتهای صفحه اضافه میشود. با قرار دادن کد زیر در custom.scss می توانید آن را با یک متن دیگر جایگزین کنید. (+)
برای راستچین شدن جهت متن لازم است فایل renderPage.tsx را ویرایش کنید. با اضافه کردن dir="rtl" به خط <html lang={lang}> جهت متن راستچین می شود.
<html dir="rtl" lang={lang}>
البته این روش همه متنها حتی نوشتههای انگلیسی را هم راستچین میکند. در بلاگ کریستالین یک ترفند برای حل این مشکل ارائه شده (اینجا. با اصلاحی که در فایل ofm.ts انجام شده جهت متن به صورت خودکار تنظیم میشود، یعنی متن فارسی راستچین و متن انگلیسی چپچین میشود. از اینجا میتوانید نتیجه این قابلیت را مشاهده کنید.
برای استفاده از این روش فایل ofm.ts را دانلود کرده و جاگزین فایل خود کنید:
quartz/plugins/transformers/ofm.ts
۵. بازطراحی صفحه 404
صفحه 404 لینک بازگشتی به سایت ندارد و کاربر نمیتواند به سایت برگردد. با اضافه کردن کد زیر به فایل 404.tsx لینک بازگشت به صفحه اصلی در این صفحه نمایش داده میشود. این کد باید بعد از <p>{i18n(cfg.locale).pages.error.notFound}</p> قرار بگیرد.
quartz\components\pages\404.tsx
<p>بازگشت به <a href="/">صفحه اصلی</a></p>
اگر قابلیت کامنت را فعال کرده باشید برای این صفحات هم کامنت نمایش داده می شود. با اضافه کردن کد زیر به فایل Comments.tsx می توانید نمایش آن را غیرفعال کنید.
quartz/components/Comments.tsx
if (fileData.slug === "404" || !fileData.slug) { return <></> }
۶. تغییر فوتر
فقط کمی استایلش را عوض کردم. برای لینک ها هم ترجیح دادم به جای متن، از لوگو استفاده کنم. توجه داشته باشید که اگر کد زیر را جایگزین کنید دیگر ویرایش لینک ها از طریق فایل quartz.layout.ts امکان پذیر نیست و باید همین کد را تغییر دهید.
در حالت پیشفرض حتی اگر طول یک سطر کوتاه باشد باز هم اسکرول محور افقی نمایش داده می شود. با اضافه کردن کد overflow-x: auto اسکرول تنها در صورتی نمایش داده میشود که طول سطر طولانی بوده و خارج از بلوک کد باشد.
بقیه تنظیمات مربوط به بکگراند، فونت و جهت قرار گفتن متن است.
تنظیم استایل دیاگرام در خود آن امکان پذیر است. دو خط آخر کد بالا استایل این دیاگرام را تعریف میکند. علاوه براین تنظیمات دیگری هم به فایل custom.scss اضافه کردم:
دایرکشن را روی rtl گذاشتم، چون معمولا از فارسی استفاده می کنم.
بکگراند را شفاف کردم، چون بکگراند code رو خاکستری کرده بودم، دیاگرام هم خاکستری شده بود.
مقداری سایز متن بدنه و هدینگ ها را افزایش دادم. همینطور فاصله بین خطوط.
custom.scss
body { font-size: 1.1em;}p { line-height: 2rem;} li { line-height: 2rem; }sup {vertical-align: middle; //اگه توی متن از پانوشت استفاده شده باشه باعث میشه فاصله بین خطوط به هم نریزه}h2 { font-size: 1.6rem; margin-top: 1rem; margin-bottom: -0.2rem; border-bottom: 1px solid var(--lightgray); padding-bottom: 0.2em;}h3 { font-size: 1.30rem; margin-top: 1rem; margin-bottom: -0.8rem;}h4,h5,h6 { font-size: 1.1rem; margin-top: 1rem; margin-bottom: -0.8rem;}
چرخش آیکون >
این آیکون در قسمت های مختلف مثل فهرست، اکسپلور و کالوت استفاده شده. جهت این آیکون در حالت بسته باید سمت چپ باشد در حالی که به سمت راست است. برای چرخش آن باید مقدار rotateZ را در فایل های مربوط به هر کدام از منفی90 به مثبت90 تغییر دهید.(+)
فهرست: quartz/components/styles/toc.scss
اکسپلور: quartz/components/styles/explorer.scss
کالوت: quartz/quartz/styles/callouts.scss
به این شکل:
&.collapsed .fold { transform: rotateZ(90deg); }
کالوت سفارشی
برای تغییر رنگ کالوت ها می توانید فایل quartz/quartz/styles/callouts.scss را ویرایش کنید. علاوه بر این میتوانید کالوت های جدید با آیکون های متفاوت اضافه کنید. مثلا من یک کالوت زرد رنگ با آیکون لامپ اضافه کردم:
لامپ
ابتدای فایل callouts.scss آیکون ها به این شکل --callout-icon مشخص شدند. یک خط را کپی کنید و اسم مورد نظر و کد SVG آیکون را جایگزین کنید. به این شکل:
این تنظیم استایل جدول را به حالت کارت تبدیل میکند. مشابه حالتی که تم minimal برای جدولهای dataview میسازد. یک حالت دیگر هم اضافه کردم که باعث می شود کارتها فقط در یک ردیف نمایش داده شوند و باقی کارتها با اسکرول کردن قابل مشاهده باشند. برای زمانی که تعداد کارتها زیاد باشد این روش مناسب تر است.
برای استفاده از این روش ابتدا این کد را به فایل custom.scs اضافه کنید.
برای اعمال این استایل میتوانید از دو روش استفاده کنید:
اگر میخواهید روی همه جدولهای موجود در یادداشت اعمال شود یک پراپرتی با عنوان cssclasses به یادداشت خود اضافه کنید و کلاس دلخواه را وارد کنید. به این شکل:
---cssclasses: card-g c-3---
اگر نمی خواهید این استایل روی همه جدولها اعمال شود می توانید جدول خود را در تگ div قرار داده و کلاس مورد نظر را برای آن تعریف کنید. به این شکل:
متن را در یک خط نگه داشته و کاراکتر های اضافی را مخفی میکند
nowarp2
متن را در دو خط نگه داشته و کاراکتر های اضافی را مخفی میکند
c1-1
نسبت تصویر را 1:1 تنظیم میکند
c16-1
نسبت تصویر را 16:9 تنظیم میکند
۸. دسته بندی و ساخت فهرست خودکار
دسته بندی در سایت باعث می شود کاربران مطالب را راحت تر پیدا کنند. کوارتز در حال حاضر قابلیتی برای دسته بندی ندارد و نهایتا میتوان از تگ یا فولدر استفاده کرد.
من ابتدا صفحات مستقلی را برای موضوعات ایجاد کردم و به صورت دستی لینک مطالب مرتبط را در آن وارد می کردم. اخیرا از پلاگین دیتاویو استفاده میکنم که به طور اتوماتیک این کار را انجام می دهد. البته خود پلاگین دیتاویو در کوارتز پشتیبانی نمی شود ولی میتوان از پلاگین Dataview Serializer استفاده کرد. چون جداول استخراج شده را به صورت HTML میسازد که به راحتی در کوارتز نمایش داده می شوند.
من ابتدا در یادداشت پراپرتی های زیر را وارد می کنم:
سپس با دستور زیر آن ها را استخراج می کنم. اگر یادداشت تصویر داشته باشد همان را نمایش می دهد. اگر نداشته باشد یک تصویر خالی (noimage.svg) نشان می دهد.
<!-- QueryToSerialize: table without id choice(image=null, ![[noimage.svg]], embed(link(image))), "[[" + file.name + "|" + title + "]]" From note WHERE draft = false AND parent = [[نرمافزار ابسیدین]] SORT order ASC -->
از روش قبلی هم برای تبدیل جدول به نمای کارتی استفاده میکنم:
Info
البته اخیرا تصمیم گرفتم به تصاویر را از فهرست حذف کنم و فقط مطالب مرتبط را لیست کنم. در حال حاضر از این دستور استفاده میکنم:
<!-- QueryToSerialize: LIST without id "[[" + file.name + "|" + title + "]]" WHERE draft = false AND parent = [[نرمافزار ابسیدین]] SORT order ASC -->
در نسخه های قبلی کوارتز امکان غیرفعال کردن کامنت برای هر صفحه وجود نداشت. من از ترفند زیر برای غیرفعال سازی صفحات دلخواه استفاده میکردم:
<style> .giscus { display: none; }</style>
در آپدیت جدید این امکان اضافه شده. کافیست یک پراپرتی با عنوان comments بسازید و از بخش property type حالت آن را روی checkbox بگذارید. حالا با کلیک روی چک باکس میتوانید کامنت را فعال یا غیر فعال کنید.
البته چون من کدهای سایت را دستکاری کردم نتوانستم از این آپدیت استفاده کنم. اما با اضافه کردن این کد به فایل زیر توانستم از این قابلیت استفاده کنم:
quartz\components\Comments.ts
export default ((opts: Options): QuartzComponentConstructor<Options> => { const Comments: QuartzComponent = ({ displayClass, fileData, cfg }: QuartzComponentProps) => { // بررسی وجود comments در فراداده و غیرفعال کردن کامنتها در صورت نیاز const disableComment: boolean = typeof fileData.frontmatter?.comments !== "undefined" && (!fileData.frontmatter?.comments || fileData.frontmatter?.comments === "false") if (disableComment) { return <></> }
۱۰. اسکرول به بالا و صفحه تصادفی
یک مورد جذاب هم در فوتر quartz.eilleeenz.com دیدم که با کلیک کردن روی Random Page یک صفحه تصادفی به کاربر نمایش میدهد. یک دکمه اسکرول به بالا هم دارد. اخیرا این دو مورد رو به صورت دکمه شناور گوشه پایین سایت قرار داده. از اینجا می توانید توضیحات خودش را مشاهده کنید. اما خلاصه میگویم که من چه طور آن را اضافه کردم.
البته روش من چندان اصولی نیست و فقط یک ترفند سریع برای استفاده از این روش است. در اصل باید برای هرکدام یک کامپوننت با استایل مجزا بسازید. همانطوری که در سایت eilleeenz انجام شده.
۱۱. مشکل تنظیم slug
تنها مشکل من با کوارتز این است که نمی توانم slug را تنظیم کنم. در حالت عادی اسلاگ بر اساس اسم فایل انتخاب می شود. من قبلا از hugo استفاده میکردم و خیلی راحت با اضافه کردن پراپرتی slug می توانستم url مشخصی را وارد کنم اما اینجا امکانش وجود ندارد.
تنظیم اسلاگ بر اساس عنوان فایل روش بهینه ای نیست. چون عنوان یادداشت های من فارسی است و فارسی بودن اسلاگ باعث می شود هنگام اشتراک گذاری با یک لینک بلند حاوی علائمی چون عدد و درصد مواجه شوم.
علاوه بر این من مدام یادداشتها را آپدیت میکنم و ممکن است عنوان فایل را هم دستکاری کنم. با اینکار اسلاگ هم تغییر میکند و لینکهای قبلی که به اشتراک گذاشتم کار نمیکنند. همچنین صفحاتی که در گوگل ایندکس شدند نیز با مشکل مواجه میشوند. پس من نیاز دارم از یک اسلاگ ثابت و انگلیسی استفاده کنم که متاسفانه کوارتز در حالت عادی امکان آن را فراهم نکرده است و من مجبورم از روش پیچیده تری استفاده کنم. یعنی اسم فایل را انگلیسی وارد میکنم تا اسلاگ انگلیسی باشد. از پراپرتی title هم برای اضافه کردن عنوان فارسی به یادداشت استفاده میکنم. با این ترفند می توانم اسلاگ و عنوان یادداشت را جداگانه مدیریت کنم.
من از پوشه ها هم استفاده نمی کنم و بخش اکسپلور را از سایدبار مخفی کردم. چون مسیر پوشهها در اسلاگ نیز وارد می شود که هم باعث طولانی شدن اسلاگ می شود هم با تغییر و جابهجایی فولدرها، اسلاگ نیز تغییر میکند و همان مشکل از کار افتادن لینکهای قبلی به وجود میآید.
مطمئنا راه حلی برای این مشکل وجود دارد اما هنوز روش ساده و راحتی پیدا نکردم. اینجا هم در مورد این مشکل صحبت شده بود که ظاهرا راه حل آن چندان مناسب نیست.
Footnotes
یکی از مشکلات محاسبه اشتباه مدت زمان تقریبی مطالعه بود که مقداری بیشتر از حالت معمولی آن را تخمین میزد. ظاهرا به خاطر زیاد بودن کلمات ربط در زبان فارسی نسبت به انگلیسی این اتفاق می افتد. مشکل دیگر تفاوت سرعت خواندن هرکس با یکدیگر است مضافا اینکه با توجه به دانش و سطح اطلاعات هر کس مدت زمان مطالعه نیز کم و زیاد می شود. به همین خاطر فکر میکنم نمایش مدت مطالعه یک فیلد اضافی است و کاربرد جدی ندارد. ↩
یک مورد به خاطر صفحه بندی خاصی است که برای موبایل در نظر گرفتم. من در فایل quartz.layout.ts فهرست مطالب را در حالت موبایل قبل از متن بدنه و بعد از ContentMeta قرار دادم. اگر به صورت دستی تصویر را اضافه می کردم فهرست مطالب قبل از تصویر نمایش داده میشد که جالب نبود. در حال حاضر تصویر در بخش ContentMeta قرار گرفته. یک مورد دیگر هم به خاطر شیوه خاصی است که برای صفحات فهرست در نظر گرفتم. با استفاده از پلاگین دیتاویو سریالیزر یک فهرست درست کردم که عنوان و تصویر یادداشت های مرتبط را نمایش می دهد. برای اینکار لازم بود از یک پراپرتی برای استخراج تصاویر استفاده کنم. ↩