تابع wp_localize_script ابزار استاندارد وردپرس برای انتقال داده از سمت سرور (PHP) به سمت کلاینت (JavaScript) است. این تابع معمولاً برای پاس دادن ajax_url، nonce، تنظیمات ترجمه و متغیرهای داینامیک به اسکریپت‌های صف‌بندی‌شده استفاده می‌شود. استفاده درست از آن، امنیت درخواست‌های AJAX، پایداری داده‌ها و تجربه کاربری بهتر را تضمین می‌کند. اشتباهات رایجی مانند نبود nonce، نبود escape، نبود شرط و نبود تست می‌تواند به خطاهای AJAX یا نفوذ امنیتی منجر شود. تسلط بر این تابع برای تعامل PHP و JavaScript ضروری است و در افزونه‌نویسی حرفه‌ای کاربرد گسترده دارد.

چرا انتقال امن داده از PHP به JS ضروری است؟

در توسعه وردپرس، تقریباً هیچ اسکریپت JavaScript بدون تعامل با PHP نوشته نمی‌شود. برای نمونه، یک اسکریپت AJAX باید URL admin-ajax.php را بشناسد، یک اسکریپت اضافه‌کردن به سبد خرید باید nonce امنیتی داشته باشد، و یک اسکریپت ترجمه باید از زبان فعلی سایت مطلع باشد. اگر این داده‌ها به‌صورت مستقیم در فایل JavaScript نوشته شوند، امکان پویایی و امنیت از بین می‌رود. تابع wp_localize_script دقیقاً برای حل این مسئله ساخته شده است: داده را از PHP می‌گیرد و به‌صورت یک شیء JavaScript در HTML چاپ می‌کند. این الگو، پایه پیاده‌سازی حرفه‌ای AJAX، فرم‌ها، ماشین‌حساب‌های قیمت و اسکریپت‌های وابسته به داده پویا در وردپرس است.

تابع wp_localize_script چیست؟

تابع wp_localize_script() یک تابع هسته وردپرس است که در فایل wp-includes/script-loader.php تعریف شده است. این تابع یک شیء JavaScript با داده‌های داده‌شده می‌سازد و آن را پیش از اسکریپت اصلی در HTML درج می‌کند. نام این تابع ممکن است کمی گمراه‌کننده باشد چرا که امروزه تنها برای ترجمه استفاده نمی‌شود. این تابع ابزار عمومی انتقال داده از PHP به JavaScript است و در همه پروژه‌های حرفه‌ای وردپرس کاربرد دارد. نکته مهم این است که اسکریپت هدف باید قبلاً ثبت یا در صف بارگذاری قرار گرفته باشد. اگر پیش از wp_enqueue_script فراخوانی شود، داده‌ها در JavaScript قابل دسترسی نخواهند بود.

امضای تابع و پارامترها

امضای این تابع به‌شکل زیر است:
function wp_localize_script( $handle, $object_name, $l10n ) {
    // ...
}
پارامتر اول (handle) شناسه اسکریپتی است که داده به آن تعلق دارد. پارامتر دوم (object_name) نام شیء JavaScript است که در سمت کلاینت قابل دسترسی خواهد بود. پارامتر سوم (l10n) آرایه یا شیء داده‌های موردنظر است. خروجی این تابع در HTML به‌شکل زیر است:
<script>
var mythemeData = {"ajaxUrl":"...","nonce":"abc123"};
</script>
پس از آن، در JavaScript می‌توان به داده‌ها از طریق mythemeData.ajaxUrl دسترسی داشت. نکته مهم: نام شیء باید یکتا باشد تا با شیءهای سایر افزونه‌ها تداخل نکند. استفاده از پیشوند اختصاصی توصیه می‌شود.

ترتیب صحیح فراخوانی

تابع wp_localize_script باید پس از wp_enqueue_script یا wp_register_script فراخوانی شود. اگر پیش از آن فراخوانی شود، داده‌ها در JavaScript قابل دسترسی نخواهند بود. نمونه صحیح:
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_scripts' );
function mytheme_enqueue_scripts() {
    wp_enqueue_script(
        'mytheme-ajax',
        get_template_directory_uri() . '/assets/js/ajax.js',
        array( 'jquery' ),
        '1.0.0',
        true
    );

    wp_localize_script(
        'mytheme-ajax',
        'mythemeData',
        array(
            'ajaxUrl' => admin_url( 'admin-ajax.php' ),
            'nonce'   => wp_create_nonce( 'mytheme_ajax_nonce' ),
        )
    );
}
نکته مهم: اگر اسکریپت در فوتر بارگذاری شود، داده‌ها نیز بلافاصله پیش از آن درج می‌شوند. این ترتیب تضمین می‌کند که داده‌ها پیش از اجرای اسکریپت در دسترس هستند.

