وردپرس‌کالاوردپرس رو ساده‌تر توسعه بده
عضویت VIP

ساخت بلاک سفارشی وردپرس با block.json و Interactivity API (آموزش کامل وردپرس ۷)

سه روش رسمی ساخت بلاک سفارشی در وردپرس ۷ را با یک پروژه‌ی واقعی یاد بگیرید: بلاک اعلان فقط با PHP، بلاک آکاردئون داینامیک با create-block و block.json، و تعاملی کردن آن با Interactivity API. همراه با ترجمه‌ی فارسی، استایل راست‌چین و خطاهای رایج.

ساخت بلاک سفارشی وردپرس با block.json و Interactivity API در وردپرس ۷

ساخت بلاک سفارشی وردپرس در سال ۱۴۰۵ سه مسیر رسمی دارد: بلاک فقط با PHP که وردپرس ۷ اضافه کرده، بلاک استاندارد با فایل block.json و ابزار create-block، و بلاک تعاملی با Interactivity API برای رفتارهای سمت کاربر. این آموزش هر سه را با یک پروژه‌ی واقعی نشان می‌دهد: یک بلاک اعلان بدون جاوااسکریپت، و یک بلاک آکاردئون کامل با ویرایش غنی در ادیتور و باز و بسته شدن در سایت. کدها روی وردپرس ۷.۰ و ۷.۱ تست شده‌اند و برای نسخه‌های قدیمی‌تر هم مسیر جایگزین گفته شده است.

آنچه در این آموزش یاد می‌گیرید

  • تفاوت سه روش ساخت بلاک و اینکه برای هر کار کدام را انتخاب کنید

  • ساخت بلاک فقط با PHP در وردپرس ۷ با 'autoRegister' => true و کنترل‌های خودکار سایدبار

  • راه‌اندازی پروژه با @wordpress/create-block و فهم تک‌تک فیلدهای block.json

  • نوشتن edit.js با RichText و InspectorControls و render.php برای خروجی داینامیک

  • تعاملی کردن بلاک با Interactivity API: دایرکتیوها، context، state و store

  • ثبت همه‌ی بلاک‌ها با یک فراخوانی در وردپرس ۶.۸ به بعد و پشتیبانی از نسخه‌های قدیمی‌تر

  • ترجمه‌ی فارسی، استایل راست‌چین، خطاهای رایج و تغییرات وردپرس ۷ در این حوزه

سه روش ساخت بلاک در وردپرس ۷

تا پیش از وردپرس ۷ برای هر بلاک حتماً به جاوااسکریپت، Node و فرآیند بیلد نیاز داشتید. وردپرس ۷.۰ مسیر سومی باز کرد که بلاک‌های ساده را فقط با PHP می‌سازد. در عین حال block.json همچنان ستون فقرات هر بلاک جدی است و Interactivity API راه رسمی اضافه کردن رفتار در سمت کاربر است. این سه مسیر رقیب هم نیستند؛ یک افزونه می‌تواند بلاک‌هایی از هر سه نوع داشته باشد.

مقایسه سه روش ساخت بلاک وردپرس: فقط PHP، استاندارد با block.json و تعاملی با Interactivity API

سه مسیر رسمی ساخت بلاک. انتخاب به این بستگی دارد که در ادیتور چه تجربه‌ای می‌خواهید و در سایت چه رفتاری.

معیار

فقط PHP (وردپرس ۷)

استاندارد با block.json

تعاملی با Interactivity API

نیاز به Node و بیلد

ندارد

دارد

دارد

ویرایش در ادیتور

فرم خودکار در سایدبار

هر چیزی که بسازید (RichText، رسانه، رنگ)

همان بلاک استاندارد

بلاک تودرتو (InnerBlocks)

ندارد

دارد

دارد

رفتار در سایت

فقط HTML و CSS

HTML و CSS، جاوااسکریپت دستی

استیت، رویداد و به‌روزرسانی خودکار DOM

حداقل نسخه

۷.۰

۶.۱ برای render و ۶.۷ برای مانیفست

۶.۵

مناسب برای

اعلان، جعبه‌ی نویسنده، بنر، آمار

کارت محصول، نظر مشتری، جدول قیمت

آکاردئون، تب، فیلتر زنده، اسلایدر

