Skip to content

Templates, Konten Dinamis & Theme Image

Template Files: Dari Database ke Hard Drive

Workflow

  1. Bangun layout di Full Site Editor menggunakan custom blocks
  2. WordPress menyimpan layout di database (wp_posts table)
  3. Copy kode dari database ke file .html di folder templates/
  4. File .html ini menjadi default yang bisa user revert kapan saja

Cara Mendapatkan Kode Template

Opsi 1: Full Site Editor → tiga titik (...) → Export → download zip

Opsi 2: Buka database → tabel wp_posts → halaman terakhir → field post_content


Attribute themeimage untuk Gambar Default

Masalah

Template yang didistribusikan berisi URL gambar yang hanya ada di instalasi kita. User lain tidak punya gambar yang sama di media library mereka.

Solusi: Attribute themeimage

Gunakan attribute custom yang mereferensikan file gambar di folder theme, bukan media upload.

Implementasi di Template File (index.html)

html
<!-- wp:ourBlockTheme/banner -->
<!-- (tanpa imageID dan imgURL — gunakan fallback) -->

<!-- wp:ourBlockTheme/slideshow -->
<!-- wp:ourBlockTheme/slide {"themeimage":"bus.jpeg"} -->
<!-- wp:ourBlockTheme/genericHeading {"text":"An Apple a Day","size":"large"} /-->
<!-- wp:ourBlockTheme/genericButton {"text":"Learn More","linkObject":{"url":"/about"}} /-->
<!-- /wp:ourBlockTheme/slide -->

<!-- wp:ourBlockTheme/slide {"themeimage":"apples.jpeg"} -->
<!-- ... konten slide ... -->
<!-- /wp:ourBlockTheme/slide -->

<!-- wp:ourBlockTheme/slide {"themeimage":"bread.jpeg"} -->
<!-- ... konten slide ... -->
<!-- /wp:ourBlockTheme/slide -->
<!-- /wp:ourBlockTheme/slideshow -->

Perhatikan: themeimage hanya berisi nama file (bukan full path). Path lengkap dikonstruksi di PHP dan JS.


Data dari PHP ke JS

Di functions.php, berikan path folder images ke JavaScript:

php
new JSXBlock("slide", true, array(
    'themeImagePath' => get_theme_file_uri('/images/')
));

JavaScript: useEffect untuk themeimage

js
// our-blocks/slide.js

attributes: {
  // ... imageID, imgURL ...
  themeimage: { type: "string" }
}

function EditComponent(props) {
  // useEffect 1: Cek themeimage pada load pertama
  useEffect(() => {
    if (props.attributes.themeimage) {
      props.setAttributes({
        imgURL: `${slide.themeImagePath}${props.attributes.themeimage}`
      });
    }
  }, []); // Empty array = hanya di initial load

  // useEffect 2: Watch perubahan imageID (user upload gambar sendiri)
  useEffect(() => {
    if (props.attributes.imageID) {
      async function fetchImage() {
        const response = await apiFetch({
          path: `/wp/v2/media/${props.attributes.imageID}`,
          method: "GET"
        });
        props.setAttributes({
          themeimage: "",          // <-- Hapus themeimage!
          imgURL: response.media_details.sizes.page_banner.source_url
        });
      }
      fetchImage();
    }
  }, [props.attributes.imageID]);

  // ...
}

PHP: slide.php

php
<?php
if (!empty($attributes['themeimage'])) {
    $attributes['imgURL'] = get_theme_file_uri('/images/' . $attributes['themeimage']);
}

if (!isset($attributes['imgURL'])) {
    $attributes['imgURL'] = get_theme_file_uri('/images/library-hero.jpg');
}
?>
<!-- ... HTML slide ... -->

Gunakan !empty() bukan !$var — lebih aman di PHP terbaru.


Alur Kerja themeimage

Template di file .html:
  themeimage: "bus.jpeg"

PHP render:
  get_theme_file_uri('/images/bus.jpeg')

