PHP-ból JS-be adat: felejtsd el a wp_localize_scriptet
Ha WordPress témát vagy plugint fejlesztesz, előbb-utóbb jön a klasszikus feladat: PHP oldalon előállítasz valami adatot (REST endpoint URL, nonce, user ID, feature flag), és ezt a frontenden futó JavaScriptnek is tudnia kell. A net tele van példákkal, amik erre a wp_localize_script()-et ajánlják – csak hát ez eredetileg nem erre lett kitalálva.
Na, nézzük meg, miért érdemes ma már inkább a wp_add_inline_script()-et használnod, és hogyan tudsz vele kulturáltan, modern JS-es szemlélettel konfigurációt átadni.
Mi a gond a wp_localize_script()-tel adatátadásra?
A wp_localize_script() neve nem véletlen: a feladata az volt (és ma is az), hogy JavaScriptben használt stringeket lehessen fordíthatóvá tenni (i18n/l10n). Az, hogy „mellékesen” tömböt is át tudsz vele adni, inkább egy elterjedt workaround, mint tiszta megoldás.
- Cél tévesztés: lokalizálásra készült, nem általános adat átadására.
- Mindig globális lesz: a kimenet a
window-ra (globális scope) kerül, ami hosszú távon könnyen ütközésekhez vezet. - Rád erőltet egy objektumformát: tipikusan asszociatív tömb → JS objektum. Primitíveket/egyszerű struktúrákat is lehet trükközni, de nem ez az erőssége.
- Felesleges boilerplate:
var ... = {...};jellegű kimenetet gyárt akkor is, ha te inkábbconst-ot használnál, vagy scoped megoldást. - Egy handle-höz egyszer: ha ugyanarra a script handle-re többször hívod, felülírhatod a korábbi adatot (és ebből jönnek a „miért tűnt el a másik config?” jellegű hibák).
Egy tipikus (és gyakori) minta így néz ki:
wp_localize_script('my-script', 'myData', [
'apiUrl' => rest_url('app/v1'),
'nonce' => wp_create_nonce('wp_rest'),
]);
A WordPress ilyenkor nagyjából ezt fogja kiköpni:
<script id="my-script-js-extra">
var myData = {"apiUrl":"https://example.com/wp-json/app/v1","nonce":"abc123"};
</script>
A tiszta megoldás: wp_add_inline_script()
A wp_add_inline_script() pont azt csinálja, amit a neve mond: inline JavaScriptet ad hozzá egy már regisztrált/enqueue-olt scripthez. Nem „lokalizál”, nem varázsol – te döntöd el, mi legyen a kimenet.
Ugyanaz az adatátadás így néz ki, ha kontrolláltan, wp_json_encode()-dal építed fel:
wp_enqueue_script(
'my-script',
get_template_directory_uri() . '/js/script.js',
[],
'1.0',
true
);
$data = [
'apiUrl' => rest_url('app/v1'),
'nonce' => wp_create_nonce('wp_rest'),
];
wp_add_inline_script(
'my-script',
'const myData = ' . wp_json_encode($data) . ';',
'before' // fontos: a fájl előtt fusson le
);
A kimenet logikusan a script fájl előtt jelenik meg:
<script>
const myData = {"apiUrl":"https://example.com/wp-json/app/v1","nonce":"abc123"};
</script>
<script src="https://example.com/wp-content/themes/my-theme/js/script.js" id="my-script-js"></script>
Miért jobb ez a gyakorlatban?
- Te irányítod a JS kódot:
const,let, IIFE, modul-szerű init – amit akarsz. - Kifejezőbb: a
wp_add_inline_script()névből is látszik, mi történik. - Jobb scope-kezelés: nem vagy rákényszerítve a „mindent a window-ra” stílusra.
- Nem csak adatot tudsz átadni: init kód, feltételek, függvényhívások, feature flag logika – bármi mehet, ami valid JS.
- Többször hívható: ugyanarra a handle-re több inline blokkot is fel tudsz fűzni, nem kell mindent egy gigantikus config objektumba gyömöszölni.
Haladó minták, amik gyakran jól jönnek
1) Inline script külső JS fájl nélkül (dummy handle)
Néha nincs is saját JS fájlod, csak szeretnél egy globális konfigurációt kirakni a HTML-be (például több különböző bundle vagy third-party script fogja olvasni). WordPress 5.0 óta simán regisztrálhatsz egy „üres” scriptet, és arra akaszthatod az inline kódot.
add_action('wp_enqueue_scripts', function () {
// Dummy handle: nincs src
wp_register_script('global', '');
wp_enqueue_script('global');
$config = [
'apiUrl' => rest_url('app/v1'),
'nonce' => wp_create_nonce('wp_rest'),
'userId' => get_current_user_id(),
];
wp_add_inline_script(
'global',
'window.APP_CONFIG = ' . wp_json_encode($config) . ';'
);
});
2) Kevesebb globális szemét: IIFE + névtér
Ha nem szeretnéd, hogy minden változó a globális scope-ban landoljon, csomagold be egy IIFE-be (Immediately Invoked Function Expression), és csak azt tedd ki window alá, amit tényleg muszáj.
wp_add_inline_script(
'my-script',
'(function() {
const config = ' . wp_json_encode($config) . ';
window.myApp = window.myApp || {};
window.myApp.config = config;
})();',
'before'
);
3) Több különálló adatcsomag ugyanahhoz a scripthez
Ahelyett, hogy egy óriási myData objektumba öntenél mindent, szétbonthatod témák szerint. A wp_add_inline_script()-et többször is hívhatod ugyanarra a handle-re.
wp_add_inline_script(
'my-script',
'const API_CONFIG = ' . wp_json_encode($api_config) . ';',
'before'
);
wp_add_inline_script(
'my-script',
'const USER_DATA = ' . wp_json_encode($user_data) . ';',
'before'
);
4) Feltételes inicializálás (DOM ready körültekintően)
Ha az init kódodnak DOM kell, akkor vagy DOMContentLoaded, vagy azonnali futtatás – attól függően, hol jár a dokumentum. Ezt inline is tök jól le tudod kezelni.
$init_code = 'if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initMyApp);
} else {
initMyApp();
}';
wp_add_inline_script('my-script', $init_code, 'after');
Mikor melyiket használd?
A lényeg az, hogy ne keverd a célokat:
wp_add_inline_script(): ha adatot vagy futtatható JS kódot akarsz PHP-ból a frontendnek adni (új fejlesztésnél ez legyen az alap).wp_localize_script(): ha tényleg JavaScript stringeket akarsz fordíthatóvá tenni, vagy legacy kódot tartasz életben, ahol a refaktor nem éri meg.
Gyors átállás: a tipikus csere
A legtöbb esetben az átállás annyi, hogy a „lokalizálást” lecseréled inline scriptre, és wp_json_encode()-dal generálsz valid JS-t.
// Régi minta (adatátadásra)
wp_localize_script('my-script', 'myData', $data);
// Új minta
wp_add_inline_script(
'my-script',
'const myData = ' . wp_json_encode($data) . ';',
'before'
);
before módban add hozzá. Ha init kódot futtatsz, ami a fájl függvényeit hívja, akkor inkább after.Összefoglaló
A wp_localize_script() köré rengeteg „adatátadós” WordPress minta épült, de ma már van erre rendes eszköz: a wp_add_inline_script(). Kevesebb hack, jobb kontroll a kimenet felett, modernebb JS-es megközelítés, és nem kell a global scope-ot teleszórni kényszerből. Ha most nyúlsz hozzá egy új feature-höz, érdemes rögtön erre átállni.
Hannah Turing
Full Stack fejlesztő a HelloWP csapatában. Laravel, WordPress, React és minden ami a modern webfejlesztéshez kell.
Összes bejegyzés