آموزش ساخت بلوک های ویرایشگر بلوک، قسمت 3


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

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


اگر به طور تصادفی با این مجموعه برخورد می کنید و این اولین پستی است که می خوانید یا هنوز هیچ یک از کارهای قبلی را انجام نداده اید (چون من یک مخزن GitHub برای این کار تنظیم نکرده ام پلاگین هنوز – و این به عمد است 🙂)، در اینجا آنچه تاکنون پوشش داده شده است:

  1. ابزارهای مورد نیاز، ساختار پلاگین، وابستگی ها، بلوک فراداده
  2. The Backend، The Frontend، عملکرد، سبک ها، نسخه ی نمایشی کاری

در مقاله قبلی عرض کردم:

در مقاله بعدی، صحبت در مورد اینکه چگونه می‌توانیم متن را در متن Block Editor ویرایش کنیم، چگونه تغییرات را ذخیره کنیم و سپس آنها را در قسمت جلویی مشاهده کنیم، صحبت خواهیم کرد.

در ابتدا، من قصد داشتم موارد زیر را در یک مقاله پوشش دهم:

  • عنصر موجود در ویرایشگر بلوک را به فیلدی که می توانیم ویرایش کنیم، تبدیل کنیم،
  • ذخیره محتوای فیلد،
  • محتوای بالا را ارائه دهید

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

Block Editor Blocks: محتوای قابل ویرایش

از مقاله قبلی به یاد بیاورید، کار با بلوک ها در ویرایشگر Block معمولاً از دو عملکرد تشکیل شده است:

  1. ویرایش کنید
  2. صرفه جویی

و اگرچه این مقاله در درجه اول مربوط به اجازه دادن به ما برای ویرایش محتوا در ویرایشگر Block است، مهم است که به یاد داشته باشید که نام توابع بیش از حد بارگذاری شده است.

به این معنا که، edit را می توان به عنوان تابعی در نظر گرفت که در آن کد مسئول دستکاری داده ها است و بس (که آنقدرها هم بد نیست). با این حال، save مسئولیت بسیار بیشتری دارد

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

💭 درک ویژگی های بلوک

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

از کتاب راهنما:

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

Block Attributes

من شخصاً، ای کاش این موضوع کمی بیشتر در کتاب راهنما گنجانده شده بود، اما هر کاری که بتوانم برای گسترش آن در اینجا انجام خواهم داد.

ابتدا توجه به این نکته ضروری است attributes به منتقل می شوند registerBlockType عملکرد.

ثانیاً، آنها دومین آرگومان ارسال شده (پس از نام بلوک) هستند و یک شی JSON – یا به طور کلی، یک ساختار داده – هستند که مشخص می کند چه محتوایی قرار است ذخیره شود و چگونه می توان آن را خواند.

سوم، JSON به گونه ای ساخته شده است که attributes گره دارای عناصر فرزند است که در آن هر فرزند نشان دهنده محتوایی است که باید ذخیره شود. به عنوان مثال، فرض کنید که ما یک content رشته سپس، ساختار داده شروع به شکل زیر می کند:

attributes: {
  content: {
  }
}

و در مورد ما، ما قصد داریم با رشته ای کار کنیم که در یک قرار دارد input عنصر (که بعداً در این مقاله به آن خواهم پرداخت). بنابراین ساختار می تواند چیزی شبیه به این باشد:

attributes: {
  content: {
    type: 'string',
    source: 'text',
    selector: 'input',
  }
}

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

💭 چگونه این ویژگی ها را تنظیم کنیم؟

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

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

Block API

اینجاست که setAttributes تابع وارد عمل می شود. به اختصار، setAttributes یک تابع ارائه شده توسط وردپرس است که به ما اجازه می دهد تا آن را ذخیره کنیم attributes ساختار داده هر زمان که محتوای یک بلوک را ویرایش می کنیم.

نکته اصلی در حال حاضر این است که هر دو attributes ساختار و ارجاع به setAttributes تابع باید به آنها منتقل شود edit عملکرد.

برای مثال، اکنون امضای تابع چیزی شبیه به این خواهد بود:

edit: ({ attributes, setAttributes }) => {
  // ...
}

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

⌨️ تبدیل یک عنصر به محتوای قابل ویرایش

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

به یاد بیاورید از مقالات قبلی که ما edit تابع در حال حاضر به شکل زیر است:

edit: () => {
    return (
        "This is content from the editor."
    );
},

ما باید این را به سه روش به روز کنیم:

  1. اضافه کردن پشتیبانی از ویژگی ها،
  2. به روز رسانی تابع برای کار با آن ویژگی ها،
  3. از یک کنترل موجود برای ویرایش متن استفاده کنید.

در اینجا نحوه انجام همه موارد بالا آمده است.

ویژگی های

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

