Kalau Anda sudah bekerja dengan WordPress cukup lama, ada satu momen yang pasti pernah terjadi: klien minta fitur konten yang tidak cocok masuk ke “Post” biasa, tapi juga tidak pas jadi “Page”. Portofolio. Testimoni. Properti. Resep. Anggota tim.
Solusi yang paling banyak disarankan di forum adalah install plugin seperti Custom Post Type UI. Cepat, mudah, tidak perlu kode. Tapi untuk developer yang peduli performa dan kebersihan kode, ada trade-off yang perlu dipikirkan: satu plugin lagi yang harus di-maintain, satu dependency tambahan, dan overhead yang tidak perlu untuk sesuatu yang bisa diselesaikan dengan 40 baris PHP.
Membuat custom post type secara manual jauh lebih bersih. Dan tidak serumit yang dibayangkan.
Kenapa Pilih Tanpa Plugin?
Ini bukan tentang anti-plugin. Jika Anda sudah tahu apa itu WordPress dan cara kerjanya, Anda tahu bahwa plugin adalah kekuatan besar sekaligus beban potensial. Setiap plugin aktif menambahkan kode yang dieksekusi di setiap page load.
Argumen untuk CPT manual:
- Tidak ada overhead plugin — kode Anda, hanya berjalan saat dibutuhkan
- Tidak ada dependency — situs tidak rusak jika plugin CPT dihapus atau tidak kompatibel
- Kontrol penuh atas argumen — tidak ada UI yang membatasi apa yang bisa dikonfigurasi
- Lebih mudah di-version control — kode di child theme masuk Git, konfigurasi plugin tidak
Perbandingan ini juga relevan ketika memutuskan platform. Kemampuan extend WordPress secara native — tanpa plugin — adalah salah satu alasan utama kenapa banyak developer tetap memilih WordPress dibanding WordPress vs platform lain seperti Webflow atau Wix yang lebih terbatas secara teknis.
Persiapan: Jangan Langsung Edit functions.php Tema Aktif
Ini poin yang tidak bisa dilewatkan. Menambahkan kode langsung ke functions.php tema aktif adalah kebiasaan yang menyebabkan dua masalah: kode hilang ketika tema diupdate, dan debugging menjadi mimpi buruk karena semua kode tercampur.

