Templates, Konten Dinamis & Theme Image
Template Files: Dari Database ke Hard Drive
Workflow
- Bangun layout di Full Site Editor menggunakan custom blocks
- WordPress menyimpan layout di database (
wp_poststable) - Copy kode dari database ke file
.htmldi foldertemplates/ - File
.htmlini 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)
<!-- 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:
themeimagehanya 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:
new JSXBlock("slide", true, array(
'themeImagePath' => get_theme_file_uri('/images/')
));JavaScript: useEffect untuk themeimage
// 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
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 userTemplate: front-page.html vs index.html
Pemisahan Homepage & Blog
| Setting (Settings → Reading) | Template |
|---|---|
| "A static page" → Homepage: Home | front-page.html |
| "A static page" → Posts page: Blog | index.html |
Langkah Setup
- Duplikat
index.html→ rename menjadifront-page.html - Edit
index.html→ ganti konten untuk blog listing - Di WordPress Settings → Reading → pilih "A static page"
- Homepage: pilih page "Home"
- 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
<!-- wp:ourBlockTheme/header /-->
<!-- wp:ourBlockTheme/singlePost /-->
<!-- wp:ourBlockTheme/footer /-->functions.php
new PlaceholderBlock("singlePost");our-blocks/singlePost.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
// 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 Template | PlaceholderBlock | Fungsi |
|---|---|---|
single.html | singlePost | Single blog post |
page.html | page | Single page |
index.html | blogIndex | Blog listing |
front-page.html | — (pakai blocks langsung) | Homepage |
archive-program.html | programArchive | Archive programs |
single-program.html | singleProgram | Single program |
single-professor.html | singleProfessor | Single professor |
page-my-notes.html | myNotes | My 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
// ❌ 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:
<!-- ❌ 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
| Konsep | Penjelasan |
|---|---|
themeimage | Attribute untuk gambar default dari folder theme |
get_theme_file_uri() | Konstruksi URL gambar yang portabel |
front-page.html vs index.html | Pisahkan homepage dan blog listing |
| PlaceholderBlock per template | Copy PHP dari theme tradisional |
| WP 6.4 singular change | Hapus while loop di block theme singular |
!empty() | Lebih aman dari !$var untuk cek atribut PHP |