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

چرا ستون‌های سفارشی، یک سرمایه‌گذاری کوچک با اثر بزرگ است

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

سناریوی اول: تیم‌های محتوایی با فرآیند کاری مشخص. در این تیم‌ها، برای هر نوشته معمولاً یک وضعیت مشخص وجود دارد: «پیش‌نویس»، «در انتظار ویرایش»، «در انتظار تأیید»، «منتشرشده» و گاهی «نیازمند بازبینی مجدد». ذخیرهٔ این وضعیت در متای هر نوشته، ساده است؛ ولی بدون یک ستون در فهرست، اعضای تیم باید تک‌تک نوشته‌ها را باز کنند تا وضعیتشان را ببینند.

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

سناریوی سوم: سایت‌های خدماتی با کاربران پرمعنا. در سایت‌هایی که کاربران نقش مهمی دارند (سامانه‌های آموزشی، باشگاه مشتریان، عضویت‌ها)، افزودن ستون‌هایی مثل «آخرین ورود»، «وضعیت اشتراک» یا «تعداد سفارش» به فهرست کاربران، تجربهٔ پشتیبانی را بهبود می‌دهد.

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

هزینهٔ فنی این بهبود، معمولاً بسیار کمتر از فایدهٔ آن است: یک اسنیپت کوچک با دو هوک، کمتر از پنجاه خط کد. به همین دلیل، در پروژه‌های خودم، ستون‌های سفارشی را یکی از اولین اولویت‌های شخصی‌سازی پیشخوان می‌دانم.

آناتومی ستون‌ها: هوک‌های مسئول در وردپرس

وردپرس برای مدیریت ستون‌های پیشخوان، مجموعه‌ای از هوک‌های استاندارد در اختیار شما می‌گذارد. پیش از نوشتن کد، ارزش دارد بدانید این هوک‌ها چه دسته‌هایی دارند، چون انتخاب اشتباه هوک، کد شما را در بخش اشتباهی از پیشخوان اجرا می‌کند:

هدفافزودن ستونپرکردن مقدار
نوشته‌هاmanage_posts_columnsmanage_posts_custom_column
برگه‌هاmanage_pages_columnsmanage_pages_custom_column
نوع سفارشی خاصmanage_{post_type}_posts_columnsmanage_{post_type}_posts_custom_column
کاربرانmanage_users_columnsmanage_users_custom_column
سفارش‌های ووکامرسmanage_edit-shop_order_columnsmanage_shop_order_posts_custom_column
محصولات ووکامرسmanage_edit-product_columnsmanage_product_posts_custom_column

سه نکتهٔ کلیدی در این نقشه. اول، برای هر هدف، یک هوک Filter برای افزودن ستون و یک هوک Action برای پرکردن مقدار وجود دارد. این دو باید با هم استفاده شوند؛ اگر فقط ستون را اضافه کنید و مقدار را پر نکنید، ستون خالی می‌ماند. دوم، برای هر نوع سفارشی که با register_post_type ساخته می‌شود، می‌توانید از الگوی مشترک manage_{post_type}_posts_columns استفاده کنید. سوم، هوک‌های ووکامرس در نسخه‌های جدید به سمت ساختار HPOS (ذخیره‌سازی سفارش‌های با عملکرد بالا) حرکت کرده‌اند که در بخش مربوطه به آن می‌پردازیم. برای مطالعهٔ تفاوت Action و Filter، تفاوت Action و Filter در وردپرس چیست و برای نحوۀ اتصال به این هوک‌ها، نحوه استفاده از add_filter در وردپرس مراجع کاملی هستند.

افزودن ستون به فهرست نوشته‌ها: گام‌به‌گام

شروع کار با یک نمونهٔ ساده: افزودن یک ستون «بازدید» به فهرست نوشته‌ها که مقدار آن از متای نوشته خوانده می‌شود. کل کد در دو تابع خلاصه می‌شود:

/**
 * Snippet: Add a custom 'views' column to posts list.
 *
 * @since 2026-09-16
 * @author WordPressKar
 *
 * Purpose: Add a custom column showing the post views count.
 * Location: mu-plugins directory or child theme functions.php.
 */

