Quill.js - ادیتوری پیشرفته برای سایت شما

Quill.js: An Advanced editor for your site

Quill.js - ادیتوری پیشرفته برای سایت شما

Quill معروفترین ادیتور WYSIWYG

در سال های اخیر ادیتورهای WYSIWYG توجه زیادی را به خود جلب کرده اند، مخصوصا در حوزه وبلاگ نویسی و تولید محتوا. عبارت WYSIWYG مخفف What You See Is What You Get و به معنی «چیزی که می بینی همان چیزی است که دریافت خواهی کرد» می باشد. این ادیتورها به کاربران و خود شما اجازه می دهند برای نوشتن مطالب در فضای وب (مثلا نوشتن یک پست) تجربه ای شبیه به Microsoft word را داشته باشید، یعنی یک طراحی و UI بسیار تمیز که به شما اجازه می دهد بدون نوشتن کد، متن ها را استایل دهی کنید.

در حال حاضر کتابخانه Quill با ۳۰ هزار ستاره در گیت هاب یکی از معروف ترین ادیتورهای  WYSIWYG به شمار می رود و قابلیت های بی نظیری را دارد. به همین دلیل تصمیم گرفته ام در این مقاله نحوه استفاده از آن را یاد بگیریم.

نصب Quill و راه اندازی پروژه با Vite

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

من شخصا Vite را ترجیح می دهم بنابراین از آن استفاده می کنم. ابتدا به پوشه ای که مورد نظر خودتان باشد بروید و ترمینال یا CMD خود را در آن باز کنید. حالا دستور زیر را اجرا کنید تا vite شروع به پکربندی کند:

npm init @vitejs/app

با اجرای این دستور از شما پرسیده می شود که باید پکیجی به نام create-vite-app نصب شود که شما باید y را نوشته و سپس enter بزنید تا این پکیج نصب شود. پس از تمام نصب از شما خواسته می شود نام پروژه (Project name) را انتخاب کنید. من نام quill-demo را تایپ کرده و enter می زنم. در مرحله بعدی از شما خواسته می شود که فریم ورک مورد نظرتان را انتخاب کنید (Select a framework) و من vanilla را انتخاب می کنم چرا که قصد استفاده از هیچ فریم ورکی را نداریم. در مرحله بعدی از شما خواسته می شود که نوع دقیق آن را مشخص کنید (Select a variant) که من گزینه vanilla-ts را انتخاب می کنم چرا که می خواهیم پروژه را با تایپ اسکریپت بنویسیم. با انجام این کار یک پوشه جدید به نام quill-demo برایتان ساخته شده و نتیجه زیر را در ترمینال می بینید:

✔ Project name: … quill-demo

✔ Select a framework: › vanilla

✔ Select a variant: › vanilla-ts




Scaffolding project in /media/amir/Development/Roxo Academy/quill-demo...




Done. Now run:




  cd quill-demo

  npm install

  npm run dev

حالا با cd quill-demo ترمینال را وارد پوشه quill-demo می کنیم و سپس دستور npm install را اجرا می کنیم تا وابستگی های vite (تایپ اسکریپت و خود vite) نصب شوند. پس از آن اگر npm run dev را در ترمینال خود اجرا کنید صفحه اول پروژه vite را می بینید که در آدرس  http://localhost:3000 در مرورگر باز می شود.

طبیعتا ما به این فایل ها نیازی نداریم بنابراین ابتدا وارد فایل index.html شده و محتوای آن را بدین شکل تغییر بدهید:

<!DOCTYPE html>

<html lang="en">




<head>

  <meta charset="UTF-8" />

  <link rel="icon" type="image/svg+xml" href="favicon.svg" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <title>Quill Demo</title>

</head>




<body>




  <header>

    <h1>A simple Quill demo</h1>

  </header>

  <main>

    <div>

      <div id="editor"></div>

    </div>

  </main>




  <script type="module" src="/src/main.ts"></script>

</body>




</html>

دقت داشته باشید که در این بخش یک div با آیدی editor تعریف کرده ام. بعدا به آن برمی گردیم.

در مرحله بعدی از پوشه src فایل main.ts را باز کرده و کد های آن را به غیر از کد های CSS پاک کنید تا محتوایش بدین شکل در بیاید:

import './style.css'

و در نهایت محتویات style.css را بدین شکل ویرایش کنید:

html {

  font-family: Avenir, Helvetica, Arial, sans-serif;

  -webkit-font-smoothing: antialiased;

  -moz-osx-font-smoothing: grayscale;

}




header {

  display: flex;

  justify-content: center;

  margin: 30px;

  font-size: 25px;

}




main {

  max-width: 900px;

  display: flex;

  flex-direction: column;

  margin: 0 auto;

}

اینها تنها چند استایل ساده برای شروع پروژه هستند. در مرحله بعدی quill را در این پروژه نصب می کنیم:

npm i quill

توجه داشته باشید که من برای استفاده از quill از npm استفاده کرده ام اما شما می توانید آن را به صورت تگ های ساده <script> نیز در صفحات HTML خود قرار بدهید. به طور مثال:

<!-- کتابخانه اصلی با امکانات استاندارد-->

<script src="//cdn.quilljs.com/1.3.6/quill.js"></script>

<script src="//cdn.quilljs.com/1.3.6/quill.min.js"></script>




<!-- فایل های استایل برای تم های مختلف -->

<link href="//cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">

<link href="//cdn.quilljs.com/1.3.6/quill.bubble.css" rel="stylesheet">




<!-- کتابخانه اصلی بدون هیچ تم و امکانات اضافی -->

<link href="//cdn.quilljs.com/1.3.6/quill.core.css" rel="stylesheet">

<script src="//cdn.quilljs.com/1.3.6/quill.core.js"></script>

اما من این کار را انجام نمی دهم بلکه از همان npm استفاده می کنم.

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

npm i -D @types/quill

پیکربندی اولیه Quill

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

در ابتدا باید یک نمونه از Quill را بسازیم بنابراین در فایل main.ts می گوییم:

import "./style.css";

import Quill from "quill";




const editor = new Quill("#editor");

این یک نمونه از Quill است که برای ما ساخته شده است. توجه داشته باشید که ما آیدی editor را به آن پاس داده ایم. این id یک div در فایل index.html ما است. در حال حاضر اگر به مرورگر بروید هیچ چیزی به جز header ما نخواهید دید. چرا؟ به دلیل اینکه نیاز به پیکربندی آن داریم. برای پیکربندی باید به فایل index.html برگردیم و کمی آن را ویرایش کنیم:

<!DOCTYPE html>

<html lang="en">




<head>

  <meta charset="UTF-8" />

  <link rel="icon" type="image/svg+xml" href="favicon.svg" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">

  <title>Quill Demo</title>

</head>




<body>




  <header>

    <h1>A simple Quill demo</h1>

  </header>

  <main>

    <div>

      <div id="editor"></div>

    </div>

  </main>




  <script type="module" src="/src/main.ts"></script>

</body>




</html>

همانطور که می بینید من یک تگ link را اضافه کرده ام که تم snow از quill را دانلود می کند. شما برای استفاده از quill حداقل به یک تم ساده نیاز دارید و تم پیش فرض همان snow است که از نظر ظاهری نیز زیبا می باشد.

در مرحله بعدی به فایل main.ts می رویم. ما تا این لحظه Quill را صدا زده ایم و سپس آیدی editor را به صورت یک رشته به آن پاس داده ایم. جالب است بدانید که Quill تنظیمات زیادی را برای پیکربندی نیز دارد و برای استفاده از آن باید یک شیء حاوی این تنظیمات را به عنوان آرگومان دوم به Quill پاس بدهید:

const quillOptions = {

  placeholder: "Write something here",

  theme: "snow",

};




const editor = new Quill("#editor", quillOptions);

تنها گزینه ای که واقعا در این بخش برای ما اجباری است، گزینه theme است چرا که تا تم quill مشخص نشود، چیزی در مرورگر شما به درستی نمایش داده نخواهد شد. گزینه دیگری که من به عنوان تنظیمات پاس داده ام یک placeholder است، یعنی متنی که به صورت کمرنگ تر درون ادیتور نمایش داده می شود و توضیحی ساده را به کاربر می دهد. به طور مثال من در این بخش رشته Write something here را نوشته ام (به معنی «چیزی را در این قسمت بنویسید») اما شما می توانید هر مقدار دیگری را در آن بنویسید.