پیش‌نیازها

  • وردپرس ۷.۰ یا بالاتر برای بلاک فقط PHP. بلاک استاندارد و تعاملی روی ۶.۵ به بعد هم کار می‌کنند.

  • PHP ۷.۴ به بالا. وردپرس ۷ پشتیبانی از نسخه‌های قدیمی‌تر را کنار گذاشته است.

  • Node نسخه‌ی ۲۲.۱۳ یا بالاتر و npm برای create-block و wp-scripts. برای مسیر فقط PHP لازم نیست.

  • یک محیط لوکال. گزینه‌ی --wp-env در create-block یک وردپرس داکری کنار پروژه بالا می‌آورد. LocalWP و Studio هم انتخاب‌های خوبی هستند.

  • آشنایی اولیه با PHP. برای بخش‌های جاوااسکریپت کدها را خط‌به‌خط توضیح داده‌ایم و نیاز به تجربه‌ی React ندارید.

روش ۱: بلاک فقط با PHP در وردپرس ۷

این مسیر برای کسانی است که PHP بلدند و نمی‌خواهند درگیر Node و بیلد شوند. کل بلاک در یک فایل PHP تعریف می‌شود. وردپرس با دیدن 'autoRegister' => true در آرایه‌ی supports، خودش بلاک را در ادیتور ثبت می‌کند، برای هر ویژگی یک کنترل در سایدبار می‌سازد و پیش‌نمایش را با ServerSideRender از همان تابع رندر می‌گیرد. یعنی خروجی ادیتور و سایت دقیقاً یکی است.

<?php
/**
 * Plugin Name: بلاک اعلان وردپرس کالا (فقط PHP)
 * Requires at least: 7.0
 * Requires PHP: 7.4
 */

defined( 'ABSPATH' ) || exit;

add_action( 'init', function () {
	register_block_type( 'wpkala/notice', array(
		'api_version'     => 3,
		'title'           => 'اعلان وردپرس کالا',
		'description'     => 'یک پیام برجسته با سه سطح اهمیت.',
		'category'        => 'text',
		'icon'            => 'info',
		'attributes'      => array(
			'message'     => array(
				'type'    => 'string',
				'default' => 'این یک اعلان است.',
				'label'   => 'متن پیام',
			),
			'level'       => array(
				'type'    => 'string',
				'enum'    => array( 'info', 'warning', 'success' ),
				'default' => 'info',
				'label'   => 'سطح اهمیت',
			),
			'dismissible' => array(
				'type'    => 'boolean',
				'default' => false,
				'label'   => 'دکمه‌ی بستن داشته باشد',
			),
		),
		'supports'        => array(
			'autoRegister' => true, // همین یک خط بلاک را بدون جاوااسکریپت در ادیتور ثبت می‌کند
			'color'        => array( 'background' => true, 'text' => true ),
			'spacing'      => array( 'padding' => true ),
		),
		'render_callback' => 'wpkala_render_notice',
	) );
} );

function wpkala_render_notice( array $attributes ): string {
	$level   = sanitize_html_class( $attributes['level'] ?? 'info' );
	$wrapper = get_block_wrapper_attributes( array( 'class' => 'wpkala-notice is-' . $level ) );
	$close   = ! empty( $attributes['dismissible'] )
		? '<button type="button" class="wpkala-notice__close" aria-label="بستن">×</button>'
		: '';

	return sprintf(
		'<div %1$s><p>%2$s</p>%3$s</div>',
		$wrapper,
		esc_html( $attributes['message'] ?? '' ),
		$close
	);
}

این فایل را با نام wpkala-notice.php در پوشه‌ی افزونه‌ها بگذارید و فعال کنید. بلاک «اعلان وردپرس کالا» در دسته‌ی متن ظاهر می‌شود و سایدبار آن سه کنترل دارد: فیلد متنی برای پیام، فهرست کشویی برای سطح و یک کلید برای دکمه‌ی بستن.

نگاشت نوع ویژگی‌ها به کنترل‌های خودکار سایدبار در بلاک فقط PHP وردپرس ۷

نگاشت نوع ویژگی به کنترل خودکار. کلید label نام فیلد را تعیین می‌کند و بدون آن نام ویژگی نمایش داده می‌شود.

چه چیزهایی در این مسیر نیست

  • بلاک تودرتو ندارد، چون پیش‌نمایش با ServerSideRender ساخته می‌شود.

  • کنترل تصویر، فایل و متن غنی ندارد. فقط چهار نوع رشته، عدد، بولین و فهرست پشتیبانی می‌شود. ویژگی‌های آرایه و شیء بدون کنترل می‌مانند.

  • هر تغییر تنظیمات یک رفت‌وبرگشت به سرور است، پس پیش‌نمایش لحظه‌ای نیست.

  • نام ویژگی را style نگذارید؛ با پشتیبانی رنگ و فاصله تداخل می‌کند و خطای «Invalid parameter(s): attributes» می‌گیرید.

  • برای استایل، فایل CSS را با wp_register_style() ثبت کنید و هندل آن را در کلید style همان آرایه بدهید.

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

