چگونه در وردپرس Meta Box ایجاد کنیم ؟

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

متا باکس های سفارشی چه هستند؟

تصور کنید که شما در حال کار بر روی یک تم برای یک مشتری هستید که می خواهد مجموعه ی گسترده ای از پوسترهای کنسرت های خود را کاتالوگ کند. شما بلافاصله به دنبال قابلیت هایی در وردپرس اصلی خواهید گشت تا ببینید که چگونه می توانید تم را سازماندهی کنید: هر پست نشان دهنده ی یک پوستر است، که برای اضافه کردن یک تصویر، عنوان و شرح مناسب است. همچنین می توانیم از سیستم های دسته بندی و تگ در داخل وردپرس برای سازماندهی پوستر استفاده کنیم. اما چه می شد اگر می خواستیم یک نوع جدید از داده های متا را به “نقش” هر پوستر اضافه کنیم؟ وردپرس تقریبا هیچ قابلیت آماده ای برای انجام این کار ندارد… وجود این مشکل ما را به جعبه های متای سفارشی هدایت می کند.
یک متا باکس سفارشی در تئوری فوق العاده ساده است و به شما اجازه می دهد تا قطعه های سفارشی داده ها را به یک پست یا یک صفحه ی وردپرس اضافه کنید – بهتر از آن، این است که می تواند مستقیما در بسیاری از صفحات پیش فرض در داخل وردپرس جای گذاری شود، بنابراین برای اینکه آسانتر بتواند توسط انواع غیر فنی مورد استفاده قرار گیرد، می توانید به راحتی آن را در داخل Post-Editor جا دهید. همانطور که در مقدمه گفته شد: شما می توانید این نوع “داده های متا” را با استفاده از سازه در بخش های سفارشی برای یک پست یا یک صفحه به پست های خود اضافه کنید. انجام این کار اشتباه نیست، اما خیلی هم برازنده و کاربر پسند نیست.
در عوض، شما باید یک جعبه ی متای سفارشی ایجاد کنید که شامل بخش هایی برای همه ی اطلاعاتتان باشد و دقیقا زمانی که پست منتشر می شود، همه چیز را ذخیره سازی کند.این همان کاری است که ما در اینجا پوشش می دهیم. این امر در سه مرحله ی بزرگ انجام می شود:

• اضافه کردن متا باکس
• خروجی گرفتن از متا باکس ها
• ذخیره کردن داده ها (از راه درست – بله درست حدس زدید، راه اشتباه هم وجود دارد)

ذکر این نکته که بسیاری از این اطلاعات را نیز می توان در داخل پست سفارشی نوع API استفاده کرد، ضروری نیست (بعدا به این نکته خواهیم پرداخت) است، اما فقط به خاطر اینکه امروز همه چیز را متمرکز نگه داریم، قصد داریم که این را به طور مستقیم به ویرایشگر پست پیش فرض اضافه کنیم.
برای مخاطبان پیشرفته تر: بله، انواع پست سفارشی جایی است که ما نهایتا به آنجا خواهیم رسید، اما مهم است که در ابتدا به چندین اصل کلی بپردازیم. به علاوه، به این دلیل که شما می توانید متا باکس های سفارشی را در همه نوع مکانی استفاده کنید، دانستن آن برای هر کسی خوب است.
در این آموزش همه چیز در فایل functions.php تم کار خواهد کرد. به هر حال، اینجا محل درستی برای آن نیست. اگر در حال اضافه کردن داده هایی به یک پست هستید، این احتمال وجود دارد که شما آنها را بدون در نظر گرفتن طراحی ظاهر کاربری، در آنجا می خواهید. به همین ترتیب، باید این کد را در مکانی قرار دهید که به طراحی شما وابسته نیست: جایی مثل یک فایل افزونه.

مرحله 1: اضافه کردن متا باکس

meta-box-title

وردپرس برای اضافه کردن متا باکس ها، در صفحه ی مدیریت، به سادگی یک تابع ارائه می کند: add_meta_box.
وارد کردنCODEX برای این تابع به خوبی انجام شده است، اما در اینجا یک مرور کوتاه بر آن آمده است. این یک نمونه است:

<?php add_meta_box( $id, $title, $callback, $page, $context, $priority, $callback_args ); ?>