// 1. افزودن ستون به فهرست نوشته‌ها
add_filter( 'manage_posts_columns', 'wphk_add_views_column' );

function wphk_add_views_column( $columns ) {
    $new_columns = array();

    foreach ( $columns as $key => $label ) {
        $new_columns[ $key ] = $label;

        // پس از ستون عنوان، ستون بازدید را اضافه می‌کنیم
        if ( 'title' === $key ) {
            $new_columns['wphk_views'] = 'بازدید';
        }
    }

    return $new_columns;
}

// 2. پرکردن مقدار ستون
add_action( 'manage_posts_custom_column', 'wphk_render_views_column', 10, 2 );

function wphk_render_views_column( $column, $post_id ) {
    if ( 'wphk_views' !== $column ) {
        return;
    }

    $views = (int) get_post_meta( $post_id, '_wphk_views', true );

    if ( $views > 0 ) {
        echo esc_html( number_format_i18n( $views ) );
        return;
    }

    echo '<span aria-hidden="true">—</span>';
}

پنج نکتهٔ کلیدی در این نمونه. اول، در تابع افزودن ستون، از یک حلقه استفاده شده تا ستون جدید پس از ستون عنوان قرار بگیرد، نه در انتهای فهرست. این تصمیم، در تجربهٔ من تجربهٔ کاربری بهتری می‌سازد؛ چون ستون‌های مهم در سمت راست فهرست (که کاربر عادت دارد نگاه کند) باقی می‌مانند. دوم، کلید wphk_views با پیشوند اختصاصی انتخاب شده تا با ستون‌های افزونه‌های دیگر تعارض پیدا نکند. سوم، در تابع پرکردن مقدار، از esc_html برای کدگذاری خروجی استفاده شده تا از تزریق دادهٔ آلوده در HTML جلوگیری شود. چهارم، استفاده از number_format_i18n برای نمایش اعداد با جداکنندهٔ فارسی؛ این تابع به‌طور خودکار از تنظیمات زبان سایت شما پیروی می‌کند. پنجم، برای مقادیر صفر، یک خط تیره نمایش داده می‌شود که زیبایی بصری جدول را حفظ می‌کند. الگوهای مشابه برای خواندن دادهٔ متا در توابع وردپرس برای مدیریت متادیتا آمده است.

پرکردن مقدار ستون با متادیتا

بیشتر موارد استفاده از ستون سفارشی، بر پایهٔ متای نوشته بنا می‌شوند. در تجربهٔ من، سه الگوی رایج در پرکردن ستون‌ها پیش می‌آید که هرکدام نکتهٔ خاص خود را دارند:

الگوی اول: مقدار ساده از متا

ساده‌ترین شکل، خواندن یک مقدار متا و نمایش مستقیم آن است:

$status = get_post_meta( $post_id, '_wphk_edit_status', true );
echo esc_html( $status ?: '—' );

نکتهٔ مهم در این الگو: استفاده از عملگر ?: (elvis) که اگر مقدار متا خالی بود، خط تیره نمایش می‌دهد. این جزئیات کوچک، تجربهٔ بصری جدول را یکنواخت‌تر می‌کند. تحلیل تفصیلی این تابع و پارامترهای آن در توابع وردپرس برای مدیریت متادیتا آمده است.

الگوی دوم: نمایش با برچسب رنگی براساس مقدار

در پروژه‌های تیم‌های محتوایی، نمایش وضعیت به‌صورت یک برچسب رنگی، خوانایی چشمگیرتری می‌سازد:

add_action( 'manage_posts_custom_column', 'wphk_render_status_column', 10, 2 );

