تابع add_settings_section() در وردپرس وظیفه تعریف یک بخش (section) در پنل تنظیمات را بر عهده دارد و به‌عنوان یکی از اجزای کلیدی Settings API، ساختار بصری و منطقی فرم‌های تنظیمات افزونه‌ها را شکل می‌دهد. بدون این تابع، فیلدهای تنظیمات به‌صورت پراکنده و بدون دسته‌بندی در پنل ظاهر می‌شوند.

تابع add_settings_section وردپرس یکی از پرکاربردترین توابع Settings API برای ساخت بخش‌های تنظیمات افزونه‌هاست. این تابع امکان تعریف عنوان، callback توضیحی و ترتیب نمایش بخش‌ها را فراهم می‌کند و پایه نظم بصری در پنل مدیریت محسوب می‌شود. در این راهنما ساختار کامل، پارامترها، نمونه‌های واقعی، اشتباهات رایج و نکات عملکردی این تابع بررسی می‌شود. همچنین تفاوت آن با add_settings_field و register_setting توضیح داده می‌شود. در پایان پرسش‌های پرتکرار و نگاه فنی عمیق به این تابع مرور خواهد شد.

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

چرا add_settings_section اهمیت دارد

وردپرس برای پنل‌های تنظیمات افزونه‌ها یک استاندارد مشخص دارد. این استاندارد از سه جزء اصلی تشکیل شده است: ثبت تنظیمات با register_setting، تعریف بخش‌ها با add_settings_section و تعریف فیلدها با add_settings_field. هر یک از این سه، مسئول بخشی از ساختار نهایی فرم است.

تابع add_settings_section() به‌طور مشخص مسئول تعریف «گروه‌های فیلد» است. در یک پنل تنظیمات بزرگ، معمولاً ده‌ها فیلد وجود دارد و بدون دسته‌بندی، کاربر دچار سردرگمی می‌شود. این تابع به شما اجازه می‌دهد فیلدهای مرتبط را در یک بخش قرار دهید و برای هر بخش یک توضیح معنادار ارائه کنید.

برای درک کامل جایگاه این تابع در کنار سایر اجزا، مطلب تابع register_setting و تابع add_settings_field را مطالعه کنید.

ساختار و امضای تابع add_settings_section

امضای این تابع به شکل زیر است:

add_settings_section( string $id, string $title, callable $callback, string $page ): void

پارامتر اول یک شناسه یکتا است که در ادامه برای اتصال فیلدها به این بخش استفاده می‌شود. پارامتر دوم عنوانی است که در بالای بخش نمایش داده می‌شود. پارامتر سوم یک callback است که محتوای توضیحی بخش را تولید می‌کند. پارامتر چهارم نام صفحه‌ای است که این بخش در آن نمایش داده می‌شود.

خروجی این تابع void است و به‌طور داخلی رکورد را در آرایه سراسری $wp_settings_sections ثبت می‌کند.

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

پارامتر id

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

add_settings_section(
    'myplugin_api_section',
    'تنظیمات API',
    'myplugin_api_section_callback',
    'myplugin_settings'
);

پارامتر title

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

add_settings_section(
    'myplugin_advanced_section',
    'تنظیمات پیشرفته',
    '__return_null',
    'myplugin_settings'
);

اگر عنوان را خالی بگذارید، بخش بدون سرصفحه نمایش داده می‌شود. این کار در برخی طراحی‌ها مفید است.

پارامتر callback

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

function myplugin_api_section_callback() {
    echo '<p>' . esc_html__( 'کلید API خود را از پنل سرویس دریافت کنید.', 'my-plugin' ) . '</p>';
}

استفاده از esc_html__ برای بین‌المللی‌سازی و escape همزمان ضروری است.

پارامتر page

نام صفحه‌ای که این بخش در آن نمایش داده می‌شود. این مقدار باید با option_group که در do_settings_sections() استفاده می‌شود یکسان باشد:

do_settings_sections( 'myplugin_settings' );

برای ساخت خود صفحه، مطلب تابع add_options_page را ببینید.

ترتیب نمایش بخش‌ها

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

add_settings_section( 'section_one', 'بخش اول', '__return_null', 'myplugin_settings' );
add_settings_section( 'section_two', 'بخش دوم', '__return_null', 'myplugin_settings' );

نقش callback در توضیح بخش

callback توضیحی یکی از ابزارهای مهم برای راهنمایی کاربر است. یک callback خوب، سه ویژگی دارد:

  • کوتاه و مفید باشد
  • هدف بخش را روشن کند
  • در صورت نیاز، به مستندات بیرونی لینک دهد
function myplugin_advanced_section_callback() {
    printf(
        '<p>%s <a href="%s" target="_blank" rel="noopener">%s</a></p>',
        esc_html__( 'این تنظیمات روی عملکرد سایت اثر مستقیم دارند.', 'my-plugin' ),
        esc_url( 'https://example.com/docs' ),
        esc_html__( 'مستندات', 'my-plugin' )
    );
}

callbackهای مفید و معتبر

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

  • __return_null: چیزی برنمی‌گرداند
  • __return_false: مقدار false برمی‌گرداند

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