Cara yang benar adalah menggunakan WordPress child theme. Semua kode kustom — termasuk CPT — diletakkan di functions.php child theme. Ketika tema induk diupdate, kode Anda aman.
Alternatif yang lebih bersih lagi: buat file terpisah khusus untuk CPT, lalu include dari functions.php:
// Di functions.php child theme Anda
// Muat file registrasi CPT secara terpisah
require_once get_stylesheet_directory() . '/inc/custom-post-types.php';
Struktur ini memisahkan tanggung jawab dan membuat kode lebih mudah dikelola. Tim kami di Codefid selalu menggunakan pendekatan ini saat membangun situs WordPress dengan struktur konten kustom — jauh lebih rapi dibanding menumpuk semua kode di satu file.
Kode Dasar: register_post_type()
Fungsi utama yang digunakan adalah register_post_type(), dipanggil melalui hook init. Berikut contoh lengkap untuk CPT “Portofolio”:
/**
* Mendaftarkan Custom Post Type: Portofolio
* Diletakkan di functions.php child theme atau file inc/custom-post-types.php
*/
function codefid_register_portfolio_cpt() {
$labels = array(
'name' => 'Portofolio',
'singular_name' => 'Portofolio',
'menu_name' => 'Portofolio',
'add_new' => 'Tambah Baru',
'add_new_item' => 'Tambah Portofolio Baru',
'edit_item' => 'Edit Portofolio',
'new_item' => 'Portofolio Baru',
'view_item' => 'Lihat Portofolio',
'search_items' => 'Cari Portofolio',
'not_found' => 'Portofolio tidak ditemukan',
'not_found_in_trash' => 'Tidak ada portofolio di sampah',
'all_items' => 'Semua Portofolio',
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'portofolio' ),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => 5,
'menu_icon' => 'dashicons-portfolio',
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields' ),
'show_in_rest' => true, // Wajib untuk Gutenberg dan REST API
);
register_post_type( 'portfolio', $args );
}
add_action( 'init', 'codefid_register_portfolio_cpt' );
Setelah kode ini ditambahkan, refresh halaman WordPress admin Anda — menu “Portofolio” akan muncul di sidebar kiri dashboard.
Memahami Argumen yang Paling Penting
Tidak semua argumen perlu diubah, tapi beberapa krusial dan sering disalahpahami:
public vs publicly_queryable
Menetapkan 'public' => true adalah shortcut yang mengaktifkan beberapa argumen sekaligus: show_in_nav_menus, show_ui, show_in_admin_bar, dan publicly_queryable. Kalau Anda butuh CPT yang hanya terlihat di admin tapi tidak accessible via URL publik — misalnya untuk data internal — set 'public' => false dan atur argumen masing-masing secara eksplisit.
hierarchical
Jika true, CPT ini berperilaku seperti Pages — bisa punya parent-child relationship. Jika false, berperilaku seperti Posts — flat. Untuk portofolio, testimoni, atau produk, biasanya false yang tepat.
show_in_rest
Ini wajib true jika Anda ingin CPT ini bisa diedit menggunakan Gutenberg Block Editor. Jika false, WordPress akan memaksa menggunakan editor lama (Classic Editor) untuk CPT tersebut. Untuk proyek baru, selalu set ini ke true.
rewrite
Argumen ini mengontrol struktur URL. Defaultnya menggunakan nama CPT sebagai slug. Tapi untuk URL yang lebih bersih atau berbahasa Indonesia, tentukan slug secara eksplisit:
// Struktur URL: yourdomain.com/portofolio/nama-item/
'rewrite' => array(
'slug' => 'portofolio',
'with_front' => false, // Jangan tambahkan prefix dari Settings > Permalinks
),
Punya proyek membangun website dengan struktur yang kompleks? Ini adalah area yang membedakan antara site builder dan developer — dan alasan kenapa membuat WordPress theme kustom yang dirancang khusus untuk proyek tertentu sering menghasilkan arsitektur yang jauh lebih bersih daripada mengandalkan tema siap pakai.
Menambahkan Custom Taxonomy
CPT tanpa taxonomy ibarat arsip tanpa kategori. Hampir selalu Anda butuh cara untuk mengelompokkan konten CPT. Ini caranya menambahkan taxonomy kustom untuk CPT portofolio di atas:
/**
* Mendaftarkan Custom Taxonomy: Kategori Portofolio
*/
function codefid_register_portfolio_taxonomy() {
$labels = array(
'name' => 'Kategori Portofolio',
'singular_name' => 'Kategori Portofolio',
'search_items' => 'Cari Kategori',
'all_items' => 'Semua Kategori',
'edit_item' => 'Edit Kategori',
'update_item' => 'Update Kategori',
'add_new_item' => 'Tambah Kategori Baru',
'new_item_name' => 'Nama Kategori Baru',
'menu_name' => 'Kategori',
);
$args = array(
'labels' => $labels,
'hierarchical' => true, // true = seperti Kategori, false = seperti Tag
'public' => true,
'show_ui' => true,
'show_admin_column' => true,
'rewrite' => array( 'slug' => 'kategori-portofolio' ),
'show_in_rest' => true,
);
// Daftarkan taxonomy dan hubungkan ke CPT 'portfolio'
register_taxonomy( 'portfolio_category', array( 'portfolio' ), $args );
}
add_action( 'init', 'codefid_register_portfolio_taxonomy' );
Setelah ini ditambahkan, menu “Kategori” akan muncul di bawah menu Portofolio di admin sidebar.
Satu catatan penting: jika Anda mendaftarkan taxonomy terpisah, pastikan CPT dan taxonomy didaftarkan di hook init yang sama atau dengan prioritas yang benar. Urutan registrasi bisa mempengaruhi apakah hubungan CPT-taxonomy terbaca dengan benar.
Untuk klien dengan kebutuhan jenis konten yang kompleks — seperti perusahaan yang membutuhkan halaman portofolio, layanan, dan testimoni dengan struktur yang berbeda — kami selalu menyarankan arsitektur CPT yang dirancang dari awal. Website yang dibangun dengan Jasa Pembuatan Web Company Profile dari Codefid selalu menggunakan struktur konten yang tepat untuk kebutuhan bisnisnya — bukan sekadar menjejalkan semua konten ke dalam Post default. Berbeda dengan solusi instan yang mengandalkan deretan plugin WordPress berlebih.
Flush Rewrite Rules — Langkah yang Sering Dilupakan
Setelah mendaftarkan CPT baru, WordPress perlu memperbarui tabel rewrite rules-nya agar URL seperti /portofolio/nama-item/ bisa dikenali. Tanpa ini, semua URL CPT akan menghasilkan halaman 404.
Cara paling mudah: masuk ke Settings → Permalinks di wp-admin, lalu klik Save Changes tanpa mengubah apa pun. Ini memaksa WordPress meregenerasi rewrite rules.
Untuk otomatisasi saat theme atau plugin diaktifkan, gunakan hook after_switch_theme atau register_activation_hook:
/**
* Flush rewrite rules saat theme diaktifkan
* Tambahkan di functions.php child theme
*/
function codefid_flush_rewrite_on_activation() {
codefid_register_portfolio_cpt();
flush_rewrite_rules();
}
add_action( 'after_switch_theme', 'codefid_flush_rewrite_on_activation' );
Jangan memanggil flush_rewrite_rules() di dalam hook init secara rutin. Ini operasi yang berat — harus dipanggil hanya sekali saat ada perubahan struktur, bukan di setiap page load.
Menampilkan CPT di Template WordPress
Setelah CPT terdaftar, WordPress otomatis menggunakan template hierarki untuk menampilkannya. Untuk halaman arsip CPT portofolio, WordPress mencari file template dalam urutan berikut:
# Hierarki template untuk arsip CPT 'portfolio'
archive-portfolio.php # Paling spesifik
archive.php # Fallback
index.php # Fallback terakhir
Dan untuk halaman detail item individual:
# Hierarki template untuk single item CPT 'portfolio'
single-portfolio.php # Paling spesifik
single.php # Fallback
index.php # Fallback terakhir
Buat file archive-portfolio.php dan single-portfolio.php di folder child theme Anda, dan desain layout sesuai kebutuhan. Untuk mengambil item CPT dalam query kustom:
// Query CPT portofolio dengan taxonomy filter
$args = array(
'post_type' => 'portfolio',
'posts_per_page' => 12,
'orderby' => 'date',
'order' => 'DESC',
// Filter berdasarkan taxonomy (opsional)
'tax_query' => array(
array(
'taxonomy' => 'portfolio_category',
'field' => 'slug',
'terms' => 'web-design',
),
),
);
$portfolio_query = new WP_Query( $args );
if ( $portfolio_query->have_posts() ) {
while ( $portfolio_query->have_posts() ) {
$portfolio_query->the_post();
// Output konten di sini
}
wp_reset_postdata(); // Selalu reset setelah custom query
}
Banyak sekali manfaat dari CPT ini. Bahkan WooCommerce itu sendiri bisa disebut sebagai custom post type.
Dengan CPT kita bisa membuat dan menghadirkan fitur yang lebih banyak dibandingkan fungsi dari post dari native WordPress itu sendiri.
Contoh kita bisa membuat:
- Portfolio
- Penawaran atau jasa
- Produk tanpa Woo
- dst
Best Practices yang Tidak Bisa Diabaikan
Beberapa hal yang membedakan kode CPT yang aman dan maintainable dari yang asal jalan:
Prefix nama CPT dan taxonomy dengan nama proyek atau brand. Bukan register_post_type('portfolio') tapi register_post_type('namaproyek_portfolio'). Ini mencegah konflik dengan plugin lain yang mungkin menggunakan nama yang sama. Nama maksimal 20 karakter, hanya huruf kecil dan underscore.
Selalu tambahkan kode CPT di child theme, bukan tema induk. Sudah dibahas di awal, tapi penting untuk ditekankan lagi.
Backup sebelum menambahkan kode apa pun. Error di functions.php bisa menyebabkan White Screen of Death. Pastikan selalu punya backup WordPress yang valid sebelum melakukan perubahan kode — terutama di situs live.
Aktifkan WP_DEBUG di environment development. Jangan pernah debug di server produksi. Error PHP akan muncul jelas saat WP_DEBUG aktif, dan ini jauh lebih baik daripada mencari-cari masalah di layar putih.
Perhatikan argumen capability_type. Default 'post' sudah cukup untuk kebanyakan kasus. Tapi jika Anda butuh kontrol akses yang berbeda — misalnya hanya editor tertentu yang bisa mengelola CPT ini — set capability_type kustom dan map capabilities-nya secara eksplisit. Ini juga relevan dari sudut pandang keamanan — struktur capability yang benar mencegah escalation akses yang tidak diinginkan, terutama di situs multi-user. Pertimbangkan juga menggunakan plugin keamanan WordPress yang bisa membantu memonitor aktivitas mencurigakan terkait akses konten.
Kapan Menggunakan Plugin, dan Kapan Harus Minta Bantuan
Jujur: ada kasus di mana plugin CPT masuk akal. Jika klien adalah non-teknis yang mungkin perlu menambah atau mengubah CPT sendiri tanpa developer, UI dari CPT UI Plugin memang memudahkan. Atau jika proyeknya sangat sederhana dan waktu adalah faktor utama.
Tapi untuk proyek yang dibangun untuk jangka panjang, dengan tim developer yang mengelolanya, kode manual selalu lebih baik — lebih ringkas, lebih cepat, lebih mudah di-version control.
Jika kebutuhannya sudah mencakup integrasi REST API kustom, Custom Fields yang kompleks, atau struktur data yang sangat spesifik untuk industri tertentu, ini sudah masuk level Jasa Web Development yang memerlukan arsitektur lebih dalam dari sekadar CPT standar.
Dan jika Anda butuh website WordPress yang sudah berjalan dengan struktur konten kustom yang benar sejak hari pertama — tanpa harus membangunnya sendiri dari nol — tim kami yang menangani Jasa Pembuatan Web WordPress bisa merancang arsitektur CPT, taxonomy, dan template yang sesuai dengan kebutuhan bisnis Anda secara spesifik.
Custom Post Type adalah fondasi dari banyak website WordPress yang serius. Menguasainya tanpa bergantung pada plugin bukan hanya soal preferensi teknis — ini soal membangun website yang benar-benar dimiliki, bukan sekadar dikonfigurasi. Dan jika Anda ingin memulai dengan fondasi yang sudah terbukti, memilih Jasa Pembuatan Website yang bekerja dengan kode bersih dan arsitektur yang terencana adalah investasi yang akan terasa manfaatnya bertahun-tahun ke depan.