$id به عنوان ID html کد باکس قرار می گیرد. این کار در صورتی که شما در حال بارگذاری CSS سفارشی یا جاوا اسکریپت در صفحه ی ویرایش به منظور رسیدگی به گزینه ها هستید، بسیار مفید است. در غیر این صورت، این امرچندان هم مهم نیست.
$title در بالای متا باکس نشان داده شده است.
$callback تابعی است که در واقع از متا باکس خروجی می گیرد. این موضوع را در مرحله 2 مورد بررسی قرار خواهیم داد.
$page جایی است که می خواهید متا باکس در آنجا نمایش داده شود. این باید به یک “post” و یا یک “page” و یا ” some_custom_post_type ” مرتبط باشد.
$context جایی است که متا باکس نمایش داده می شود. گزینه ی “normal” آن را در زیر ویرایشگر پست قرار می دهد. گزینه ی “side” آن را به نوار کناری سمت راست صفحه ی ویرایش منتقل می کند (به وسیله ی دسته بندی ها، تگ ها و غیر). گزینه ی “advanced” نیز باکس را در همان ستونی که ویرایشگر پست وجود دارد، قرار می دهد.
$priority به وردپرس می گوید که مکان متا باکس در چه ناحیه ای باشد. گزینه های “high”، “default” یا “low” به ترتیب متا باکس ها را در نزدیکی بالای صفحه، در موقعیت طبیعی آنها و یا در پایین صفحه قرار می دهد. از آنجایی که همه ی متا باکس ها قادر به کشید شدن هستند، $priority کار چندان بزگی نیست.
سرانجام $callback_args اجازه می دهد تا داده هایتان را به شکل یک آرایه به تابع $callback منتقل کنید. ما قصد نداریم از آن در این اینجا استفاده، اما می تواند برای انتقال برخی داده ها به متا باکس مفید باشد. فرض کنید که افزونه ی شما چندین گزینه داشت که محتویات نمایش داده شده در متا باکس ها را تحت تاثیر قرار می داد. شما می توانید اطلاعات این گزینه ها را از طریق آرایه ی $callback_args منتقل می کند.
بنابراین، شکل add_meta_box ما شبیه به این خواهد بود.

<?php add_meta_box( 'my-meta-box-id', 'My First Meta Box', 'cd_meta_box_cb', 'post', 'normal', 'high' ); ?>

نمی توانیم این را به تنهایی در فایل افزونه استفاده کنید. نتیجه ی انجام این کار، صفحه ی سفید مرگ و خطای مصیبت بار PHPمثل: فراخوانی به تابع تعریف نشده، خواهد بود. چرا؟ زیرا قبل از آن وردپرس بارگذاری شود، تابع add_meta_box را فراخوانی کرده بودیم. بنابراین نیاز داریم که از یک قلاب وردپرس استفاده کنیم، که بخشی از API پلاگین است. در واقع، توابع به یک عملکرد داده شده به وردپرس یا قلاب فیلتر، قلاب می شود، بنابراین زمانی که این قلاب بارگذاری شود، این توابع شروع به کار خواهند کرد. با پیچیدن تماس add_meta_box ما در یک تابع، و سپس اتصال آن تابع به قلاب عملکرد add_meta_boxes، از خطاهای مصیب بار جلوگیری خواهیم کرد.
کد ما برای اضافه کردن متاباکس به صفحه ی پستهایمان، چیزی شبیه به این خواهد بود:

<?php
add_action( 'add_meta_boxes', 'cd_meta_box_add' );
function cd_meta_box_add()
{
	add_meta_box( 'my-meta-box-id', 'My First Meta Box', 'cd_meta_box_cb', 'post', 'normal', 'high' );
}
?>

مرحله 2: خروجی گرفتن از متا باکس

برای اضافه کردن متا باکس کد بالا کافی است، اما حالا باید از چیزی خروجی بگیریم و بخش اضافه کنیم. این فقط یک نوع کد HTML است که برای نمایش دادن اطلاعات ذخیره شده، با کمی PHP مخلوط شده است. نیازی به دخالت دادن تگ فرم ها نداریم زیرا که وردپرس این کار را برای ما انجام خواهد داد.
رشته ای را که ما به add_meta_box به عنوان $callback انتقال دادیم به یاد دارید؟ در حال حاضر می خواهم یک تابع با همین نام یجاد کنیم. این تابع از تمام چیز هایی که در متا باکس نمایش داده می شود، مراقبت خواهد کرد.