در حال حاضر با نوشتن این کد متوجه خالی بودن toolbar یا نوار ابزار بالای ادیتور می شوید. Quill برای پُر کردن آن، ابزار جالبی دارد. ساده ترین راه آن بدین شکل است که یک آرایه را تعریف کرده و تمام ابزار های مورد نظر خودتان را در آن بنویسید. من این کار را در main.ts انجام می دهم:

import "./style.css";

import Quill from "quill";

import { QuillOptionsStatic } from "quill";




const toolbarOptions = [

  [

    { size: ["small", false, "large", "huge"] },

    { header: [1, 2, 3, 4, 5, 6, false] },

  ],

  ["bold", "italic", "underline", "strike"],

  ["link", "image", "video"],




  ["blockquote", "code-block"],

  [{ list: "ordered" }, { list: "bullet" }],

  [{ script: "sub" }, { script: "super" }],

  [{ indent: "-1" }, { indent: "+1" }],

  [{ direction: "rtl" }],




  [{ color: [] }, { background: [] }],

  [{ font: [] }],

  [{ align: [] }],




  ["clean"],

];




const quillOptions = {

  modules: {

    toolbar: toolbarOptions,

  },

  placeholder: "Write something here",

  theme: "snow",

} as QuillOptionsStatic;




const editor = new Quill("#editor", quillOptions);

من در ابتدا تایپی به نام QuillOptionsStatic را وارد کرده ام تا شیء  quillOptions را روی همین تایپ تنظیم کنم. این کار سلیقه ای است و به شما در توسعه کمک می کند (گزینه ها برایتان نمایش داده می شوند) اما اجباری نیست. Quill ماژول های مختلفی را دارد که نوار ابزار یا همان toolbar یکی از آن ها است. برای تعریف کردن نوار ابزار باید ابتدا شیء modules را در تنظیمات پیکربندی quill تعریف کرده و سپس نوار ابزار را به آن پاس بدهید. در مرحله بعدی باید آرایه ای از ابزار های مورد نظرتان را به آن پاس بدهید تا در مرورگر نمایش داده شوند.

من این آرایه را در متغیر toolbarOptions ذخیره کرده ام. در نظر داشته باشید که ترتیب آرایه های درون toolbarOptions برابر با ترتیب نمایش این ابزار ها در نوار ابزار است. اولین آرایه برای تعیین اندازه نوشته ها است که size نام دارد. من مقادیر زیر را به آن پاس داده ام:

  • small: اندازه نوشته ها کوچک باشد.
  • false: اندازه نوشته ها متوسط باشد. توجه کنید که medium نداریم، بلکه باید false را پاس بدهید. هر زمانی که یک مقدار را روی false تنظیم کنید یعنی آن استایل خاص باید حذف شود و در نتیجه آن استایل خاص به حالت «عادی» برمی گردد که همان حالت بدون استایل است.
  • large: اندازه نوشته ها بزرگ باشد.
  • huge: اندازه نوشته ها بسیار بزرگ باشد.

شاید بپرسید از کجا باید بدانیم که چنین گزینه هایی در Quill وجود دارد؟ برای آشنایی با این گزینه ها باید به وب سایت رسمی Quill مراجعه نمایید.

در آرایه بعدی header ها را داریم که همان تگ های h1 تا h6 هستند. در صورتی که می خواهید فقط تگ های h1 تا h3 را داشته باشید می توانید به جای پاس دادن تمام این اعداد، فقط اعداد ۱ تا ۳ را پاس بدهید. حتما تا الان فهمیده اید که Quill قابلیت ویرایش بسیار بالایی دارد.