روش ۲: بلاک استاندارد با block.json و create-block

مسیر اصلی و آینده‌دار همین است. ابزار رسمی @wordpress/create-block یک افزونه‌ی کامل با پیکربندی بیلد می‌سازد و شما فقط روی سه فایل تمرکز می‌کنید: block.json، edit.js و render.php. بلاکی که این‌جا می‌سازیم یک آکاردئون است که در بخش بعد با Interactivity API تعاملی می‌شود.

قدم ۱: ساخت پروژه

# نسخه‌ی Node باید ۲۲.۱۳ یا بالاتر باشد
node -v

# ساخت افزونه با یک بلاک داینامیک
npx @wordpress/create-block@latest wpkala-blocks --variant dynamic --namespace wpkala --title "بلاک‌های وردپرس کالا"

cd wpkala-blocks
npm start     # حالت توسعه با بیلد خودکار
npm run build # خروجی نهایی در پوشه‌ی build
ساختار فایل‌های افزونه بلاک ساخته‌شده با create-block و گزینه dynamic

ساختار پروژه. وردپرس فقط پوشه‌ی build را می‌خواند و src محل کار شماست.

گزینه‌ی --variant dynamic به جای save.js فایل render.php می‌سازد. گزینه‌ی --namespace پیشوند نام بلاک است و باید در همه‌ی بلاک‌های شما یکی باشد تا با بلاک‌های دیگران تداخل نکند.

تفاوت بلاک استاتیک با save.js و بلاک داینامیک با render.php در وردپرس

بلاک استاتیک HTML را موقع ذخیره در دیتابیس می‌نویسد؛ بلاک داینامیک آن را هر بار از PHP می‌سازد.

قدم ۲: block.json، شناسنامه‌ی بلاک

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

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "wpkala/accordion",
	"version": "1.0.0",
	"title": "آکاردئون",
	"category": "widgets",
	"icon": "list-view",
	"description": "عنوان و متنی که با کلیک باز و بسته می‌شود.",
	"keywords": [ "accordion", "toggle", "آکاردئون", "سوال" ],
	"textdomain": "wpkala-blocks",
	"attributes": {
		"heading": { "type": "string", "default": "" },
		"body": { "type": "string", "default": "" },
		"open": { "type": "boolean", "default": false }
	},
	"supports": {
		"html": false,
		"anchor": true,
		"interactivity": true,
		"color": { "background": true, "text": true },
		"spacing": { "padding": true, "margin": true }
	},
	"example": {
		"attributes": { "heading": "چطور سفارش بدهم؟", "body": "محصول را به سبد اضافه کنید و مراحل پرداخت را دنبال کنید." }
	},
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css",
	"render": "file:./render.php",
	"viewScriptModule": "file:./view.js"
}

فیلد

کار

نکته

apiVersion

نسخه‌ی Block API

همیشه ۳ بگذارید؛ ادیتور را داخل iframe رندر می‌کند و در وردپرس ۷.۱ اجباری شده

name

شناسه‌ی یکتا به شکل namespace/slug

فقط حروف کوچک، عدد و خط تیره

attributes

داده‌هایی که بلاک ذخیره می‌کند

در بلاک داینامیک فقط همین‌ها در دیتابیس می‌روند

supports

قابلیت‌های آماده‌ی ادیتور

interactivity: true برای Interactivity API الزامی است

render

فایل PHP خروجی سایت

از ۶.۱؛ متغیرهای $attributes و $content و $block در دسترس‌اند

editorScript

جاوااسکریپت فقط ادیتور

index.js که Edit را ثبت می‌کند

viewScriptModule

ماژول جاوااسکریپت فقط سایت

از ۶.۵؛ برای Interactivity API به جای viewScript

style و editorStyle

استایل مشترک و استایل فقط ادیتور

مسیرها به خروجی build اشاره می‌کنند

example

داده‌ی نمونه برای پیش‌نمایش در اینسرتر

بدون آن پیش‌نمایش خالی است

textdomain

دامنه‌ی ترجمه

برای فارسی کردن title و description و رشته‌های JS

قدم ۳: index.js و edit.js