<?php
function cd_meta_box_cb()
{
	echo 'What you put here, show\'s up in the meta box';	
}
?>

meta-box-content-1

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

اضافه کردن input

<?php
function cd_meta_box_cb()
{
	?>
	<label for="my_meta_box_text">Text Label</label>
	<input type="text" name="my_meta_box_text" id="my_meta_box_text" />
	<?php	
}
?>

اما چطور است که واقعا اطلاعاتی را نمایش دهیم؟ خوب، همانطور که در مرحله 3 می ببینید، ما این داده ها را با استفاده از تابع update_post_meta در جدول wp_postmeta ، ذخیره می کنیم. این تابع دارای دو تابع مرتبط با آن به نام های get_post_meta و get_post_custom است، که از wp_postmeta اطلاعات کسب می کند. get_post_meta تنها از یک کلید اطلاعات کسب می کند، در حالی که get_post_custom از همه ی آنها اطلاعات کسب خواهد کرد. از آنجا که ما واقعا تنها از یک بخش استفاده می کنیم، اجازه دهید از get_post_meta استفاده کنیم.
همچنین توجه داشته باشید که تابع add_meta_box به callback ما یک متغیر $post را منتقل می کند که یک موضوع پست است.

<?php
function cd_meta_box_cb( $post )
{
$values = get_post_custom( $post->ID );
$text = isset( $values['my_meta_box_text'] ) ? esc_attr( $values['my_meta_box_text'][0] ) : ”;
$selected = isset( $values['my_meta_box_select'] ) ? esc_attr( $values['my_meta_box_select'][0] ) : ”;
$check = isset( $values['my_meta_box_check'] ) ? esc_attr( $values['my_meta_box_check'][0] ) : ”;
	?>
<p>
	<label for="my_meta_box_text">Text Label</label>
	<input type="text" name="my_meta_box_text" id="my_meta_box_text" value="<?php echo $text; ?>" />
        </p>
	<?php		
}

?>

اضافه کردن منوی کرکره ای

<?php	
function cd_meta_box_cb( $post )
{
$values = get_post_custom( $post->ID );
$text = isset( $values['my_meta_box_text'] ) ? esc_attr( $values['my_meta_box_text'][0] ) : ”;
$selected = isset( $values['my_meta_box_select'] ) ? esc_attr( $values['my_meta_box_select'][0] ) : ”;
$check = isset( $values['my_meta_box_check'] ) ? esc_attr( $values['my_meta_box_check'][0] ) : ”;
	?>
	<p>
		<label for="my_meta_box_text">Text Label</label>
		<input type="text" name="my_meta_box_text" id="my_meta_box_text" value="<?php echo $text; ?>" />
	</p>
	
	<p>
		<label for="my_meta_box_select">Color</label>
		<select name="my_meta_box_select" id="my_meta_box_select">
			<option value="red" <?php selected( $selected, 'red' ); ?>>Red</option>
			<option value="blue" <?php selected( $selected, 'blue' ); ?>>Blue</option>
		</select>
	</p>
	<?php	
}
?>

با اضافه کردن بخش دوم، تماس get_post_meta را به get_post_custom تغییر داده ایم، که یک آرایه شرکت پذیر از همه ی کلید ها و ارزش های سفارشی پست ها را برمی گرداند. سپس ما از طریق نام بخش ها به آنها دسترسی پیدا می کنیم. بیانیه ی نوع سوم، کد های مارا در برابر دادن هشدارهای PHP محافظت می کند (شاخص های تعریف نشده و از این قبیل). در مرحله ی 3 به تشریح تابع esc_attr در خواهیم پرداخت.
در منو کرکره ای، قصد داریم که از یکی از مفید ترین توابع وردپرس استفاده کنیم: selected . این تابع ارزش اول یعنی اطلاعلت ذخیره شده ی ما را با ارزش دوم یعنی ویژگی
مقلیسه می کند. اگر آنها یکی باشند، این تابع، selected=”selected” را منعکس می کند، که باعث می شود این ارزش در منو کرکره ای نمایش داده شود. بسیار شیرین است و همچنین ما را از نوشتن تعداد زیادی از توابع و بیانیه های نوع سوم نجات خواهد داد. شما همچنین می توانید از تابع selected() با دکمه های رادیویی استفاده کنید.

  فعال‌سازی حالت ریکاوری در وردپرس (دو روش استاندارد)

