PHP Render Callback
Mengapa PHP Render?
Masalah dengan Save Component JSX
Ketika HTML output dari SaveComponent berubah setelah banyak post sudah tersimpan, WordPress mendeteksi ketidakcocokan dan menampilkan pesan error "Attempt Block Recovery".
Bayangkan Anda punya 500+ post dan mengubah satu class name di save component — semua 500 post akan rusak!
Solusi: PHP Render Callback
Dengan PHP render callback:
- Database hanya menyimpan block comments + attributes (bukan HTML)
- HTML dirender oleh PHP setiap kali halaman dimuat
- Mengubah HTML output tidak merusak post yang sudah ada
Update Class JSXBlock
Tambahkan parameter opsional untuk render callback:
php
class JSXBlock {
function __construct($name, $renderCallback = null, $data = null) {
$this->name = $name;
$this->renderCallback = $renderCallback;
$this->data = $data;
add_action('init', [$this, 'onInit']);
}
function onInit() {
wp_register_script(
$this->name,
get_stylesheet_directory_uri() . "/build/{$this->name}.js",
array('wp-blocks', 'wp-editor')
);
// Jika ada data untuk dilewatkan ke JavaScript
if ($this->data) {
wp_localize_script($this->name, $this->name, $this->data);
}
$args = array(
'editor_script' => $this->name
);
// Jika render callback aktif
if ($this->renderCallback) {
$args['render_callback'] = [$this, 'ourRenderCallback'];
}
register_block_type("ourBlockTheme/{$this->name}", $args);
}
function ourRenderCallback($attributes, $content) {
ob_start();
require get_theme_file_path("/our-blocks/{$this->name}.php");
return ob_get_clean();
}
}Parameter JSXBlock
| Parameter | Default | Fungsi |
|---|---|---|
$name | (wajib) | Nama block |
$renderCallback | null | true = gunakan PHP render |
$data | null | Array data dari PHP ke JS (via wp_localize_script) |
Penggunaan
php
// Tanpa render callback (save ke database sebagai HTML)
new JSXBlock("genericHeading");
// Dengan render callback (PHP render setiap page load)
new JSXBlock("banner", true);
// Dengan render callback + data dari PHP ke JS
new JSXBlock("banner", true, array(
'fallbackImage' => get_theme_file_uri('/images/library-hero.jpg')
));Fungsi ourRenderCallback
php
function ourRenderCallback($attributes, $content) {
ob_start();
require get_theme_file_path("/our-blocks/{$this->name}.php");
return ob_get_clean();
}| Variabel | Isi |
|---|---|
$attributes | Array atribut block (imgURL, className, dll.) |
$content | HTML konten nested/InnerBlocks |
Pattern ob_start() / ob_get_clean()
ob_start() → Mulai buffering output
require ... → File PHP menghasilkan HTML
return ob_get_clean() → Ambil buffer & kembalikan sebagai stringFile PHP Render
Contoh our-blocks/banner.php
php
<?php
if (!isset($attributes['imgURL'])) {
$attributes['imgURL'] = get_theme_file_uri('/images/library-hero.jpg');
}
?>
<div class="page-banner">
<div class="page-banner__bg-image"
style="background-image: url('<?php echo esc_url($attributes['imgURL']); ?>');">
</div>
<div class="page-banner__content container">
<?php echo $content; ?>
</div>
</div>Perhatikan Perbedaan
| JSX (editor) | PHP (render) |
|---|---|
className="page-banner" | class="page-banner" |
style={{backgroundImage: ...}} | style="background-image: ..." |
<InnerBlocks /> | <?php echo $content; ?> |
Di file PHP, gunakan HTML biasa (
class=bukanclassName=)!
Update Save Component
Sekarang SaveComponent hanya mengembalikan InnerBlocks.Content:
js
function SaveComponent() {
return <InnerBlocks.Content />;
}Tidak ada HTML wrapper — semua HTML dirender oleh PHP.
Apa yang Disimpan di Database?
Sebelum (tanpa render callback):
html
<!-- wp:ourBlockTheme/banner {"imgURL":"http://..."} -->
<div class="page-banner">
<div class="page-banner__bg-image" style="background-image: url(...)">
</div>
<div class="page-banner__content container">
<!-- wp:ourBlockTheme/genericHeading {"text":"Hello","size":"large"} -->
<h1 class="headline headline--large">Hello</h1>
<!-- /wp:ourBlockTheme/genericHeading -->
</div>
</div>
<!-- /wp:ourBlockTheme/banner -->Sesudah (dengan render callback):
html
<!-- wp:ourBlockTheme/banner {"imgURL":"http://..."} -->
<!-- wp:ourBlockTheme/genericHeading {"text":"Hello","size":"large"} -->
<h1 class="headline headline--large">Hello</h1>
<!-- /wp:ourBlockTheme/genericHeading -->
<!-- /wp:ourBlockTheme/banner -->Kunci: Hanya block comments + attributes yang tersimpan. HTML wrapper dirender oleh PHP.
Kesimpulan
| Konsep | Penjelasan |
|---|---|
| Masalah save HTML | Ubah HTML → 500+ post rusak (Block Recovery) |
| Solusi | PHP render callback — HTML dirender per-request |
render_callback | Fungsi PHP yang return HTML |
ob_start/ob_get_clean | Buffer output PHP → return sebagai string |
$attributes | Array data block dari database |
$content | HTML nested blocks (InnerBlocks) |
| Save component | Hanya <InnerBlocks.Content /> |
| File PHP | HTML biasa (class=), echo $content untuk nested |