import { registerBlockType } from '@wordpress/blocks';
import metadata from './block.json';
import Edit from './edit';
import './style.scss';

// بلاک داینامیک است؛ save نداریم و خروجی از render.php می‌آید
registerBlockType( metadata.name, { edit: Edit } );

edit.js همان چیزی است که نویسنده در گوتنبرگ می‌بیند. از RichText برای ویرایش متن در جای خود و از InspectorControls برای تنظیمات سایدبار استفاده می‌کنیم. تابع useBlockProps() کلاس‌ها و ویژگی‌های لازم ادیتور (رنگ، فاصله، anchor) را روی ریشه‌ی بلاک می‌گذارد.

import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, ToggleControl } from '@wordpress/components';
import './editor.scss';

export default function Edit( { attributes, setAttributes } ) {
	const { heading, body, open } = attributes;

	return (
		<>
			<InspectorControls>
				<PanelBody title={ __( 'تنظیمات آکاردئون', 'wpkala-blocks' ) }>
					<ToggleControl
						label={ __( 'به صورت پیش‌فرض باز باشد', 'wpkala-blocks' ) }
						checked={ open }
						onChange={ ( value ) => setAttributes( { open: value } ) }
					/>
				</PanelBody>
			</InspectorControls>

			<div { ...useBlockProps( { className: 'wpkala-acc' } ) }>
				<RichText
					tagName="h3"
					className="wpkala-acc__btn"
					value={ heading }
					allowedFormats={ [] }
					placeholder={ __( 'عنوان سؤال…', 'wpkala-blocks' ) }
					onChange={ ( value ) => setAttributes( { heading: value } ) }
				/>
				<RichText
					tagName="div"
					className="wpkala-acc__panel"
					value={ body }
					placeholder={ __( 'متن پاسخ…', 'wpkala-blocks' ) }
					onChange={ ( value ) => setAttributes( { body: value } ) }
				/>
			</div>
		</>
	);
}

قدم ۴: render.php

این فایل در هر بازدید اجرا می‌شود و خروجی نهایی را می‌سازد. در نسخه‌ی اول فقط HTML ساده می‌دهیم؛ در بخش بعد همین فایل را با دایرکتیوهای Interactivity API کامل می‌کنیم. دو قاعده‌ی ثابت: هر مقدار را escape کنید و ریشه‌ی بلاک را با get_block_wrapper_attributes() بسازید تا رنگ و فاصله‌ای که کاربر در ادیتور انتخاب کرده اعمال شود.

قدم ۵: ثبت بلاک‌ها در فایل اصلی افزونه

از وردپرس ۶.۸ همه‌ی بلاک‌های پوشه‌ی build با یک فراخوانی ثبت می‌شوند. فایل blocks-manifest.php را wp-scripts با پرچم --blocks-manifest می‌سازد و باعث می‌شود وردپرس برای هر بلاک فایل JSON را جداگانه نخواند.

<?php
/**
 * Plugin Name: بلاک‌های وردپرس کالا
 * Description: مجموعه بلاک‌های سفارشی وردپرس کالا.
 * Requires at least: 6.8
 * Requires PHP: 7.4
 * Text Domain: wpkala-blocks
 */

defined( 'ABSPATH' ) || exit;

add_action( 'init', function () {
	// وردپرس ۶.۸ به بعد: همه‌ی بلاک‌های پوشه‌ی build با یک فراخوانی ثبت می‌شوند
	if ( function_exists( 'wp_register_block_types_from_metadata_collection' ) ) {
		wp_register_block_types_from_metadata_collection(
			__DIR__ . '/build',
			__DIR__ . '/build/blocks-manifest.php'
		);
		return;
	}

	// نسخه‌های قدیمی‌تر: هر بلاک جداگانه
	foreach ( glob( __DIR__ . '/build/*/block.json' ) as $block_json ) {
		register_block_type( dirname( $block_json ) );
	}
} );
{
	"scripts": {
		"build": "wp-scripts build --blocks-manifest",
		"start": "wp-scripts start --blocks-manifest",
		"plugin-zip": "wp-scripts plugin-zip",
		"lint:js": "wp-scripts lint-js",
		"format": "wp-scripts format"
	}
}

حالا npm run build را اجرا کنید، افزونه را فعال کنید و بلاک «آکاردئون» را در ادیتور بیاورید. عنوان و متن را می‌نویسید و در سایت نمایش داده می‌شود؛ فقط هنوز باز و بسته نمی‌شود. این کار Interactivity API است.