function wphk_render_status_column( $column, $post_id ) {
    if ( 'wphk_status' !== $column ) {
        return;
    }

    $status = get_post_meta( $post_id, '_wphk_edit_status', true );

    $map = array(
        'draft'    => array( 'label' => 'پیش‌نویس', 'color' => '#6b7280' ),
        'review'   => array( 'label' => 'در انتظار ویرایش', 'color' => '#d97706' ),
        'approved' => array( 'label' => 'تأیید شده', 'color' => '#059669' ),
        'blocked'  => array( 'label' => 'نیاز به بازبینی', 'color' => '#dc2626' ),
    );

    if ( ! isset( $map[ $status ] ) ) {
        echo '<span aria-hidden="true">—</span>';
        return;
    }

    printf(
        '<span class="wphk-badge" style="background:%s;color:#fff;padding:2px 8px;border-radius:12px;font-size:11px;">%s</span>',
        esc_attr( $map[ $status ]['color'] ),
        esc_html( $map[ $status ]['label'] )
    );
}

سه نکتهٔ کلیدی در این الگو. اول، استفاده از یک آرایه برای نقشهٔ مقادیر به برچسب و رنگ؛ این ساختار، افزودن وضعیت‌های جدید را ساده می‌کند. دوم، چک isset پیش از تولید خروجی که از خطا در مقادیر ناشناخته جلوگیری می‌کند. سوم، esc_attr و esc_html برای کدگذاری هر دو بخش خروجی. الگوهای مشابه برای نمایش وضعیت در سایر بخش‌های پیشخوان در توابع وردپرس برای نوشته‌ها و متادیتا آمده است.

الگوی سوم: محاسبهٔ پویا از چند منبع

در برخی موارد، مقدار ستون از ترکیب چند متا یا حتی از کوئری به دیتابیس به دست می‌آید. مثال: نمایش تعداد نظرات تأییدنشده برای هر نوشته. این نوع محاسبه، در فهرست‌های پربازدید می‌تواند هزینهٔ کارایی داشته باشد. راه‌حل، کش کردن نتیجه است:

add_action( 'manage_posts_custom_column', 'wphk_render_pending_comments', 10, 2 );

function wphk_render_pending_comments( $column, $post_id ) {
    if ( 'wphk_pending' !== $column ) {
        return;
    }

    $cache_key = 'wphk_pending_' . $post_id;
    $count     = get_transient( $cache_key );

    if ( false === $count ) {
        $comments = get_comments( array(
            'post_id' => $post_id,
            'status'  => 'hold',
            'count'   => true,
        ) );
        $count = (int) $comments;
        set_transient( $cache_key, $count, 5 * MINUTE_IN_SECONDS );
    }

    echo esc_html( number_format_i18n( $count ) );
}

سه نکتهٔ کلیدی: اول، استفاده از transient برای کش کردن نتیجهٔ محاسبه که فشار روی دیتابیس را کاهش می‌دهد. دوم، تنظیم زمان کش روی ۵ دقیقه که تعادل خوبی بین تازگی داده و کارایی ایجاد می‌کند. سوم، پاک کردن کش پس از هر تغییر مرتبط. اگر با مفهوم کش در وردپرس آشنایی کمتری دارید، بهترین افزونه‌های کش وردپرس برای افزایش سرعت نکات مفیدی دارد.

ستون سفارشی که در هر بار بارگذاری فهرست، یک کوئری سنگین به دیتابیس می‌زند، دقیقاً برعکس هدف اولیه است: از یک طرف تجربهٔ مدیر را بهبود می‌دهد و از طرف دیگر سایت را کند می‌کند. کش، پل بین این دو است.

افزودن قابلیت مرتب‌سازی به ستون سفارشی

ستون سفارشی که قابل مرتب‌سازی نباشد، تنها نیمی از کاربرد خود را ارائه می‌دهد. با افزودن قابلیت مرتب‌سازی، می‌توانید فهرست نوشته‌ها را براساس مقدار آن ستون مرتب کنید. این کار به دو هوک نیاز دارد:

// 1. فعال‌سازی مرتب‌سازی در ستون
add_filter( 'manage_edit-post_sortable_columns', 'wphk_make_views_column_sortable' );

function wphk_make_views_column_sortable( $columns ) {
    $columns['wphk_views'] = 'wphk_views';
    return $columns;
}

// 2. اعمال مرتب‌سازی در کوئری
add_action( 'pre_get_posts', 'wphk_views_column_orderby' );