اضافه کردن جعبه ی تیک (Check-box)

<?php
function cd_meta_box_cb()
{
	// $post is already set, and contains an object: the WordPress post
	global $post;
	$values = get_post_custom( $post->ID );
	$text = isset( $values['my_meta_box_text'] ) ? $values['my_meta_box_text'] : '';
	$selected = isset( $values['my_meta_box_select'] ) ? esc_attr( $values['my_meta_box_select'] ) : '';
	$check = isset( $values['my_meta_box_check'] ) ? esc_attr( $values['my_meta_box_check'] ) : '';
	
	// We'll use this nonce field later on when saving.
	wp_nonce_field( 'my_meta_box_nonce', 'meta_box_nonce' );
	?>
	<p>
		<label for="my_meta_box_text">Text Label</label>
		<input type="text" name="my_meta_box_text" id="my_meta_box_text" value="<?php echo $text; ?>" />
	</p>
	
	<p>
		<label for="my_meta_box_select">Color</label>
		<select name="my_meta_box_select" id="my_meta_box_select">
			<option value="red" <?php selected( $selected, 'red' ); ?>>Red</option>
			<option value="blue" <?php selected( $selected, 'blue' ); ?>>Blue</option>
		</select>
	</p>
	
	<p>
		<input type="checkbox" id="my_meta_box_check" name="my_meta_box_check" <?php checked( $check, 'on' ); ?> />
		<label for="my_meta_box_check">Do not check this</label>
	</p>
	<?php	
}
?>

باز هم وردپرس تابع مفید checked() را ارائه می دهد. این کار دقیقا شبیه به selected() ارزش اول (داده های ذخیره شده ی ما) را با ارزش دوم مقایسه کرده و اگر آنها یکی باشند، checked=”checked” را منعکس می کند.
wp_nonce_field دو بخش پنهان را به متا باکس های ما اضافه می کند. یکی از آنها nonce است. آنها رشته های تصادفی از اعداد هستند که برای هر کاربر بر اساس هر وبلاگ به مدت 24 ساعت معتبر هستند. Nonce ها راهی برای تأیید مقصود هستند، و آنها اطمینان حاصل می کنند که وردپرس هیچ کاری انجام نمی دهد مگر اینکه درخواست آن از یک مکان بسیار خاص آمده باشد. به عبارت دیگر، ما نمی خواهیم که با اجرا کردن تابع ذخیره شده ی خود (مرحله ی سوم را بررسی کنید) در جای دیگری بجز در قلاب save_post، به طور تصادفی اطلاعاتمان را به روز رسانی کنیم، بنابراین قبل از انجام هر کاری از معتبر بودن Nonce مطمئن شویم.

meta-box-content-3

مرحله 3 ذخیره کردن اطلاعات

“هنگامی که می خواهید چیزی را به پایگاه داده های خود و یا سایت خود وارد کنید، قاعده ی شماره یک این است که: به کاربر اعتماد نکنید! حتی اگر آن کاربر خود شما هستید.”

برای ذخیره کردن اطلاعاتمان، قصد داریم که به یکی دیگر از قلابهای وردپرس تکیه کنیم: save_post.این دقیقا مانند قلاب عملکردی بالا عمل می کند:

<?php add_action( 'save_post', 'cd_meta_box_save' ); ?>

تابع cd_meta_box_save یک استدلال یعنی post id را دریافت خواهد کرد، و مراقب تمیز کردن و ذخیره کردن همه ی اطلاعات ما است. قلاب save_post پس از به روز رسانی کردن و یا بعد از فشار دادن دکمه ی ذخیره کردن پیش نویس، اجرا خواهد شد. بنابراین ما به تمام اطلاعات $_POST دسترسی پیدا می کنیم، که شامل بخش متا باکس های ما در داخل تابع ذخیره سازی می باشد. به هر حال قبل از اینکه ما بتوانیم هر حرکتی بکنیم، باید سه کار انجام دهیم: بررسی کنید که آیا پست به طور خودکار ذخیره می شود، ارزش nonce را که قبلا ساختیم بررسی کنید، و چک کنید تا از این امر که کاربر فعلی در واقع می تواند پست را ویرایش کند مطمئن شوید.