روش ۳: تعاملی کردن بلاک با Interactivity API

Interactivity API از وردپرس ۶.۵ راه رسمی رفتار سمت کاربر در بلاک‌هاست و بلاک‌های هسته مثل جست‌وجو، ناوبری و گالری با آن ساخته شده‌اند. ایده‌اش ساده است: HTML کامل از PHP می‌آید، شما با چند ویژگی به نام دایرکتیو می‌گویید هر عنصر به چه داده‌ای وابسته است، و یک استور کوچک جاوااسکریپت فقط رفتار را اضافه می‌کند. نه رندر دوباره در مرورگر داریم، نه jQuery و نه کتابخانه‌ی سنگین.

جریان کار Interactivity API وردپرس از render.php تا دایرکتیوها و استور view.js

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

render.php با دایرکتیوها

<?php
/**
 * render.php — هر بار که صفحه نمایش داده می‌شود اجرا می‌شود.
 * متغیرهای در دسترس: $attributes، $content و $block
 */

// استیت سراسری این namespace: یک بار برای همه‌ی آکاردئون‌های صفحه
wp_interactivity_state( 'wpkala/accordion', array(
	'labelOpen'   => 'بستن',
	'labelClosed' => 'بیشتر بخوانید',
) );

$panel_id = wp_unique_id( 'wpkala-acc-' );
$context  = array(
	'isOpen'  => ! empty( $attributes['open'] ),
	'panelId' => $panel_id,
);
?>
<div
	<?php echo get_block_wrapper_attributes( array( 'class' => 'wpkala-acc' ) ); ?>
	data-wp-interactive="wpkala/accordion"
	<?php echo wp_interactivity_data_wp_context( $context ); ?>
	data-wp-class--is-open="context.isOpen"
>
	<button
		type="button"
		class="wpkala-acc__btn"
		data-wp-on--click="actions.toggle"
		data-wp-bind--aria-expanded="context.isOpen"
		data-wp-bind--aria-controls="context.panelId"
	>
		<span><?php echo esc_html( $attributes['heading'] ?? '' ); ?></span>
		<small data-wp-text="state.label"></small>
	</button>

	<div
		class="wpkala-acc__panel"
		data-wp-bind--id="context.panelId"
		data-wp-bind--hidden="!context.isOpen"
	>
		<?php echo wp_kses_post( $attributes['body'] ?? '' ); ?>
	</div>
</div>

سه مفهوم در این فایل هست. wp_interactivity_state() استیت سراسری namespace را روی سرور مقداردهی می‌کند و همه‌ی آکاردئون‌های صفحه آن را می‌بینند. wp_interactivity_data_wp_context() کانتکست محلی هر بلاک را به شکل یک ویژگی امن تولید می‌کند؛ هرگز JSON را دستی داخل data-wp-context ننویسید. و دایرکتیوها: data-wp-on--click رویداد را به یک action وصل می‌کند، data-wp-bind--hidden یک ویژگی HTML را از روی داده تنظیم می‌کند و data-wp-text متن عنصر را از استیت می‌خواند.

view.js و استور

import { store, getContext } from '@wordpress/interactivity';

const { state } = store( 'wpkala/accordion', {
	state: {
		// استیت مشتق‌شده: بر اساس کانتکست همان عنصر محاسبه می‌شود
		get label() {
			return getContext().isOpen ? state.labelOpen : state.labelClosed;
		},
	},
	actions: {
		toggle() {
			const context = getContext();
			context.isOpen = ! context.isOpen;
		},
	},
	callbacks: {
		// نمونه‌ی data-wp-watch: هر بار isOpen عوض شود اجرا می‌شود
		logState() {
			const { isOpen, panelId } = getContext();
			console.log( panelId, isOpen ? 'باز شد' : 'بسته شد' );
		},
	},
} );

استور با همان namespace ثبت می‌شود که در data-wp-interactive نوشتید. تابع getContext() کانتکست همان عنصری را برمی‌گرداند که رویداد روی آن رخ داده، پس چند آکاردئون در یک صفحه با هم قاطی نمی‌شوند. getter به نام label یک استیت مشتق‌شده است: به محض تغییر isOpen، متن دکمه هم بدون هیچ کد اضافه‌ای عوض می‌شود.

چون در block.json "viewScriptModule": "file:./view.js" و "interactivity": true را گذاشته‌ایم، وردپرس این فایل را به صورت ماژول و فقط در صفحه‌هایی که بلاک حضور دارد بارگذاری می‌کند. اگر به اشتباه viewScript بگذارید، دستور import خطا می‌دهد و بلاک تعاملی نمی‌شود.

