Skip to content

Block Attributes, Output & Dynamic Blocks

Gambaran Umum

Video ini membahas block attributes (cara menyimpan data block), perbedaan static vs dynamic blocks, konsep deprecated blocks, dan mengapa dynamic blocks biasanya merupakan pilihan terbaik.


Block Type Attributes

Mendefinisikan Attributes

jsx
wp.blocks.registerBlockType('ourplugin/are-you-paying-attention', {
  title: 'Are You Paying Attention?',
  icon: 'smiley',
  category: 'common',
  attributes: {
    skyColor: {
      type: 'string'
    },
    grassColor: {
      type: 'string'
    }
  },
  edit: EditComponent,
  save: SaveComponent
});

Props & setAttributes

Di dalam function edit, WordPress menyediakan props:

jsx
function EditComponent(props) {
  function updateSkyColor(event) {
    props.setAttributes({ skyColor: event.target.value });
  }
  
  return (
    <div>
      <input 
        type="text" 
        value={props.attributes.skyColor} 
        onChange={updateSkyColor} 
      />
    </div>
  );
}
PropsKegunaan
props.attributesAkses semua attribute values
props.attributes.skyColorAkses attribute spesifik
props.setAttributes({...})Update attribute (merge, bukan replace)

Cara Data Disimpan di Database

WordPress menyimpan attributes dalam HTML comment:

html
<!-- wp:ourplugin/are-you-paying-attention {"skyColor":"blue","grassColor":"green"} -->
<p>Today the sky is blue and the grass is green.</p>
<!-- /wp:ourplugin/are-you-paying-attention -->

Attributes disimpan sebagai JSON di dalam HTML comment, bukan di tabel terpisah.

Alternatif: source dan selector

Selain menyimpan di HTML comment, bisa juga mengambil value dari HTML output langsung:

javascript
attributes: {
  skyColor: {
    type: 'string',
    source: 'text',      // Ambil text content
    selector: '.sky'     // Dari element dengan class 'sky'
  }
}

Brad tidak merekomendasikan pendekatan ini karena lebih fragile. Lebih baik simpan di HTML comment (default behavior).


Static Blocks: Masalah Deprecated

Problem

Dengan static block, function save() menghasilkan HTML yang disimpan di database. Jika kamu mengubah struktur HTML di function save(), WordPress akan menampilkan error "unexpected content" untuk semua post yang sudah ada.

Solusi: Property deprecated

jsx
wp.blocks.registerBlockType('ourplugin/are-you-paying-attention', {
  // ...
  deprecated: [
    {
      // Versi lama: attributes dan save function
      attributes: {
        skyColor: { type: 'string' },
        grassColor: { type: 'string' }
      },
      save: function(props) {
        return (
          <p>Today the sky is {props.attributes.skyColor} and the grass is {props.attributes.grassColor}.</p>
        );
      }
    }
  ],
  // Versi baru (terkini)
  save: function(props) {
    return (
      <h6>Today the sky is {props.attributes.skyColor} and the grass is {props.attributes.grassColor}.</h6>
    );
  }
});

Cara Kerja Deprecated:

  1. WordPress membandingkan HTML di database dengan output save() terkini
  2. Jika tidak cocok, WordPress cek deprecated array (dari terbaru ke terlama)
  3. Jika cocok dengan salah satu versi lama, tidak error — tapi HTML tetap yang lama
  4. User harus buka post dan re-save agar menggunakan struktur baru

Kekurangan:

  • Perlu manual re-save setiap post yang menggunakan block
  • Jika punya 1000 post, harus edit dan save 1000 kali 😱

Dynamic Blocks — Solusi Terbaik

Konsep

Alih-alih menyimpan HTML di database (static), hanya simpan attributes dan biarkan PHP menghasilkan HTML saat halaman dimuat.

Key Changes:

1. save() mengembalikan null

jsx
wp.blocks.registerBlockType('ourplugin/are-you-paying-attention', {
  // ...
  save: function() {
    return null;  // Tidak ada HTML yang disimpan di database
  }
});

2. Ubah action hook dari enqueue_block_editor_assets ke init

php
function __construct() {
  add_action('init', array($this, 'adminAssets'));  // ← 'init' bukan 'enqueue_block_editor_assets'
}

3. Gunakan wp_register_script() (bukan enqueue)

php
function adminAssets() {
  wp_register_script(
    'ournewblocktype',
    plugin_dir_url(__FILE__) . 'build/index.js',
    array('wp-blocks', 'wp-element')
  );

4. register_block_type() dengan render_callback

php
  register_block_type('ourplugin/are-you-paying-attention', array(
    'editor_script' => 'ournewblocktype',
    'render_callback' => array($this, 'theHTML')
  ));
}

5. PHP Render Callback

php
function theHTML($attributes) {
  ob_start(); ?>
  <p>Today the sky is <?php echo esc_html($attributes['skyColor']); ?> 
     and the grass is <?php echo esc_html($attributes['grassColor']); ?>.</p>
  <?php return ob_get_clean();
}

Pattern ob_start() / ob_get_clean()

php
ob_start();          // Mulai output buffering (tangkap semua output)
// ... HTML/PHP ...
return ob_get_clean();  // Ambil buffer dan bersihkan

Ini memungkinkan kamu menulis HTML biasa (bukan string concatenation) dan mengembalikan hasilnya sebagai string.


Perbandingan: Static vs Dynamic Blocks

AspekStatic BlockDynamic Block
HTML disimpan di DB?✅ Ya❌ Hanya attributes
Output dihasilkan olehJavaScript (save())PHP (render_callback)
Perlu deprecated?✅ Ya, saat HTML berubah❌ Tidak pernah
Perubahan berlaku ke semua post?❌ Perlu re-save manual✅ Otomatis
Cocok untukBlock sederhana yang jarang berubahBlock kompleks, data dynamic

Opini Brad:

Static save function "borderline useless" untuk situs dengan banyak post. Dynamic blocks jauh lebih praktis karena perubahan desain otomatis berlaku ke semua post tanpa perlu re-save satu-satu.


Data di Database untuk Dynamic Block

html
<!-- wp:ourplugin/are-you-paying-attention {"skyColor":"blue","grassColor":"green"} /-->

Perhatikan: tidak ada HTML content di antara comments. Hanya attributes JSON. PHP yang menangani rendering saat page dimuat.