callback برای بخش‌های پویا

در برخی سناریوها، توضیح بخش باید بر اساس وضعیت سایت تغییر کند. مثلاً اگر کلید API تنظیم نشده است، پیام هشدار نمایش داده شود:

function myplugin_api_section_callback() {
    $key = get_option( 'myplugin_api_key' );
    if ( empty( $key ) ) {
        echo '<div class="notice notice-warning inline"><p>' . esc_html__( 'کلید API تنظیم نشده است.', 'my-plugin' ) . '</p></div>';
    }
}

نمونه‌های عملی در پروژه واقعی

ساخت پنل تنظیمات کامل با دو بخش

add_action( 'admin_init', function () {
    register_setting( 'myplugin_settings', 'myplugin_api_key', array(
        'sanitize_callback' => 'sanitize_text_field',
    ) );
    register_setting( 'myplugin_settings', 'myplugin_mode', array(
        'sanitize_callback' => 'sanitize_key',
    ) );

    add_settings_section(
        'myplugin_main_section',
        'تنظیمات اصلی',
        function () {
            echo '<p>' . esc_html__( 'تنظیمات پایه افزونه', 'my-plugin' ) . '</p>';
        },
        'myplugin_settings'
    );

    add_settings_section(
        'myplugin_advanced_section',
        'تنظیمات پیشرفته',
        '__return_null',
        'myplugin_settings'
    );

    add_settings_field(
        'myplugin_api_key_field',
        'کلید API',
        function () {
            $value = get_option( 'myplugin_api_key' );
            echo '<input type="text" name="myplugin_api_key" value="' . esc_attr( $value ) . '" />';
        },
        'myplugin_settings',
        'myplugin_main_section'
    );
} );

در این الگو، بخش اصلی و پیشرفته تفکیک شده‌اند. برای مطالعه فیلدها، مطلب add_settings_field را ببینید.

بخش تنظیمات بر اساس قابلیت کاربر

if ( current_user_can( 'manage_options' ) ) {
    add_settings_section(
        'myplugin_admin_section',
        'تنظیمات مدیریتی',
        '__return_null',
        'myplugin_settings'
    );
}

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

بخش تنظیمات برای افزونه‌های چندزبانه

در افزونه‌های چندزبانه، ممکن است هر زبان به یک بخش تنظیمات جداگانه نیاز داشته باشد. در این حالت، بخش‌ها را با suffix زبان نام‌گذاری کنید:

foreach ( array( 'fa', 'en', 'ar' ) as $lang ) {
    add_settings_section(
        'myplugin_section_' . $lang,
        sprintf( 'تنظیمات %s', strtoupper( $lang ) ),
        '__return_null',
        'myplugin_settings'
    );
}

ترکیب با add_menu_page برای پنل اختصاصی

اگر پنل تنظیمات در منوی اختصاصی قرار دارد، مطلب تابع add_menu_page راهنماست. در ادامه، همان add_settings_section روی این صفحه اعمال می‌شود.

نمایش تنظیمات در Custom Post Type

اگر بخش تنظیمات به یک post type خاص مرتبط است، مطلب تابع register_post_type را مطالعه کنید.

ذخیره‌سازی و بازیابی مقادیر

پس از ساخت بخش و فیلدها، مقادیر با تابع get_option و تابع update_option مدیریت می‌شوند.

پاک‌سازی در زمان غیرفعال‌سازی

برای حذف تنظیمات در زمان غیرفعال‌سازی، از تابع register_deactivation_hook و تابع delete_option استفاده کنید.

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

نبود callback مناسب

اگر callback نامعتبر یا ناموجود باشد، بخش بدون توضیح نمایش داده می‌شود و ممکن است خطای PHP رخ دهد. همیشه از یک تابع معتبر یا __return_null استفاده کنید.

نبود id یکتا

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

نبود escape در callback

هر خروجی HTML در callback باید escape شود. عدم escape می‌تواند به XSS منجر شود، به‌ویژه اگر متن از دیتابیس خوانده شود:

echo '<p>' . esc_html( get_option( 'myplugin_note' ) ) . '</p>';

مطلب Output Escaping در وردپرس راهنمای کامل است.

فراموشی صفحه در add_settings_field

اگر در add_settings_field مقدار page اشتباه باشد، فیلد در صفحه نمایش داده نمی‌شود. همیشه اطمینان حاصل کنید که مقدار page در تمام سه تابع یکسان است.

نبود تناسب بین بخش‌ها

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

نبود بررسی nonce در فرم

اگرچه settings_fields() nonce را اضافه می‌کند، اما اگر فرم را دستی ساخته‌اید، باید از Nonce در وردپرس استفاده کنید.

نبود تست روی سناریوهای مرزی

تست‌هایی مثل «صفحه با ۱۰ بخش»، «بخش بدون فیلد»، «کاربر بدون دسترسی» و «تداخل با افزونه دیگر» را حتماً بنویسید.

امنیت و عملکرد در add_settings_section