دایرکتیوهای پرکاربرد

دایرکتیو

کار

مثال

data-wp-interactive

فعال کردن API برای عنصر و فرزندانش با یک namespace

data-wp-interactive="wpkala/accordion"

data-wp-context

داده‌ی محلی عنصر و فرزندانش

خروجی wp_interactivity_data_wp_context()

data-wp-bind--attr

تنظیم یک ویژگی HTML از روی داده؛ بولین ویژگی را اضافه یا حذف می‌کند

data-wp-bind--hidden="!context.isOpen"

data-wp-class--name

افزودن یا حذف کلاس بر اساس بولین

data-wp-class--is-open="context.isOpen"

data-wp-style--prop

تنظیم یک ویژگی CSS درون‌خطی

data-wp-style--color="context.color"

data-wp-text

متن عنصر

data-wp-text="state.label"

data-wp-on--event

اجرای action با رویداد DOM

data-wp-on--click="actions.toggle"

data-wp-on-window--event و data-wp-on-document--event

رویدادهای سراسری

data-wp-on-window--resize="callbacks.onResize"

data-wp-watch

اجرا هنگام ساخت عنصر و هر بار تغییر داده‌ی خوانده‌شده

data-wp-watch="callbacks.logState"

data-wp-init

اجرا فقط یک بار هنگام ساخت عنصر

data-wp-init="callbacks.setup"

data-wp-each

تکرار یک template برای هر آیتم فهرست

<template data-wp-each="context.items">

data-wp-key

کلید یکتا برای ردیابی عنصرها در فهرست

data-wp-key="item-1"

استایل راست‌چین

/* style.scss: در ادیتور و سایت بارگذاری می‌شود */
.wpkala-acc {
	border: 1px solid #d9e2db;
	border-radius: 12px;
	overflow: hidden;

	&__btn {
		display: flex;
		justify-content: space-between;
		align-items: center;
		width: 100%;
		padding: 14px 18px;
		background: transparent;
		border: 0;
		font: inherit;
		text-align: start; /* راست‌چین در فارسی، چپ‌چین در انگلیسی */
		cursor: pointer;
	}

	&__panel {
		padding: 0 18px 16px;
	}

	&.is-open &__btn {
		color: #0f5a41;
	}
}

به جای left و right از text-align: start و ویژگی‌های منطقی مثل padding-inline-start استفاده کنید. بلاک شما بدون هیچ تغییری هم در سایت فارسی و هم انگلیسی درست می‌نشیند. کلاس is-open را خود دایرکتیو data-wp-class اضافه و حذف می‌کند.

ترجمه‌ی فارسی بلاک

title و description و keywords در block.json با textdomain ترجمه‌پذیرند. رشته‌های داخل edit.js با __() نوشته شده‌اند و برای اینکه در ادیتور فارسی نمایش داده شوند باید ترجمه‌های جاوااسکریپت را ثبت کنید:

add_action( 'init', function () {
	// ترجمه‌ی رشته‌های جاوااسکریپت بلاک (فایل‌های JSON در پوشه‌ی languages)
	wp_set_script_translations( 'wpkala-accordion-editor-script', 'wpkala-blocks', __DIR__ . '/languages' );
} );

هندل اسکریپت از نام بلاک ساخته می‌شود: namespace و slug با خط تیره و پسوند -editor-script. اگر رشته‌ها را مستقیم به فارسی نوشته‌اید (مثل مثال‌های همین مقاله) این مرحله لازم نیست، اما بلاک شما فقط فارسی خواهد بود.

تغییرات وردپرس ۷ که روی ساخت بلاک اثر دارد

  • ثبت بلاک فقط با PHP با autoRegister در ۷.۰ اضافه شد و در ۷.۱ پایدار ماند.

  • ادیتور همیشه در iframe رندر می‌شود. اگر بلاکی هنوز apiVersion ۱ یا ۲ دارد، به ۳ ارتقا دهید وگرنه استایل‌های ادیتور ممکن است اعمال نشوند.

  • پشتیبانی anchor برای بلاک‌های داینامیک و CSS سفارشی برای هر نمونه‌ی بلاک در ۷.۰.

  • نمایش بر اساس اندازه‌ی صفحه: کاربر می‌تواند هر بلاک را فقط در موبایل یا دسکتاپ نشان دهد؛ کاری از سمت شما لازم نیست.

  • Interactivity API در ۷.۰ تابع watch() را برای رصد تغییر استیت بیرون از DOM اضافه کرد و state.navigation در core/router منسوخ شد.

  • آماده‌سازی React 19 در ۷.۱ آغاز شد. اگر از APIهای قدیمی React یا __next40pxDefaultSize استفاده می‌کنید، هشدارهای deprecation را جدی بگیرید.