استفاده در AJAX و nonce

یکی از رایج‌ترین کاربردهای wp_localize_script، پاس دادن URL و nonce برای درخواست‌های AJAX است. سمت PHP:
wp_localize_script(
    'mytheme-ajax',
    'mythemeData',
    array(
        'ajaxUrl' => admin_url( 'admin-ajax.php' ),
        'nonce'   => wp_create_nonce( 'mytheme_load_more' ),
    )
);
سمت JavaScript:
jQuery.ajax({
    url: mythemeData.ajaxUrl,
    type: 'POST',
    data: {
        action: 'mytheme_load_more',
        nonce: mythemeData.nonce,
        page: 2
    },
    success: function( response ) {
        console.log( response );
    }
});
سمت PHP (پردازش درخواست):
add_action( 'wp_ajax_mytheme_load_more', 'mytheme_load_more_handler' );
add_action( 'wp_ajax_nopriv_mytheme_load_more', 'mytheme_load_more_handler' );

function mytheme_load_more_handler() {
    if ( ! check_ajax_referer( 'mytheme_load_more', 'nonce', false ) ) {
        wp_send_json_error( array( 'message' => 'درخواست نامعتبر' ), 403 );
    }

    // پردازش و پاسخ
    wp_send_json_success( array( 'posts' => $posts ) );
}
نکته مهم: بدون nonce، هر کاربر خارجی می‌تواند درخواست‌های AJAX به سایت شما ارسال کند و این یک حفره امنیتی جدی است. راهنمای هوک‌های AJAX در راهنمای هوک wp_ajax و راهنمای هوک wp_ajax_nopriv آمده است. برای مطالعه دقیق‌تر روی توابع بررسی nonce، به راهنمای wp_verify_nonce و راهنمای check_ajax_referer مراجعه کنید. همچنین توابع ارسال پاسخ JSON در راهنمای wp_send_json_success و راهنمای wp_send_json_error به تفصیل بررسی شده است.

Escape و امنیت داده‌ها

تابع wp_localize_script داده‌ها را با wp_json_encode به JSON تبدیل می‌کند و در HTML درج می‌کند. این مکانیزم کاراکترهای خطرناک را به‌درستی escape می‌کند و از تزریق JavaScript جلوگیری می‌کند. با این حال، توصیه می‌شود از درج داده‌های حساس مانند رمزهای عبور، کلیدهای API سرور یا اطلاعات شخصی در این تابع خودداری کنید. اگر داده‌ای در سمت کلاینت درج شود، حتی اگر escape شده باشد، در ابزارهای توسعه‌دهنده مرورگر قابل مشاهده است. الگوی صحیح پاس دادن داده:
wp_localize_script(
    'mytheme-form',
    'mythemeFormData',
    array(
        'strings' => array(
            'required'  => esc_html__( 'این فیلد اجباری است', 'mytheme' ),
            'invalid'   => esc_html__( 'مقدار نامعتبر است', 'mytheme' ),
            'success'   => esc_html__( 'با موفقیت ارسال شد', 'mytheme' ),
        ),
        'maxUpload' => wp_max_upload_size(),
    )
);
نکته مهم: استفاده از esc_html__ برای رشته‌های ترجمه و esc_url برای URLها، امنیت داده‌های منتقل‌شده را تضمین می‌کند. راهنمای این تابع در صفحه esc_html آمده است.

کاربردهای عملی در قالب و افزونه

بارگذاری اسکریپت نقشه با کلید API:
wp_enqueue_script(
    'mytheme-map',
    get_template_directory_uri() . '/assets/js/map.js',
    array(),
    '1.0.0',
    true
);