function wphk_views_column_orderby( $query ) {
    if ( ! is_admin() || ! $query->is_main_query() ) {
        return;
    }

    if ( 'wphk_views' !== $query->get( 'orderby' ) ) {
        return;
    }

    $query->set( 'meta_key', '_wphk_views' );
    $query->set( 'orderby', 'meta_value_num' );
}

چهار نکتهٔ کلیدی در این الگو. اول، نام هوک manage_edit-post_sortable_columns برای فهرست نوشته‌ها است؛ برای انواع دیگر، ساختار مشابه با نام نوع نوشته است. دوم، در هوک pre_get_posts، ابتدا باید بررسی کنید که در پیشخوان هستید (is_admin) و کوئری، کوئری اصلی است (is_main_query) — بدون این دو شرط، مرتب‌سازی می‌تواند به بخش‌های دیگر سایت اثر بگذارد. سوم، مقدار orderby روی meta_value_num تنظیم شده که مرتب‌سازی عددی را تضمین می‌کند؛ اگر مقدار ستون متنی بود، از meta_value استفاده کنید. چهارم، این الگو فقط برای مرتب‌سازی متای ساده کار می‌کند؛ اگر مقدار ستون از محاسبهٔ پیچیده به دست می‌آید، به یک کوئری سفارشی نیاز دارید. توضیح تفصیلی هوک pre_get_posts در مهم‌ترین Action Hook های وردپرس آمده است.

ستون برای برگه‌ها و انواع سفارشی

برای برگه‌ها و انواع سفارشی، الگوی کار مشابه است ولی نام هوک تفاوت دارد. برای برگه‌ها:

add_filter( 'manage_pages_columns', 'wphk_add_pages_column' );

function wphk_add_pages_column( $columns ) {
    $columns['wphk_template'] = 'قالب برگه';
    return $columns;
}

add_action( 'manage_pages_custom_column', 'wphk_render_pages_column', 10, 2 );

function wphk_render_pages_column( $column, $post_id ) {
    if ( 'wphk_template' !== $column ) {
        return;
    }

    $template = get_page_template_slug( $post_id );
    echo $template
        ? esc_html( basename( $template ) )
        : '<span aria-hidden="true">—</span>';
}

و برای یک نوع سفارشی مثل portfolio:

add_filter( 'manage_portfolio_posts_columns', 'wphk_add_portfolio_columns' );

function wphk_add_portfolio_columns( $columns ) {
    $columns['wphk_client'] = 'مشتری';
    return $columns;
}

add_action( 'manage_portfolio_posts_custom_column', 'wphk_render_portfolio_columns', 10, 2 );

function wphk_render_portfolio_columns( $column, $post_id ) {
    if ( 'wphk_client' !== $column ) {
        return;
    }

    $client = get_post_meta( $post_id, '_wphk_client_name', true );
    echo $client
        ? esc_html( $client )
        : '<span aria-hidden="true">—</span>';
}

سه نکتهٔ کلیدی: اول، الگوی manage_{post_type}_posts_columns و manage_{post_type}_posts_custom_column برای هر نوع سفارشی که با register_post_type ساخته شده کار می‌کند. دوم، برای برگه‌ها، هوک‌های اختصاصی manage_pages_columns و manage_pages_custom_column وجود دارد. سوم، تابع get_page_template_slug برای نمایش قالب استفاده‌شده در هر برگه مفید است و در پروژه‌های شرکتی با چند قالب، تجربهٔ ویرایشی را بهبود می‌دهد. الگوهای مشابه برای نمایش اطلاعات انواع سفارشی در توابع وردپرس برای دریافت اطلاعات نوشته آمده است.

افزودن ستون به فهرست کاربران

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

// 1. افزودن ستون به فهرست کاربران
add_filter( 'manage_users_columns', 'wphk_add_users_phone_column' );

function wphk_add_users_phone_column( $columns ) {
    $columns['wphk_phone'] = 'شماره موبایل';
    return $columns;
}

// 2. پرکردن مقدار ستون
add_filter( 'manage_users_custom_column', 'wphk_render_users_phone_column', 10, 3 );