خطاهای رایج و راه‌حل

نشانه

علت

راه‌حل

بلاک در اینسرتر دیده نمی‌شود

بلاک ثبت نشده یا پوشه‌ی build خالی است

npm run build را اجرا کنید و مطمئن شوید register در هوک init است

بلاک فقط PHP در ادیتور ظاهر نمی‌شود

وردپرس پایین‌تر از ۷.۰ یا autoRegister در جای اشتباه

نسخه را بررسی کنید؛ autoRegister باید داخل آرایه‌ی supports باشد

کلیک روی آکاردئون کاری نمی‌کند

view.js با viewScript بارگذاری شده یا namespace در PHP و JS فرق دارد

از viewScriptModule استفاده کنید و رشته‌ی namespace را یکی کنید

پیام «Block validation failed» بعد از تغییر بلاک

بلاک استاتیک است و HTML ذخیره‌شده با save جدید نمی‌خواند

به رندر داینامیک مهاجرت کنید یا نسخه‌ی deprecated تعریف کنید

render.php در build نیست

فایل بیرون از src بود یا فقط npm start اجرا شده

فایل را کنار block.json در src بگذارید و build بگیرید

استایل ادیتور با سایت فرق دارد

apiVersion قدیمی یا استایل فقط در editorStyle

apiVersion را ۳ کنید و استایل مشترک را در style بگذارید

خطای Invalid parameter(s): attributes

ویژگی‌ای به نام style در بلاک فقط PHP

نام ویژگی را عوض کنید

رشته‌های فارسی در ادیتور انگلیسی‌اند

ترجمه‌ی جاوااسکریپت ثبت نشده

wp_set_script_translations() را با هندل درست صدا بزنید

جمع‌بندی

در وردپرس ۷ دیگر لازم نیست برای هر بلاک کوچک یک پروژه‌ی جاوااسکریپت راه بیندازید. بلاک‌های ساده را فقط با PHP و autoRegister بسازید، بلاک‌هایی که ویرایش غنی یا بلاک تودرتو می‌خواهند را با create-block و block.json، و هر جا کاربر در صفحه با بلاک کار می‌کند Interactivity API را اضافه کنید. در هر سه مسیر دو قاعده ثابت است: رندر داینامیک با render.php و ساخت ریشه‌ی بلاک با get_block_wrapper_attributes().

اگر همین امروز شروع می‌کنید، آکاردئون این مقاله را بسازید و بعد یک بلاک «تب» کنارش اضافه کنید؛ فقط کافی است context آرایه‌ای از تب‌ها نگه دارد و با data-wp-each دکمه‌ها را بسازید. مرحله‌ی بعدی سری توسعه‌ی وردپرس کالا درباره‌ی WP-CLI است که ساخت، تست و مهاجرت همین بلاک‌ها را از خط فرمان سریع می‌کند.

سؤال‌های متداول

برای ساخت بلاک وردپرس حتماً باید React بلد باشم؟

خیر. در وردپرس ۷ بلاک‌های ساده را فقط با PHP و autoRegister می‌سازید. برای بلاک‌های استاندارد هم create-block همه‌ی پیکربندی را آماده می‌کند و شما با چند کامپوننت آماده مثل RichText و ToggleControl کار می‌کنید. دانستن React کمک می‌کند اما پیش‌نیاز نیست.

بلاک استاتیک بهتر است یا داینامیک؟

برای تقریباً همه‌ی بلاک‌ها داینامیک. HTML در هر بازدید از render.php ساخته می‌شود، پس تغییر خروجی هرگز محتوای قدیمی را نمی‌شکند و به داده‌ی زنده دسترسی دارید. استاتیک فقط برای بلاک‌های صرفاً متنی که هیچ‌وقت تغییر ساختار نمی‌دهند منطقی است.

Interactivity API چه فرقی با نوشتن جاوااسکریپت معمولی دارد؟

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

بلاک فقط PHP چه محدودیت‌هایی دارد؟

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

بلاک‌هایم روی وردپرس ۶ هم کار می‌کنند؟