wp_localize_script(
    'mytheme-map',
    'mythemeMap',
    array(
        'apiKey'  => get_option( 'mytheme_maps_api_key' ),
        'markers' => get_option( 'mytheme_markers' ),
        'zoom'    => 12,
    )
);
پاس دادن تنظیمات قالب به اسکریپت:
wp_localize_script(
    'mytheme-main',
    'mythemeSettings',
    array(
        'stickyHeader' => (bool) get_theme_mod( 'sticky_header', true ),
        'smoothScroll' => (bool) get_theme_mod( 'smooth_scroll', true ),
        'darkMode'     => (bool) get_theme_mod( 'dark_mode', false ),
    )
);
پاس دادن اطلاعات کاربر:
$user_data = array();
if ( is_user_logged_in() ) {
    $current_user = wp_get_current_user();
    $user_data = array(
        'id'        => $current_user->ID,
        'name'      => $current_user->display_name,
        'canEdit'   => current_user_can( 'edit_posts' ),
    );
}

wp_localize_script( 'mytheme-app', 'mythemeUser', $user_data );
نکته مهم: استفاده از current_user_can امکان کنترل دسترسی سمت کلاینت را فراهم می‌کند. راهنمای این تابع در صفحه current_user_can آمده است.

جایگزین‌های مدرن

در وردپرس ۵.۰ و بالاتر، توابع جدیدتری برای تزریق داده به JavaScript معرفی شده‌اند: - wp_add_inline_script: امکان افزودن کد JavaScript به اسکریپت صف‌بندی‌شده را فراهم می‌کند - wp_set_script_translations: مدیریت ترجمه اسکریپت‌ها به روش مدرن - wp_add_inline_script با پارامتر before: تزریق کد پیش از اسکریپت اصلی نمونه استفاده از wp_add_inline_script:
$data = wp_json_encode( array(
    'ajaxUrl' => admin_url( 'admin-ajax.php' ),
    'nonce'   => wp_create_nonce( 'mytheme_nonce' ),
) );

wp_add_inline_script(
    'mytheme-ajax',
    'window.mythemeData = ' . $data . ';',
    'before'
);
با این حال، wp_localize_script همچنان روش استاندارد و پرکاربرد است و برای اکثر پروژه‌ها کافی است.

نقش در Child Theme

در Child Theme، می‌توانید داده‌های اضافی به اسکریپت‌های Parent Theme اضافه کنید یا برای اسکریپت سفارشی خود، داده‌های مستقل تعریف کنید. الگوی افزودن داده به اسکریپت Parent:
add_action( 'wp_enqueue_scripts', 'mychild_localize_scripts', 20 );
function mychild_localize_scripts() {
    wp_localize_script(
        'mytheme-main',
        'mychildData',
        array(
            'childActive' => true,
            'customColor' => get_theme_mod( 'child_accent_color', '#1a1a1a' ),
        )
    );
}
نکته مهم: اولویت ۲۰ باعث می‌شود این تابع پس از تابع Parent Theme اجرا شود و اطمینان حاصل شود که اسکریپت اصلی قبلاً صف‌بندی شده است. برای مطالعه درباره ساختار Child Theme به راهنمای get_stylesheet_directory_uri مراجعه کنید.

نکات امنیتی و اشتباهات رایج

اشتباه اول، نبود nonce است. اگر درخواست‌های AJAX بدون بررسی nonce پردازش شوند، هر کاربر خارجی می‌تواند درخواست‌های دلخواه ارسال کند. اشتباه دوم، نبود escape در داده‌های منتقل‌شده است. هرچند wp_localize_script داده‌ها را JSON می‌کند، در سمت JavaScript باید از textContent به‌جای innerHTML استفاده کنید. اشتباه سوم، نبود شرط بارگذاری است. اگر داده‌ها را در همه صفحات بارگذاری کنید، حجم HTML افزایش می‌یابد. اشتباه چهارم، فراخوانی پیش از wp_enqueue_script است. در این حالت، داده‌ها در JavaScript قابل دسترسی نیستند. اشتباه پنجم، نبود تست است. باید بررسی کنید که داده‌ها در JavaScript قابل دسترسی هستند و درخواست‌های AJAX به‌درستی پردازش می‌شوند. اشتباه ششم، پاس دادن داده‌های حساس است. هرگز کلید خصوصی، رمز عبور یا اطلاعات شخصی در این تابع نگذارید. اشتباه هفتم، استفاده از نام شیء تکراری است. اگر نام شیء با افزونه دیگری یکسان باشد، داده‌های یکدیگر را بازنویسی می‌کنند.