function wphk_render_users_phone_column( $value, $column_name, $user_id ) {
    if ( 'wphk_phone' !== $column_name ) {
        return $value;
    }

    $phone = get_user_meta( $user_id, 'wphk_phone', true );
    return $phone
        ? esc_html( $phone )
        : '<span aria-hidden="true">—</span>';
}

سه نکتهٔ کلیدی در این الگو. اول، نام‌گذاری هوک‌ها در فهرست کاربران متفاوت است؛ manage_users_columns برای افزودن ستون و manage_users_custom_column برای پرکردن مقدار. دوم، در تابع پرکردن، سه پارامتر دریافت می‌شود و باید مقدار $value بازگردانده شود. سوم، به‌جای get_post_meta، از get_user_meta برای خواندن اطلاعات کاربر استفاده می‌کنیم. تحلیل تفصیلی توابع مدیریت کاربران در توابع وردپرس برای کار با کاربران آمده است.

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

در فروشگاه‌های ووکامرسی، افزودن ستون‌های سفارشی به فهرست سفارش‌ها و محصولات، بخش بزرگی از تجربهٔ روزانهٔ تیم فروش را می‌سازد. الگوی کار مشابه است، ولی یک نکتهٔ مهم وجود دارد: ووکامرس در نسخه‌های اخیر به سمت ساختار HPOS (High-Performance Order Storage) رفته که در آن، سفارش‌ها از جدول wp_posts به جدول‌های اختصاصی منتقل می‌شوند. برای اطمینان از سازگاری با هر دو ساختار، از توابع اختصاصی ووکامرس برای خواندن متای سفارش استفاده کنید:

// 1. افزودن ستون به فهرست سفارش‌ها
add_filter( 'manage_edit-shop_order_columns', 'wphk_add_order_column' );

function wphk_add_order_column( $columns ) {
    $new_columns = array();

    foreach ( $columns as $key => $label ) {
        $new_columns[ $key ] = $label;

        if ( 'order_status' === $key ) {
            $new_columns['wphk_payment_method'] = 'روش پرداخت';
        }
    }

    return $new_columns;
}

// 2. پرکردن مقدار ستون
add_action( 'manage_shop_order_posts_custom_column', 'wphk_render_order_column', 10, 2 );

function wphk_render_order_column( $column, $order_id ) {
    if ( 'wphk_payment_method' !== $column ) {
        return;
    }

    $order = wc_get_order( $order_id );
    if ( ! $order ) {
        return;
    }

    echo esc_html( $order->get_payment_method_title() );
}

سه نکتهٔ کلیدی در این الگو. اول، استفاده از تابع wc_get_order و متدهای شیء سفارش، به‌جای get_post_meta مستقیم؛ این رویکرد با ساختار HPOS سازگار است. دوم، بررسی if ( ! $order ) که در سناریوهای نادر از خطای Null جلوگیری می‌کند. سوم، استفاده از متد get_payment_method_title که عنوان روش پرداخت را با فرمت صحیح برمی‌گرداند. برای مطالعهٔ جامع‌تر این حوزه، مدیریت سفارش‌ها در ووکامرس و برای آشنایی با ساختار کلی ووکامرس، ووکامرس چیست و چگونه فروشگاه اینترنتی بسازیم مراجع کاملی هستند.

اعمال شرطی براساس نقش و نوع نوشته

در پروژه‌های تیمی و سازمانی، همیشه ایدهٔ خوبی است که ستون‌های سفارشی براساس نقش کاربر اعمال شوند. مثلاً برای نویسنده‌های معمولی، ستون تعداد بازدید ممکن است بی‌معنی باشد؛ ولی برای مدیر سایت، ارزشمند است. الگوی اعمال شرطی:

add_filter( 'manage_posts_columns', 'wphk_conditional_column' );

function wphk_conditional_column( $columns ) {
    $user = wp_get_current_user();

    if ( ! $user instanceof WP_User ) {
        return $columns;
    }

    $is_editor = in_array( 'editor', (array) $user->roles, true )
              || in_array( 'administrator', (array) $user->roles, true );

    if ( ! $is_editor ) {
        return $columns;
    }

    $columns['wphk_views'] = 'بازدید';
    return $columns;
}