<?php
add_action( 'save_post', 'cd_meta_box_save' );
function cd_meta_box_save( $post_id )
{
	// Bail if we're doing an auto save
	if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
	
	// if our nonce isn't there, or we can't verify it, bail
	if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;
	
	// if our current user can't edit this post, bail
	if( !current_user_can( 'edit_post' ) ) return;
}
?>

حالا به سراغ چیزهای سرگرم کننده می رویم: در حقیقت اطلاعات ما را ذخیره می کند. هنگامی که می خواهید چیزی را به پایگاه داده های خود و یا سایت خود وارد کنید، قاعده ی شماره یک این است که: به کاربر اعتماد نکنید! حتی اگر آن کاربر خود شما هستید. برای رسیدن به این هدف، قبل از اینکه هر گونه اطلاعاتی را ذخیره کنیم، باید مطمئن شویم که هیچ چیز مخربی در آن وجود ندارد. خوشبختانه وردپرس تعدادی تابع برای اعتبار سنجی (data validation) اطلاعات ارائه داده است.
شما قبلا esc_attr() را در بالا دیده اید (مرحله 2). این یکی را در HTML کد نویسی می کند. چرا باید از این استفاده کنیم؟ به این دلیل که کاربران نتوانند در متا باکس شما یکاسکریپت وارد کنند. اگر می خواهید به تگ های HTML معینی اجازه ورود دهید اما بقیه را محروم کنید، wp_kses می توانید این کار را انجام دهد. این کار دو استدلال را شامل می شود، اولی رشته ای است که شما می خواهید بررسی کنید و دومی یک آرایه ی شرکت پذیر از تگ های مجاز است. وردپرس تعداد زیادی ابزار اعتبار سنجی اطلاعات ارائه می دهد، فقط جرات استفاده کردن از آنها را داشته باشید!
ما قصد داریم که مراقبت از تاریخاطلاعات ذخیره شده ی خود از با استفاده از تابع update_post_meta استفاده کنیم. این کار سه استدلال را در بر می گیرد: ID یک پست، کلید متا، و ارزش.

<?php
add_action( 'save_post', 'cd_meta_box_save' );
function cd_meta_box_save( $post_id )
{
	// Bail if we're doing an auto save
	if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
	
	// if our nonce isn't there, or we can't verify it, bail
	if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;
	
	// if our current user can't edit this post, bail
	if( !current_user_can( 'edit_post' ) ) return;
	
	// now we can actually save the data
	$allowed = array( 
		'a' => array( // on allow a tags
			'href' => array() // and those anchors can only have href attribute
		)
	);
	
	// Make sure your data is set before trying to save it
	if( isset( $_POST['my_meta_box_text'] ) )
		update_post_meta( $post_id, 'my_meta_box_text', wp_kses( $_POST['my_meta_box_text'], $allowed ) );
		
	if( isset( $_POST['my_meta_box_select'] ) )
		update_post_meta( $post_id, 'my_meta_box_select', esc_attr( $_POST['my_meta_box_select'] ) );
		
	// This is purely my personal preference for saving check-boxes
	$chk = isset( $_POST['my_meta_box_check'] ) && $_POST['my_meta_box_select'] ? 'on' : 'off';
	update_post_meta( $post_id, 'my_meta_box_check', $chk );
}
?>

meta-box-final

نتیجه گیری

این بود همه ی آنچه که باید برای ایجاد متا باکس ها انجام می دادید! شما باید یک متا باکس با کارکرد کامل داشته باشید. ممکن است نمونه های دیگری را در حلقه ی وب از طریق چندین بخش پیدا کنید بدون اینکه واقعا اطلاعات را تمیز کند. این روش اشتباه است. همیشه از سازه در توابع اعتبار سنجی اطلاعات استفاده کنید؛ بخش ها یا ارزش های مختلف ممکن است به اعتبار سنجی های مختلفی نیاز داشته باشند.
برای استفاده از این بخش های سفارشی در بخش ظاهر کاربری سایتتان، از توابع get_post_meta یا get_post_custom استفاده کنید (به مرحله ی 2 مراجعه کنید).
// ]]>

دانلود
آیا این مقاله برای شما مفید بود؟
تقریبا
خیر

دیدگاهتان را بنویسید

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