این تابع به‌تنهایی عملیات حساسی انجام نمی‌دهد، اما در ترکیب با فیلدها نقش مهمی در امنیت دارد:

  • callback توضیحی باید escape کند
  • سطح دسترسی کاربر باید در نمایش صفحه بررسی شود
  • nonce باید در فرم باشد
  • داده‌های نمایش‌داده‌شده نباید حاوی اطلاعات حساس باشند

برای مطالعه کامل امنیت در Settings API، مطلب راهنمای Sanitization و SQL Injection Prevention مرجع هستند.

از نظر عملکرد، add_settings_section هزینه قابل توجهی ندارد چون فقط یک رکورد در حافظه ثبت می‌کند. اما اگر callback توضیحی کوئری سنگین اجرا کند، هر بار بارگذاری صفحه تنظیمات هزینه ایجاد می‌شود. توصیه می‌شود callbackها سبک باشند و کوئری سنگین در آن‌ها اجرا نشود.

برای مطالعه الگوهای بهینه‌سازی پنل مدیریت، مطلب بهینه‌سازی سرعت پنل مدیریت توصیه می‌شود.

پرسش‌های پرتکرار درباره add_settings_section

تفاوت add_settings_section با add_settings_field چیست؟

add_settings_section() یک بخش یا گروه تعریف می‌کند، در حالی که add_settings_field() فیلدهای داخل این بخش را تعریف می‌کند. هر فیلد به یک بخش متصل می‌شود.

آیا می‌توان بدون add_settings_section فیلد تعریف کرد؟

فنی ممکن است اما توصیه نمی‌شود. add_settings_field به یک section نیاز دارد و اگر section تعریف نشود، فیلد در جایی نامشخص نمایش داده می‌شود.

آیا ترتیب نمایش بخش‌ها قابل تغییر است؟

ترتیب نمایش بر اساس ترتیب فراخوانی add_settings_section تعیین می‌شود. برای تغییر ترتیب، باید ترتیب فراخوانی را تغییر دهید.

آیا callback اجباری است؟

خیر، می‌توانید از __return_null یا __return_false استفاده کنید. اما اگر نیازی به توضیح دارید، callback مناسب راهنمایی بهتری برای کاربر است.

آیا می‌توان یک section را در چند صفحه نمایش داد؟

خیر، هر section به یک صفحه مشخص تعلق دارد. اگر نیاز به نمایش در چند صفحه دارید، باید section را چند بار با idهای متفاوت ثبت کنید.

آیا می‌توان بخش‌ها را با شرط نمایش داد؟

بله، با current_user_can یا منطق شرطی دیگر. این الگو در افزونه‌های حرفه‌ای رایج است.

آیا این تابع در قالب‌ها هم کاربرد دارد؟

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

نگاه فنی عمیق به add_settings_section

در سطح معماری، add_settings_section() یک رکورد در آرایه سراسری $wp_settings_sections ثبت می‌کند. کلید این آرایه ترکیبی از نام صفحه و id بخش است. در زمان رندر با do_settings_sections()، وردپرس به ترتیب این آرایه را می‌پیماید و برای هر بخش، عنوان و callback را نمایش می‌دهد و سپس فیلدهای متصل به آن بخش را استخراج و رندر می‌کند.

نکته ظریف اول، مسئله hook اجرای این تابع است. ثبت باید در admin_init انجام شود. اگر در hook دیگری مثل init ثبت کنید، صفحه تنظیمات بخش‌ها را نمی‌بیند چون admin_init قبلاً اجرا شده است.

نکته دوم، اثر ترتیب اجرا در شبکه‌های چندسایتی است. در Multisite، اگر تنظیمات سطح شبکه باشد، باید با network_admin_menu هماهنگ شود. برای مطالعه کامل، مطلب مدیریت Multisite وردپرس مفید است.

مسئله سوم، تعامل با افزونه‌های امنیتی است. برخی افزونه‌های امنیتی، فیلترهایی روی $wp_settings_sections اعمال می‌کنند و ممکن است بخش‌های حساس را برای کاربران غیرمجاز مخفی کنند. اگر افزونه شما با آن‌ها ناسازگار است، این موضوع را باید در تست خود لحاظ کنید.

در نهایت، در پروژه‌های Enterprise توصیه می‌شود یک Wrapper اختصاصی برای Settings API بسازید که ثبت بخش‌ها و فیلدها را در یک ساختار یکپارچه انجام دهد. این کار از پخش شدن منطق جلوگیری می‌کند و امکان افزودن قابلیت‌هایی مثل import/export را فراهم می‌کند. برای مطالعه بیشتر، مباحث توابع وردپرس برای گزینه‌های سایت و تابع register_meta مفید هستند. برای مطالعه بیشتر درباره وردپرس، WordPress در ویکی‌پدیا نقطه شروع خوبی است.

اگر در پروژه‌ای با مشکل ترتیب نمایش بخش‌ها یا تداخل با سایر افزونه‌های تنظیمات مواجه شده‌اید، برای ما جالب است بدانید کدام راهکار عملاً به حل مسئله کمک کرده است. تجربه خود را در دیدگاه‌ها بنویسید تا برای سایر توسعه‌دهندگان هم مفید باشد.