سه نکتهٔ کلیدی در این الگو. اول، استفاده از wp_get_current_user که در پیشخوان به‌درستی کاربر جاری را برمی‌گرداند. دوم، چک instanceof WP_User برای جلوگیری از خطا در سناریوهای نادر. سوم، اعمال شرط فقط در تابع افزودن ستون کافی است؛ ولی توجه داشته باشید که تابع پرکردن مقدار هم باید همان شرط را داشته باشد یا از بررسی سادهٔ نام ستون استفاده کند. در تجربهٔ من، بدون شرط در هر دو تابع، ممکن است دادهٔ حساس برای کاربران بدون دسترسی نمایش داده شود. تحلیل کامل لایه‌های امنیتی در هوک‌های وردپرس و افزایش امنیت کد آمده است.

ملاحظات کارایی و کش

ستون‌های سفارشی، در نگاه اول سبک به‌نظر می‌رسند؛ ولی در فهرست‌هایی با بیست یا پنجاه نوشته، محاسبهٔ مقدار هر ستون، بیست یا پنجاه بار اجرا می‌شود. سه ملاحظهٔ کارایی که در پروژه‌های خودم رعایت می‌کنم:

ملاحظهٔ اول: کش کردن محاسبات سنگین. همان‌طور که در بخش پرکردن ستون اشاره کردم، اگر مقدار ستون از یک محاسبهٔ سنگین به دست می‌آید، با transient آن را کش کنید. الگوی مشابه در سایر بخش‌های پیشخوان در کاهش مصرف منابع هاست آمده است.

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

ملاحظهٔ سوم: پاک کردن کش هنگام تغییر داده. اگر مقدار ستون شما کش می‌شود، پس از هر تغییر مرتبط باید کش را پاک کنید. در وردپرس، با ترکیب هوک‌های save_post و updated_post_meta می‌توانید این کار را انجام دهید. الگوی مشابه برای پاک‌سازی کش در رفع مشکلات کرون در وردپرس آمده است.

محل درست قرارگیری این اسنیپت

مانند همهٔ اسنیپت‌های وردپرس، محل قرارگیری این کد هم تصمیم مهمی است. سه گزینه پیش روی شماست:

گزینهٔ اول: افزونهٔ اختصاصی یا mu-plugins. این اسنیپت، به‌طور طبیعی به تجربهٔ پیشخوان مربوط است و مستقل از قالب معنا پیدا می‌کند. قرار دادن آن در یک افزونهٔ اختصاصی کوچک، پایدارترین مسیر است. اگر با ساختار افزونهٔ اختصاصی آشنا نیستید، کدنویسی اختصاصی برای افزونه وردپرس و ساختار فایل‌های یک افزونه استاندارد وردپرس مراجع کاملی هستند.

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

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

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

اشتباهات رایج در افزودن ستون سفارشی

در بازبینی سایت‌های مختلف، شش اشتباه تکراری در این حوزه دیده‌ام که هرکدام درس‌آموز است:

اشتباهپیامد واقعیاصلاح
فراموشی بازگشت مقدار در تابع افزودن ستونستون اضافه نمی‌شودبازگشت $columns در انتهای تابع
نبود چک if ( 'wphk_key' !== $column ) در تابع پرکردنمقدار در همهٔ ستون‌ها تکرار می‌شودشرط ابتدایی برای نام ستون
نبود esc_html و esc_attr در خروجیریسک XSSکدگذاری همهٔ خروجی‌ها
استفاده از کوئری سنگین در حلقهٔ ردیف‌هاکندی محسوس فهرست پیشخواناستفاده از transient یا کوئری ترکیبی
نبود شرط is_admin و is_main_query در مرتب‌سازیاثر ناخواسته بر front-endبررسی هر دو شرط در pre_get_posts
نبود پیشوند اختصاصی در نام ستون و توابعتعارض با افزونه‌های دیگرپیشوند یکتا مثل wphk_

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

دو پروندهٔ واقعی از پروژه‌ها

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

