مقاله کاربردی

آموزش ساخت Custom Post Type در وردپرس با register_post_type

آموزش ساخت Custom Post Type در وردپرس با register_post_type

چکیده مطلب

ساخت Custom Post Type در وردپرس با register_post_type؛ از تعریف برچسب‌ها و پشتیبانی REST تا ثبت taxonomy، نمایش با WP_Query و رفع خطای 404.

زمان مطالعه: 2 دقیقهدسته: وردپرسبه‌روزرسانی: 1405/08/04

آموزش ساخت Custom Post Type در وردپرس با register_post_type

ساخت Custom Post Type در وردپرس زمانی به کار می‌آید که محتوای شما در قالب نوشته یا برگه جا نمی‌گیرد؛ مثل فهرست کتاب‌ها، نمونه‌کارها، پرونده مشتریان یا کاتالوگ اقلامی که فروشگاهی نیستند. با ثبت یک نوع پست سفارشی، وردپرس برای آن محتوا مسیر، آرشیو، قالب و صفحه مدیریت مستقل می‌سازد و مدیریت آن از پراکندگی میان برگه‌ها نجات پیدا می‌کند. در این راهنما مسیر کامل ثبت CPT با register_post_type، افزودن طبقه‌بندی، پشتیبانی از ویرایشگر بلوک و REST API، نمایش در سمت کاربر و رفع خطاهای رایج را گام‌به‌گام می‌بینید.

Custom Post Type چیست و چه زمانی به آن نیاز دارید؟

وردپرس به‌صورت پیش‌فرض چند نوع محتوا دارد: نوشته، برگه، پیوست و انواع داخلی مثل بازنگری‌ها. هر «نوع پست» تعیین می‌کند که یک رکورد در کدام بخش ذخیره شود، چه قالبی برای نمایش آن رندر شود و چه قابلیت‌هایی در پیشخوان به آن اختصاص یابد. نوع پست سفارشی همان سازوکار است، اما با تعریف شما.

نکته‌ای که اغلب نادیده گرفته می‌شود این است: CPT برای «ساختار» است، نه برای «داده». اگر فقط چند فیلد اضافه به نوشته‌های موجود نیاز دارید، ثبت نوع پست تازه معمولاً سربار بی‌دلیلی است.

تفاوت CPT با فیلد سفارشی و برگه

برگه برای محتوای ثابت و معدود مثل «درباره ما» مناسب است. فیلد سفارشی برای افزودن داده ساختاریافته به همان نوشته یا برگه به کار می‌رود. نوع پست سفارشی اما یک جریان مستقل می‌سازد: آرشیو خودش را دارد، در جست‌وجو و فید حاضر است، می‌تواند طبقه‌بندی اختصاصی بگیرد و در REST API به‌صورت مجموعه‌ای جداگانه دیده شود. انتخاب میان این سه، پیش از نوشتن یک خط کد، مهم‌ترین تصمیم این مسیر است.

نشانه‌های واقعی نیاز به CPT

  • محتوایی دارید که تکراری و پرشمار است و باید هر آیتم صفحه مستقل داشته باشد.
  • به آرشیو صفحه‌بندی‌شده با فیلترهای اختصاصی نیاز دارید.
  • می‌خواهید اقلام از نوشته‌های وبلاگ جدا بمانند تا خروجی فید و نقشه سایت شلوغ نشود.
  • ساختار داده‌ای شما ثابت است و قرار است سال‌ها باقی بماند.

پیش‌نیاز و محل قرار دادن کد

کد ثبت CPT باید همیشه و زودتر از سایر بخش‌ها بارگذاری شود. توابع ثبت را داخل فایل functions.php پوسته فرزند یا بهتر از آن، داخل یک افزونه اختصاصی قرار دهید تا با تغییر پوسته، ساختار محتوا از دست نرود. اگر میان این دو گزینه تردید دارید، مقاله افزونه اختصاصی وردپرس تفاوت نگهداری، هزینه و مسیر توسعه را توضیح می‌دهد.

هر ثبت باید روی هوک init انجام شود. اجرای آن پیش از init یا در زمان نامناسب باعث می‌شود نوع پست در بخشی از مدیریت و در REST دیده نشود. جزئیات ترتیب اجرای هوک‌ها را در مقاله هوک در وردپرس بخوانید.

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

<?php
function wpw_register_book_cpt() {
    register_post_type(
        'book',
        array(
            'label'        => 'کتاب‌ها',
            'public'       => true,
            'show_in_rest' => true,
            'supports'     => array( 'title', 'editor', 'thumbnail' ),
            'has_archive'  => true,
            'rewrite'      => array( 'slug' => 'books' ),
        )
    );
}
add_action( 'init', 'wpw_register_book_cpt', 0 );