آرایه بعدی مربوط به حالت های متن است که مقادیر bold (توپُر) و italic (مورب) و غیره را پاس داده ایم. سپس یک آرایه برای الصاق تصاویر (image) و اضافه کردن لینک به متون (link) و جاسازی یک ویدیو (video) را داریم. آرایه های بعدی نیز انواع و اقسام ابزار های دیگر هستند. شما می توانید با باز کردن مرورگر خود و بازی با این ابزار ها، استفاده از هر کدام را یاد بگیرید. من برخی از آرایه ها مانند color را خالی گذاشته ام چرا که تم snow به صورت خودکار آن را پُر می کند اما اگر شما دوست داشتید رنگ های خاصی را مشخص کنید می توانید آن ها را در همین آرایه بنویسید. آخرین آرایه نیز clean نام دارد که مسئول حذف کرده استایل های اعمال شده است.

از آنجایی که فایل اصلی ما در حال حاضر بیش از حد شلوغ شده است من در پوشه src یک فایل دیگری به نام constants.ts را ایجاد می کنم و آرایه ابزار ها و تنظیمات پیکربندی را به آن منتقل می کنم:

import { QuillOptionsStatic } from "quill";




const toolbarOptions = [

  [

    { size: ["small", false, "large", "huge"] },

    { header: [1, 2, 3, 4, 5, 6, false] },

  ],

  ["bold", "italic", "underline", "strike"],

  ["link", "image", "video"],




  ["blockquote", "code-block"],

  [{ list: "ordered" }, { list: "bullet" }],

  [{ script: "sub" }, { script: "super" }],

  [{ indent: "-1" }, { indent: "+1" }],

  [{ direction: "rtl" }],




  [{ color: [] }, { background: [] }],

  [{ font: [] }],

  [{ align: [] }],




  ["clean"],

];




export const quillOptions = {

  modules: {

    toolbar: toolbarOptions,

  },

  placeholder: "Write something here",

  theme: "snow",

} as QuillOptionsStatic;

حالا به فایل main.ts برمی گردیم و شیء پیکربندی را import می کنیم:

import "./style.css";

import Quill from "quill";

import { quillOptions } from "./constants";




const editor = new Quill("#editor", quillOptions);

همانطور که می بینید حالا فایل main.ts بسیار تمیز تر شده است.

سایز پیش فرض ادیتور

در حال حاضر فضای نوشتاری در ادیتور ما بسیار کوچک است (یک خط):

کوچک بودن بیش از حد ادیتور
کوچک بودن بیش از حد ادیتور

اما بهتر است یک سایز پیش فرض را برایش در نظر بگیریم. برای این کار می توانیم height یا ارتفاع div مورد نظر را تعیین کنیم. ابتدا به فایل style.css رفته و سپس استایل زیر را به آن اضافه کنید:

#editor {

  height: 400px;

}

با انجام این کار ارتفاع ادیتور شما ثابت می ماند که ظاهری بسیار زیبا تر از حالت قبل است.

راست چین کردن Quill

اگر بخواهیم با زبان فارسی کار کنیم طبیعتا باید نوشته ها از راست به چپ نوشته شوند. در حال حاضر در نوار ابزار گزینه ای برای RTL (راست به چپ) کردن متون وجود دارد اما من می خواهم ادیتور به صورت پیش فرض RTL باشد و نیازی به کلیک روی دکمه خاصی نداشته باشیم. برای حل این مشکل خصوصیتی به نام format روی ادیتور اصلی وجود دارد که با استفاده از آن می توانیم این کار را انجام بدهیم:

import "./style.css";

import Quill from "quill";

import { quillOptions } from "./constants";




const editor = new Quill("#editor", quillOptions);

editor.format("direction", "rtl");

editor.format("align", "right");

این روشی است که به طور معمول در فضای وب مشاهده خواهید کرد اما این روش مشکل کوچکی دارد. با اینکه این کار باعث راست نویس شدن ادیتور می شود اما placeholder باز هم در سمت چپ باقی می ماند که باعث زشت شدن ظاهر ادیتور می شود. خوشبختانه راه حل بهتری نیز وجود دارد.

اگر یادتان باشد ما یک div با آیدی editor را در صفحه HTML خود ساخته بودیم و به شما توضیح دادم که Quill این آیدی را هدف گرفته و خود را در آن تزریق می کند. یکی از کار های دیگری که quill انجام می دهد، اضافه کردن یک کلاس به نام ql-editor به همان div است بنابراین ما می توانیم آن کلاس را با CSS هدف گرفته و همه چیز را راست چین کنیم. برای این کار به فایل style.css رفته و می گوییم:

#editor .ql-editor {

  height: 400px;

  direction: rtl;

  text-align: right;

}

با این کار همه چیز به طور صحیح راست چین می شود. برای اثبات این موضوع به فایل constants.ts رفته و متن placeholder را روی یک متن فارسی می گذاریم:

export const quillOptions = {

  modules: {

    toolbar: toolbarOptions,

  },

  placeholder: "متن خود را در این بخش بنویسید...",

  theme: "snow",

} as QuillOptionsStatic;

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

اضافه کردن placeholder به زبان فارسی و راست چین کردن آن
اضافه کردن placeholder به زبان فارسی و راست چین کردن آن

البته در نظر داشته باشید که هنوز هم باید از متد های editor.format استفاده کنیم، در غیر این صورت رفتار های عجیبی از سمت quill مشاهده می کنید (مثلا لیست ها بهم خواهند ریخت و الی آخر).

ثبت محتویات Quill به سرور

از آنجایی که ثبت نوشته های کاربر در Quill بستگی به سرور شما و زبان آن دارد من نمی توانیم یک راهکار را برای تمام افراد ارائه بدهم اما می خواهم شما را با ساختار داده های ثبت شده آشنا کنم. بیایید در ابتدا به فایل index.html رفته و یک دکمه را به آن اضافه کنیم:

<!DOCTYPE html>

<html lang="en">




<head>

  <meta charset="UTF-8" />

  <link rel="icon" type="image/svg+xml" href="favicon.svg" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">

  <title>Quill Demo</title>

</head>




<body>




  <header>

    <h1>A simple Quill demo</h1>

  </header>

  <main>

    <form>

      <div id="editor"></div>

      <input name="my-form-content" type="hidden">

      <button id="editor-submit" type="submit">Submit the data</button>

    </form>

  </main>




  <script type="module" src="/src/main.ts"></script>

</body>




</html>

همانطور که می بینید یک دکمه ساده از نوع submit را در این بخش تعریف کرده ام و آیدی خاصی را نیز به آن داده ام. البته مهم ترین تغییر این بوده است که div اصلی را به یک <form> تغییر داده ام. همچنین یک input مخفی با name دلخواه خودم (my-form-content) را نیز در این فرم قرار داده ام که بعدا از آن استفاده خواهیم کرد.

حالا به فایل style.css رفته و می گوییم:

#editor-submit {

  margin: 10px;

  padding: 5px;

  float: right;

}

من با این کار فقط ظاهر دکمه را کمی تصحیح کرده ام تا به ادیتور نچسبد.

حالا به فایل main.ts رفته چنین کدی را می نویسیم:

import "./style.css";

import Quill from "quill";

import { quillOptions } from "./constants";




const editor = new Quill("#editor", quillOptions);

editor.format("direction", "rtl");

editor.format("align", "right");




const form = document.querySelector("form") as HTMLFormElement;




form.onsubmit = () => {




  const hiddenInput = document.querySelector(

    "input[name=my-form-content]"

  ) as HTMLInputElement;




  // می ریزیم input داده های درون ادیتور خودمان را درون یک

  hiddenInput.value = JSON.stringify(editor.getContents());




  console.log(editor.getContents());




  // را برمی گردانیم false هیچ سروری برای دریافت این داده ها وجود ندارد بنابراین

  return false;

};

همانطور که می بینید ابتدا input مخفی را گرفته ام و سپس محتوای فرم خودم را درون آن قرار داده ام، البته به صورت JSON.stringify شده تا سرور بتواند آن را دریافت کند. حالا در سمت سرور می توانیم هر کاری را که خواستیم با این داده ها انجام بدهیم. من در این پروژه سروری ندارم بنابراین فقط داده ها را log کرده ام (متد getContents محتوای درون ادیتور را می گیرد). این داده ها را باید در سمت سرور parse کرده و سپس از آن ها به سلیقه خودتان استفاده کنید.

البته می توانید مستقیما محتوای درون div با کلاس ql-editor را نیز دریافت کنید. همه چیز بستگی به سلیقه خودتان دارد.


منبع: وب سایت quilljs

نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.