پروندهٔ اول: تیم محتوایی که با یک ستون، زمان بازبینی را نصف کرد

همان پروژهٔ ابتدای مقاله. تیم ویرایشی روزانه ده‌ها نوشته را بازبینی می‌کرد و در هر بازبینی، باید تک‌تک نوشته‌ها را باز می‌کرد تا وضعیت ویرایشی‌شان را ببیند. راه‌حل: پیاده‌سازی یک فیلد متای وضعیت ویرایش در ویرایشگر و افزودن یک ستون «وضعیت ویرایش» به فهرست نوشته‌ها که مقدارش را با برچسب رنگی نمایش می‌داد. نتیجه در یک ماه: زمان متوسط بازبینی هفتگی تیم از دو ساعت به یک ساعت کاهش یافت. تجربهٔ مشابه در پروژه‌های تیمی با ستون‌های قابل مرتب‌سازی در توابع وردپرس برای مدیریت نقش‌ها و دسترسی‌ها آمده است.

پروندهٔ دوم: فروشگاهی که با یک ستون، صفِ پشتیبانی را کوتاه کرد

در یک فروشگاه ووکامرسی، تیم پشتیبانی روزانه با سؤال «وضعیت این سفارش چطور است؟» روبه‌رو بود. پیش از تغییر، برای هر پاسخ، باید سفارش را باز می‌کردند تا روش پرداخت و وضعیت ارسال را ببینند. راه‌حل: افزودن ستون «روش پرداخت» به فهرست سفارش‌ها با wc_get_order و نمایش فشردهٔ اطلاعات. نتیجه: تعداد تیکت‌های پشتیبانی در دو هفته حدود ۱۵٪ کاهش یافت. تجربهٔ مشابه در حوزهٔ سفارش‌ها در مدیریت سفارش‌ها در ووکامرس آمده است.

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

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

قطعه کد افزودن ستون سفارشی به مدیریت وردپرس، یکی از پرکاربردترین و در عین حال کم‌سروصداترین کارهای سفارشی‌سازی پیشخوان است. سه ستون این کار: افزودن ستون با هوک‌های manage_*_columns، پرکردن مقدار با هوک‌های manage_*_custom_column، و فعال‌سازی مرتب‌سازی با هوک‌های ترکیبی manage_*_sortable_columns و pre_get_posts. این الگو برای فهرست نوشته‌ها، برگه‌ها، انواع سفارشی، کاربران و سفارش‌های ووکامرس کار می‌کند. سه ملاحظهٔ کارایی (کش محاسبات، پرهیز از کوئری در حلقه، پاک‌سازی کش پس از تغییر) به‌تنهایی می‌توانند تفاوت محسوسی در سرعت پیشخوان بسازند. سه ملاحظهٔ امنیتی (کدگذاری خروجی، بررسی نقش کاربر، شرط‌های is_admin و is_main_query) در همهٔ ستون‌های سفارشی باید رعایت شوند. و محل درست این اسنیپت، افزونهٔ اختصاصی یا چایلد تم است، نه فایل قالب والد.

گام بعدی عملی که پیشنهاد می‌کنم: در همین امروز، یکی از فهرست‌های پیشخوان سایت خود را باز کنید و از خودتان بپرسید چه اطلاعاتی را همیشه برای دیدن باید داخل نوشته‌ها یا محصولات بروید. اگر این اطلاعات در متای نوشته یا کاربر ذخیره شده، همین هفته می‌توانید با یک اسنیپت کوچک، آن را به‌صورت ستون سفارشی به فهرست اضافه کنید. اگر تجربه‌ای با افزودن ستون سفارشی داشته‌اید — به‌ویژه اگر ستونی ساخته‌اید که در تیم شما به یک استاندارد تبدیل شده — برای من جالب است بدانید چطور به آن رسیدید. تجربهٔ خودتان را در دیدگاه‌ها بنویسید؛ به‌ویژه اگر روش تمیزی برای ترکیب چند ستون قابل مرتب‌سازی در فهرست‌های حجیم پیدا کرده‌اید. 🧩