تحلیل فنی پیشرفته

در نگاه مهندسی، تابع wp_localize_script() یک نقطه معماری در لایه تزریق داده است که بر چند جنبه از سیستم اثر می‌گذارد. لایه اول لایه Serialization است. داده‌ها با wp_json_encode به JSON تبدیل می‌شوند و این تبدیل، کاراکترهای خطرناک را escape می‌کند. لایه دوم لایه Ordering است. داده‌ها پیش از اسکریپت اصلی در HTML درج می‌شوند و این ترتیب تضمین می‌کند که در JavaScript قابل دسترسی باشند. لایه سوم لایه Performance است. داده‌های منتقل‌شده در هر بار بارگذاری صفحه در HTML درج می‌شوند. اگر داده‌ها حجیم باشند، حجم HTML افزایش می‌یابد. برای داده‌های بزرگ، بهتر است از درخواست‌های AJAX جداگانه استفاده کنید. لایه چهارم لایه امنیت است. nonceها، احراز هویت و کنترل دسترسی از طریق این تابع پاس داده می‌شوند. این الگو پایه امنیت درخواست‌های AJAX است. لایه پنجم لایه کشینگ است. داده‌های منتقل‌شده در HTML کش می‌شوند. اگر داده‌ها بر اساس وضعیت کاربر تغییر کنند، باید استراتژی کش مناسب انتخاب شود. لایه ششم لایه Integration است. ترکیب wp_localize_script با wp_enqueue_script و هوک‌های AJAX، یک الگوی کامل برای تعامل PHP و JavaScript می‌سازد. لایه هفتم لایه Multisite است. در شبکه‌های Multisite، هر سایت می‌تواند داده‌های متفاوتی داشته باشد. لایه هشتم لایه تست است. تست‌های End-to-End باید مطمئن شوند که داده‌ها در JavaScript در دسترس هستند و درخواست‌های AJAX به‌درستی پردازش می‌شوند. مفاهیم پایه‌ای AJAX در Ajax در ویکی‌پدیا توضیح داده شده است. برای مطالعه بیشتر روی توابع مرتبط، می‌توانید به راهنمای wp_enqueue_script، راهنمای wp_register_script، راهنمای هوک wp_enqueue_scripts، راهنمای هوک wp_ajax، راهنمای wp_verify_nonce، راهنمای wp_send_json_success، راهنمای current_user_can و راهنمای is_user_logged_in مراجعه کنید.

پرسش‌های پرتکرار

آیا wp_localize_script تنها برای ترجمه است؟ خیر، امروزه برای انتقال هر نوع داده از PHP به JavaScript استفاده می‌شود. آیا می‌توان چند بار برای یک اسکریپت فراخوانی کرد؟ بله، اما هر فراخوانی، شیء جدید ایجاد می‌کند. توصیه می‌شود همه داده‌ها در یک فراخوانی پاس داده شوند. چطور از داده‌ها در JavaScript استفاده کنیم؟ از طریق نام شیء که به‌عنوان پارامتر دوم پاس داده می‌شود. آیا wp_localize_script قابل استفاده برای REST API است؟ بله، می‌توان rest_url و nonce مربوطه را پاس داد. آیا می‌توان داده‌ها را با AJAX بارگذاری کرد به‌جای wp_localize_script؟ بله، برای داده‌های حجیم یا پویا، درخواست AJAX جداگانه توصیه می‌شود.

نتیجه و مسیر ادامه

تابع wp_localize_script() ابزار استاندارد وردپرس برای انتقال داده از PHP به JavaScript است. استفاده درست از آن یعنی فراخوانی پس از wp_enqueue_script، پاس دادن nonce و ajax_url، escape داده‌ها و توجه به کش. اشتباه‌های کوچک در این تابع اغلب به خطاهای AJAX یا نفوذ امنیتی منجر می‌شوند. اگر این تابع را در پروژه‌ای واقعی به کار برده‌اید و رفتار غیرمنتظره‌ای دیده‌اید — به‌خصوص در ترکیب با کش یا افزونه‌های امنیتی — تجربه‌تان می‌تواند راهگشای دیگران باشد. کدام بخش بیشترین زمان را از شما گرفت؟ دیدگاه خود را بنویسید.