Output:
  http://domain.com/wp-content/themes/mytheme/images/bus.jpeg

User upload gambar sendiri:
  imageID berubah → useEffect → themeimage di-reset ke ""
  → imgURL = URL media upload user

Template: front-page.html vs index.html

Pemisahan Homepage & Blog

Setting (Settings → Reading)Template
"A static page" → Homepage: Homefront-page.html
"A static page" → Posts page: Blogindex.html

Langkah Setup

  1. Duplikat index.html → rename menjadi front-page.html
  2. Edit index.html → ganti konten untuk blog listing
  3. Di WordPress Settings → Reading → pilih "A static page"
  4. Homepage: pilih page "Home"
  5. Posts page: pilih page "Blog"

Membuat Template untuk Custom Post Types

Pattern yang Berulang

Untuk setiap template, langkahnya sama:

1. Buat file .html di templates/ folder
2. Isi: header block + placeholder block + footer block
3. Buat PlaceholderBlock di functions.php
4. Buat .js file (sederhana, tanpa JSX)
5. Buat .php file (copy dari theme tradisional)

Contoh: Single Blog Post

templates/single.html

html
<!-- wp:ourBlockTheme/header /-->
<!-- wp:ourBlockTheme/singlePost /-->
<!-- wp:ourBlockTheme/footer /-->

functions.php

php
new PlaceholderBlock("singlePost");

our-blocks/singlePost.js

js
wp.blocks.registerBlockType("ourBlockTheme/singlePost", {
  title: "Fictional University Single Post",
  edit: function() {
    return wp.element.createElement("div",
      { className: "our-placeholder-block" },
      "Single Post Placeholder"
    );
  },
  save: function() { return null; }
});

our-blocks/singlePost.php

php
<?php
// Copy konten dari single.php theme tradisional
// TANPA get_header() dan get_footer()
// TANPA while loop (WP 6.4+ sudah handle otomatis di block theme)
?>

Daftar Template yang Dibuat

File TemplatePlaceholderBlockFungsi
single.htmlsinglePostSingle blog post
page.htmlpageSingle page
index.htmlblogIndexBlog listing
front-page.html— (pakai blocks langsung)Homepage
archive-program.htmlprogramArchiveArchive programs
single-program.htmlsingleProgramSingle program
single-professor.htmlsingleProfessorSingle professor
page-my-notes.htmlmyNotesMy Notes page

Perubahan Penting: WordPress 6.4 — Singular Content

Masalah

Selama 20 tahun, WordPress mengharuskan while loop bahkan untuk konten singular. Di WordPress 6.4, block theme otomatis menjalankan main query loop.

Gejala

Di block theme, halaman singular (single post, page, dll.) kosong/error jika PHP masih menggunakan while (have_posts()).

Solusi

Hapus while loop dari semua file PHP render block singular:

php
<?php
// ❌ SEBELUM (error di block theme WP 6.4+)
while (have_posts()) {
    the_post();
    // ... konten ...
}

// ✅ SESUDAH (langsung tanpa while loop)
// WordPress sudah handle loop untuk kita
// ... konten langsung ...
?>

Catatan: Ini hanya berlaku untuk block theme pada singular content. Archive/listing tetap perlu while loop.


Catatan tentang isset() untuk Single Professor

Untuk file singleprofessor.php, perhatikan span like-box:

php
<!-- Error di PHP terbaru -->
data-like="<?php echo $existQuery->posts[0]->ID; ?>"

<!-- Fix dengan isset -->
data-like="<?php if (isset($existQuery->posts[0]->ID)) echo $existQuery->posts[0]->ID; ?>"

Kesimpulan

KonsepPenjelasan
themeimageAttribute untuk gambar default dari folder theme
get_theme_file_uri()Konstruksi URL gambar yang portabel
front-page.html vs index.htmlPisahkan homepage dan blog listing
PlaceholderBlock per templateCopy PHP dari theme tradisional
WP 6.4 singular changeHapus while loop di block theme singular
!empty()Lebih aman dari !$var untuk cek atribut PHP