پارامترهای مهم register_post_type

آرگومان‌های این تابع تعیین می‌کنند نوع پست شما چقدر «کامل» رفتار کند. اگر فقط چند پارامتر ساده بدهید، CPT کار می‌کند اما تجربه مدیریت و نمایش آن ناقص می‌ماند.

برچسب‌ها و نمایش فارسی در پیشخوان

پارامتر labels تمام متن‌های پیشخوان را تأمین می‌کند: نام جمع، نام مفرد، دکمه افزودن، پیام جست‌وجو و پیام «پیدا نشد». اگر آن را تعریف نکنید، وردپرس نام نوع پست لاتین را نشان می‌دهد که برای تیم محتوا گیج‌کننده است.

public، supports، has_archive و rewrite

پارامتر public دسترسی عمومی را روشن می‌کند؛ supports مشخص می‌کند ویرایشگر چه بخش‌هایی داشته باشد (عنوان، ویرایشگر محتوا، تصویر شاخص، چکیده و فیلدهای سفارشی)؛ has_archive صفحه آرشیو می‌سازد و rewrite نامک نشانی‌ها را تعیین می‌کند. قرار دادن with_front روی false جلوی افزوده‌شدن پیشوند دسته‌بندی به نشانی CPT را می‌گیرد.

function wpw_register_book_cpt() {
    $labels = array(
        'name'          => 'کتاب‌ها',
        'singular_name' => 'کتاب',
        'add_new_item'  => 'افزودن کتاب تازه',
        'edit_item'     => 'ویرایش کتاب',
        'search_items'  => 'جست‌وجوی کتاب‌ها',
        'not_found'     => 'کتابی پیدا نشد',
    );

    $args = array(
        'labels'          => $labels,
        'public'          => true,
        'show_in_rest'    => true,
        'rest_base'       => 'books',
        'menu_icon'       => 'dashicons-book',
        'supports'        => array( 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields' ),
        'taxonomies'      => array( 'book_genre' ),
        'has_archive'     => true,
        'hierarchical'    => false,
        'capability_type' => 'post',
        'map_meta_cap'    => true,
        'rewrite'         => array( 'slug' => 'books', 'with_front' => false ),
    );

    register_post_type( 'book', $args );
}
add_action( 'init', 'wpw_register_book_cpt', 0 );

افزودن طبقه‌بندی سفارشی با register_taxonomy

نوع پست به‌تنهایی ساختار کافی نمی‌سازد؛ برای گروه‌بندی اقلام به طبقه‌بندی اختصاصی نیاز دارید. پارامتر hierarchical را روی true بگذارید تا رفتار شبیه دسته‌ها و ساخت درختی داشته باشید، و روی false بگذارید تا شبیه برچسب‌ها و بدون سلسله‌مراتب شود. مهم است که طبقه‌بندی را به نام دقیق نوع پست متصل کنید، وگرنه در صفحه ویرایش ظاهر نمی‌شود.

function wpw_register_book_genre_taxonomy() {
    register_taxonomy(
        'book_genre',
        array( 'book' ),
        array(
            'labels'            => array(
                'name'          => 'ژانرها',
                'singular_name' => 'ژانر',
            ),
            'public'            => true,
            'hierarchical'      => true,
            'show_in_rest'      => true,
            'show_admin_column' => true,
            'rewrite'           => array( 'slug' => 'book-genre' ),
        )
    );
}
add_action( 'init', 'wpw_register_book_genre_taxonomy', 0 );

پشتیبانی از ویرایشگر بلوک و REST API

اگر show_in_rest را روی true نگذارید، نوع پست شما از ویرایشگر بلوک خارج می‌شود و به ویرایشگر کلاسیک برمی‌گردد. این پارامتر همچنین مسیر /wp-json/wp/v2/ را برای CPT فعال می‌کند و پایه اتصال سایت به ابزارهای بیرونی و عامل‌های هوش مصنوعی است. پارامتر rest_base نشانی مجموعه را در REST مشخص می‌کند؛ آن را کوتاه، لاتین و بدون فاصله انتخاب کنید تا مصرف‌کننده‌های API دچار ابهام نشوند.

روشن‌کردن REST به‌معنای عمومی‌شدن همه داده‌ها نیست؛ کنترل دسترسی همچنان از مسیر capability و پارامترهایی مثل capability_type و map_meta_cap اعمال می‌شود. برای اقلام حساس، بازبینی نقش‌ها پس از ثبت CPT الزامی است.

نمایش Custom Post Type در بخش کاربری

پس از ثبت، وردپرس به‌طور خودکار از قالب‌های پوسته استفاده می‌کند. اگر قالب اختصاصی نسازید، ظاهر CPT به قالب نوشته‌ها نزدیک می‌شود که همیشه مطلوب نیست.

قالب‌های پیشنهادی پوسته

  • single-book.php برای صفحه تک‌آیتم.
  • archive-book.php برای صفحه آرشیو؛ اگر نسازید، پوسته سراغ archive.php می‌رود.
  • taxonomy-book_genre.php برای صفحه ژانرها.

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

حلقه WP_Query برای نمایش سفارشی

برای نمایش CPT در برگه‌ای دلخواه یا بخشی از صفحه اصلی، از WP_Query استفاده کنید و در پایان حتماً wp_reset_postdata() را صدا بزنید تا حلقه اصلی سایت خراب نشود.

$books = new WP_Query(
    array(
        'post_type'      => 'book',
        'posts_per_page' => 6,
        'orderby'        => 'date',
        'order'          => 'DESC',
    )
);

if ( $books->have_posts() ) {
    while ( $books->have_posts() ) {
        $books->the_post();
        the_title( '<h3>', '</h3>' );
        the_excerpt();
    }
    wp_reset_postdata();
}

بازنویسی پیوندها و جلوگیری از خطای 404

بازنویسی پیوندها و جلوگیری از خطای 404

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

function wpw_plugin_activate() {
    wpw_register_book_cpt();
    wpw_register_book_genre_taxonomy();
    flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'wpw_plugin_activate' );

اگر هنگام توسعه، قواعد نشانی به‌هم ریخت، به‌جای فراخوانی تابع در کد، یک‌بار از مسیر تنظیمات پیوندهای یکتا صفحه را ذخیره کنید تا قواعد بازسازی شود.

امنیت و پاکسازی خروجی در قالب CPT

هر مقداری که از پایگاه داده می‌آید و در قالب چاپ می‌شود، باید پاک‌سازی یا Escape شود. برای متن از esc_html()، برای مقدار ویژگی‌ها از esc_attr() و برای نشانی‌ها از esc_url() استفاده کنید. اگر برای CPT سفارشی متاباکس می‌سازید، ذخیره‌سازی را بدون بررسی nonce و بدون کنترل سطح دسترسی انجام ندهید؛ این دو، جلوی ذخیره‌سازی ناخواسته و تغییر داده توسط کاربران بی‌مجوز را می‌گیرند.

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

آرشیو خطای 404 می‌دهد

معمولاً علت، ذخیره‌نشدن قواعد نشانی یا تعریف نکردن has_archive است. قواعد را بازسازی کنید و بررسی کنید که تابع ثبت روی init اجرا شود.

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

پارامتر show_in_rest را روی true بگذارید. اگر سرویس‌های امنیتی مسیر /wp-json/ را بسته باشند، ویرایشگر بلوک برای CPT هم مشکل پیدا می‌کند.

نامک با برگه یا نوشته تداخل دارد

اگر اسلاگ CPT با اسلاگ برگه‌ای یکسان باشد، ممکن است نشانی برگه برنده شود. اسلاگ را یکتا و متفاوت انتخاب کنید و with_front را در صورت نیاز غیرفعال کنید.

سنجش نتیجه و بازگشت امن

پیش از اعمال روی سایت اصلی، تغییر را در محیط آزمایشی بک‌آپ‌دار اجرا کنید. سپس این موارد را بررسی کنید: ظاهر آرشیو، صحت نشانی‌ها، حضور اقلام در جست‌وجوی پیشخوان، کارکرد REST و صحت نمایش در قالب موبایل. اگر نتیجه مطلوب نبود، غیرفعال‌کردن افزونه ثبت‌کننده ساختار را برمی‌گرداند، اما داده‌های ذخیره‌شده حذف نمی‌شوند و تا زمان پاک‌سازی دستی باقی می‌مانند؛ پس تصمیم نهایی درباره حذف داده را با احتیاط بگیرید.

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

دنیای وردپرس

دنیای وردپرس

نویسنده و توسعه‌دهنده وردپرس

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

گفت‌وگو

دیدگاه‌ها

نظر، پرسش یا تجربهٔ خود را درباره این مقاله با دیگران به اشتراک بگذارید.

هنوز دیدگاهی ثبت نشده است.

اولین نفری باشید که دیدگاه خود را درباره این مقاله ثبت می‌کند.

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

پیشنهاد ویژه

محصولات پیشنهادی مرتبط با این مقاله

افزونه‌ها و ابزارهایی که راه‌اندازی و نگهداری سایت وردپرسی شما را ساده‌تر می‌کنند.

مشاهده همه محصولات