بلاک استاندارد و تعاملی روی ۶.۵ به بعد کار می‌کنند. تابع wp_register_block_types_from_metadata_collection از ۶.۸ هست و در کد مقاله برای نسخه‌های قدیمی‌تر مسیر جایگزین گذاشته‌ایم. بلاک فقط PHP با autoRegister مخصوص وردپرس ۷.۰ به بالاست.

چطور چند بلاک در یک افزونه داشته باشم؟

برای هر بلاک یک پوشه در src بسازید که block.json خودش را دارد. wp-scripts با پرچم --blocks-manifest همه را در build و یک فایل blocks-manifest.php جمع می‌کند و تابع ثبت گروهی همه را یک‌جا ثبت می‌کند.

استایل بلاک را چطور راست‌چین کنم؟

از ویژگی‌های منطقی CSS استفاده کنید: text-align: start به جای right، padding-inline-start به جای padding-right و margin-inline-end به جای margin-left. با این کار همان استایل در سایت فارسی و انگلیسی درست کار می‌کند.

  • ۱۴ دقیقه مطالعه
نویسندهمدیریت

نظرات کاربران

ثبت نظر و امتیاز

هنوز نظری ثبت نشده؛ اولین نظر را شما بنویسید.

نظر و امتیاز خود را بنویسید

ایمیل شما منتشر نمی‌شود. نظرها پس از بازبینی منتشر می‌شوند.

با ارسال نظر، قوانین انتشار نظرات سایت را می‌پذیرید.

مطالب مرتبط

اگر این مقاله برایتان مفید بود، این‌ها را هم بخوانید

محیط توسعه لوکال وردپرس در ۱۴۰۵ با wp-env، Docker، Playground، Studio و LocalWP
توسعه و کدنویسی وردپرس

محیط توسعه‌ی لوکال وردپرس در ۱۴۰۵: wp-env، Docker، Playground، Studio و LocalWP

جایگزین‌های امروزی XAMPP برای توسعه‌ی وردپرس: wp-env ابزار رسمی، Docker Compose برای تیم، Playground برای اجرا داخل مرورگر و Studio و LocalWP برای طراحان. با فایل‌های پیکربندی آماده، Blueprint برای دمو و نکته‌های مخصوص اینترنت ایران.

۹ دقیقه مطالعه
REST API وردپرس: اندپوینت سفارشی، احراز هویت با Application Password، کش و امنیت
توسعه و کدنویسی وردپرس

REST API وردپرس: ساخت اندپوینت سفارشی، احراز هویت با Application Password، کش و امنیت

REST API راه استاندارد اتصال اپ موبایل، سایت هدلس، سرویس‌های اتوماسیون و هوش مصنوعی به وردپرس است. در این راهنما یک API واقعی محصولات می‌سازید، چهار روش احراز هویت را مقایسه می‌کنید، کش را در چهار لایه می‌چینید و با چک‌لیست امنیت API را آماده‌ی انتشار می‌کنید.

۱۲ دقیقه مطالعه
هوک‌های وردپرس به زبان ساده: اکشن، فیلتر و ۲۰ مثال واقعی بدون افزونه
توسعه و کدنویسی وردپرس

هوک‌های وردپرس به زبان ساده: اکشن، فیلتر و ۲۰ مثال واقعی بدون افزونه

هوک‌ها راه رسمی تغییر رفتار وردپرس بدون دست زدن به هسته و افزونه‌ها هستند. در این راهنما اکشن و فیلتر را با تصویر یاد می‌گیرید، چهار پارامتر add_action را باز می‌کنیم، جای درست کد و ترتیب اجرای هوک‌ها را می‌بینید و ۲۰ مثال آماده‌ی کپی برای محتوا، امنیت، ورود، پیشخوان، ووکامرس و کرون می‌گیرید.

۱۳ دقیقه مطالعه
دیپلوی وردپرس با Git و GitHub Actions روی هاست ایرانی
توسعه و کدنویسی وردپرس

دیپلوی وردپرس با Git و GitHub Actions روی هاست ایرانی (راهنمای کامل)

هر تغییر کد با یک git push به صورت خودکار، تست‌شده و قابل بازگشت روی سرور بنشیند. در این راهنما یک پایپ‌لاین کامل GitHub Actions برای وردپرس می‌سازید: ساختار ریپو، کلید دیپلوی، بیلد قالب و بلاک، rsync، WP-CLI، استقرار اتمیک، staging با تأیید انسانی و سه استراتژی مخصوص هاست‌های ایرانی.