registerBlockType(name, {
    attributes: {
        content: {
            type: 'string',
            source: 'text',
            selector: 'input'
        },
    },

در اینجا توجه داشته باشید که selector نوع مورد استفاده ما یک است input. این مربوط به نوع کنترلی است که بعداً از آن استفاده خواهیم کرد.

با این حال، برای وضوح، بدانید که ما کنترلی را در درون خود اعمال خواهیم کرد div عنصری به گونه ای که کاربر بتواند محتوای آن را ویرایش کند. و از آنجایی که همه چیز در نهایت به HTML خلاصه می شود، این قابلیت ویژه قابل ویرایش توسط یک ارائه می شود input عنصر

عملکرد را به روز کنید

بعد، ما باید به روز رسانی کنیم edit عملکرد به گونه ای است که می پذیرد attributes و اشاره به setAttribute عملکرد. برای انجام این کار، تابع را طوری تنظیم می کنیم که شبیه آنچه در بالا بحث کردیم به نظر برسد.

edit: ({ attributes, setAttributes }) => {
    const blockProps = useBlockProps({
        className: 'tm-block-demo-container'
    });
    return (
        <div {...blockProps}>
          <!-- TODO -->        
        </div>
    );
},

بقیه عملکردها در مرحله بعدی تکمیل می شوند. البته توجه داشته باشید که اصول عملکرد تغییر نکرده است:

  • ما هنوز از a استفاده می کنیم div عنصر به عنوان ظرف اصلی ما،
  • ما در حال اعمال آن هستیم blockProps به div به طوری که ما کنترل آن را در ویرایشگر Block داریم.

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

محتوای قابل ویرایش

اولین قدم برای اطمینان از اینکه محتوای ما قابل ویرایش است، اضافه کردن کنترلی است که به ما امکان می دهد واقعاً محتوا را ویرایش کنیم. در HTML استاندارد، این چیزی شبیه به یک است input یا الف textareو سپس با استفاده از یک قلاب وردپرس و فراخوانی API موجود در سمت سرور اعتبارسنجی، ضدعفونی و سریال سازی می کنیم.

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

اما این یک سوال را ایجاد می کند: وردپرس چه کنترل یا مؤلفه ای را ارائه می دهد که به ما امکان می دهد عناصر را وارد کنیم؟

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

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

با توجه به کتاب راهنما، ما باید از آن استفاده کنیم @wordpress/components بسته برای گرفتن کامپوننت که پس از آن موارد زیر را به بالای صفحه خود اضافه می کنیم index.js فایلی که به شکل زیر باشد:

import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
import { TextControl } from '@wordpress/components';

import metadata from './block.json';
const { name } = metadata;

import './index.scss';

سپس، به پایین می آییم edit تابع و با اضافه کردن موارد زیر آن را تکمیل کنید:

edit: ({ attributes, setAttributes }) => {
    const blockProps = useBlockProps({
        className: 'tm-block-demo-container'
    });
    return (
        <div {...blockProps}>
            <TextControl
                placeholder="This is content from the editor."
                className="tm-block-demo-input"
                value={attributes.content}
                onChange={(value) => setAttributes({ content: value })}
            />
        </div>
    );
},

نکات کلیدی که در اینجا باید به آنها توجه کرد موارد زیر است:

  • این placeholder ویژگی همان متنی است که در ابتدا در اولین تکرار افزونه نشان می دادیم. این مقدار در قسمت جلویی نمایش داده نمی‌شود، اما در این سری از مقاله‌ها نشان داده می‌شود و ما حرکت از داده‌های استاتیک به داده‌های پویا را آغاز می‌کنیم.
  • این value ویژگی را می خواند content دارایی از attributes ساختار داده و در صورت تنظیم، آن را در فیلد قرار می دهد. علاوه بر این، از آنجایی که این یک است TextControl، اینجاست که کاربر می تواند اطلاعات خود را برای رندر در فرانت اند وارد کند.
  • این onChange ویژگی تابعی است که محتویات را می پذیرد value ویژگی، به content دارایی از attributes ساختار داده و سپس ارسال که به setAttributes به داده ها می تواند [eventually] نجات یابد.

وقتی می دوی npm run build در ترمینال و سپس بلوک را به Block Editor اضافه کنید، باید چیزی شبیه به این ببینید:

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

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

🎨 سبک دادن به بلوک

اگر می‌پرسید چگونه باید به نظر برسد، دو چیز وجود دارد که به راحتی ما را راهنمایی می‌کند:

  1. شیوه نامه موجود،
  2. نحوه ظاهر بلوک در قسمت جلویی (زیرا ما هنوز چیزی را که در قسمت توسعه داده ایم ارائه نکرده ایم edit عملکرد)

به خاطر آوردن:

و سپس اگر به موجود نگاه کنید index.scss، موارد زیر را مشاهده خواهید کرد:

.tm-block-demo-container,
.tm-block-demo-container,
.wp-block-tm-tm-block-demo {
    color: #fff;
    background: #0d63fd;
    border: 1px solid #0a58ca;
    font-weight: bold;
    padding: 0.5em;
    width: 100%;
}

اصل کاری که باید انجام دهیم این است که به روز رسانی کنیم input سبک های عنصر به طوری که به نظر می رسد بخشی از آن است div عنصری که در ابتدا در آن داشتیم edit عملکرد. برای این کار می توانید از ابزارهای توسعه دهنده در مرورگر دلخواه خود استفاده کنید.

در نهایت، شما باید به چیزی شبیه به این پایان دهید:

.tm-block-demo-container,
.wp-block-tm-tm-block-demo {
    color: #fff;
    background: #0d63fd;
    border: 1px solid #0a58ca;
    font-weight: bold;
    padding: 0.5em;
    width: 100%;
}

.tm-block-demo-input input,
.tm-block-demo-input input:focus {
    border: none !important;
    background: #0d63fd;
    color: white;
}

حالا اجرا کنید npm run build و مرورگر را رفرش کنید. موارد زیر را خواهید دید:

  • فونت متفاوت به نظر می رسد،
  • را placeholder متفاوت دارد،
  • با تمرکز بر input عنصر حاشیه کمی را نشان می دهد

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

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

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

⏭️ TODO

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

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

به طور خاص، ما قصد داریم به این موارد بپردازیم:

  • چگونه محتوا را ذخیره کنیم،
  • آن را در قسمت جلویی رندر کنید

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

📚 مرجع


– تهیه و ترجمه توسط wordpress-templates.ir

سفارش طراحی سایت به وی تی!