Mengembangkan Plugin WordPress Secara Mudah dan Mendalam: Membangun Plugin Kustom Pertama Anda dari Nol.

Baca dalam 4 menit.
2026-03-13
2026-06-03
1,873
Saya mendapatkan komisi ketika Anda berbelanja melalui tautan di bawah ini, tanpa biaya tambahan untuk Anda.

Dasar-Dasar Plugin WordPress dan Lingkungan Pengembangan

Sebelum memulai menulis kode, sangat penting untuk memahami konsep dasar plugin WordPress dan membangun lingkungan pengembangan yang sesuai. Sebuah plugin WordPress pada dasarnya adalah sebuah folder yang berisi kode PHP, yang digunakan untuk memperluas fungsi-fungsi inti WordPress melalui API yang tersedia. Ukuran plugin bisa sangat kecil (hanya berupa beberapa baris kode singkat) atau sangat besar (bahkan mencakup sistem manajemen yang lengkap). Prinsip utama pengembangan plugin WordPress adalah “tidak mengubah kode inti”, sehingga fitur kustom yang Anda buat tidak akan hilang saat WordPress diperbarui.

Untuk pengembangan yang efisien, Anda memerlukan lingkungan pengembangan lokal. Anda dapat menggunakan alat-alat seperti XAMPP, MAMP, Local by Flywheel, atau Docker untuk dengan cepat membangun server yang mencakup PHP dan MySQL. Setelah itu, instalasi versi terbaru dari WordPress. Selama proses pengembangan, disarankan untuk…wp-config.phpAktifkan di dalam file.WP_DEBUGHal ini dilakukan untuk segera mengungkapkan kesalahan (error) yang terjadi.

“Jantung” dari sebuah plugin adalah sebuah file PHP utama. Komentar di bagian awal file tersebut berfungsi sebagai “kartu identitas” plugin tersebut; WordPress menggunakan informasi meta ini untuk mengenali dan mengelola plugin di latar belakang. Berikut adalah contoh komentar di bagian awal file utama plugin yang standar:

推荐阅读 Apa itu tema WordPress?

<?php
/**
 * Plugin Name: 我的第一个自定义插件
 * Plugin URI:  https://example.com/my-first-plugin
 * Description: 这是一个用于学习插件开发的简单插件,它将在文章末尾添加自定义内容。
 * Version:     1.0.0
 * Author:      开发者名称
 * License:     GPL v2 or later
 * Text Domain: my-first-plugin
 */

Buatlah plugin fungsional pertamamu.

Mari kita mulai dengan sebuah fungsi praktis: menambahkan secara otomatis teks kustom di akhir setiap artikel di situs web. Contoh ini akan menjadi inti dari proses pengembangan plugin.

UltaHost – Hosting untuk WordPress
Jaminan pengembalian uang dalam 30 hari, bandwidth dan basis data yang tidak terbatas, perlindungan DDoS gratis, diskon 50% untuk pembelian selama 3 tahun (dari harga normal: 50%).

File utama plugin dan proses inisialisasi

Pertama-tama, di WordPress…wp-content/pluginsBuat folder baru di bawah direktori, misalnyamy-first-pluginDalam folder tersebut, buatlah file PHP utama. File tersebut dapat diberi nama…my-first-plugin.phpSilakan salin kode komentar di atas dan masukkannya ke dalam teks yang diinginkan.

Selanjutnya, kita memerlukan cara yang aman untuk menjalankan kode inisialisasi plugin. Praktik terbaik adalah mengemas semua fungsi dalam sebuah kelas, atau menggunakan fungsi yang berada dalam namespace. Di sini, kita akan menggunakan sebuah kelas sederhana untuk mengorganisir kode tersebut. Setelah komentar di bagian awal file utama, tambahkan definisi kelas berikut:

if ( ! defined( 'ABSPATH' ) ) {
	exit; // 防止直接访问文件
}

class My_First_Plugin {
    public function __construct() {
        // 构造函数,在这里挂载钩子
    }
}

// 初始化插件
new My_First_Plugin();

if ( ! defined( ‘ABSPATH’ ) )Baris kode ini merupakan standar keamanan dalam pengembangan plugin WordPress, yang digunakan untuk mencegah pengguna mengakses file plugin Anda langsung melalui URL.

Menggunakan “hook” untuk menambahkan konten bagian kaki (footer) pada halaman artikel

Arsitektur plugin WordPress didasarkan pada sistem “Hook”, yang terbagi menjadi Action dan Filter. Action memungkinkan Anda untuk menjalankan kode pada saat tertentu, sedangkan Filter memungkinkan Anda untuk memodifikasi data.

推荐阅读 Panduan Akhir untuk Mengoptimalkan Kinerja Situs Web WordPress: Dari Konfigurasi Dasar hingga Analisis Lengkap tentang Plugin Penyimpanan Cache

Tujuan kami adalah menambahkan teks di belakang isi artikel; ini merupakan proses “penyaringan” konten. Oleh karena itu, kami akan menggunakan…the_contentFilter ini. Modifikasi konstruktor dan metode dalam kelasnya sebagai berikut:

class My_First_Plugin {
    public function __construct() {
        // 将自定义方法挂载到‘the_content’过滤器上
        add_filter( 'the_content', array( $this, 'add_footer_to_content' ) );
    }

/**
     * 在文章内容后添加自定义页脚
     *
     * @param string $content 原始文章内容。
     * @return string 修改后的文章内容。
     */
    public function add_footer_to_content( $content ) {
        // 确保只在主循环的单篇文章页面显示
        if ( is_single() &amp;&amp; in_the_loop() &amp;&amp; is_main_query() ) {
            $custom_footer = '<div class="my-plugin-footer"><p>Terima kasih telah membaca artikel ini! Dibuat oleh [My First Plugin].</p></div>';
            $content .= $custom_footer;
        }
        return $content;
    }
}

add_filter()Fungsi tersebut akan menggunakan metode kelas (class method).add_footer_to_contentDaftar kethe_contentFilter: Ketika WordPress bersiap untuk menghasilkan konten artikel, metode kita akan dipanggil dan konten asli akan diteruskan ke metode tersebut. Kami menggunakan penilaian kondisional untuk memastikan bahwa hanya halaman artikel saja yang akan ditambahkan dengan bagian kaki (footer), sehingga halaman utama dan halaman arsip tidak akan ditampilkan dengan bagian kaki yang sama. Setelah itu, HTML kustom akan ditambahkan ke akhir konten dan hasilnya dikembalikan.

Menambahkan opsi panel administrasi untuk plugin

Sebuah plugin yang matang biasanya memungkinkan pengguna untuk melakukan konfigurasi di belakang layar. Kita akan menambahkan opsi pengaturan sederhana untuk teks kaki halaman yang baru saja kita buat, sehingga pengguna dapat mengatur teks yang ingin ditampilkan secara custom.

hosting.com hosting bersama
Kinerja tinggi, dilengkapi dengan CPU AMD EPYC, penyimpanan SSD NVMe, dan LiteSpeed, dukungan internal ahli 24 jam sehari, langkah-langkah keamanan canggih termasuk SSL, brute force, malware, dan perlindungan DDoS, menghemat hingga 731 TB/bulan.

Create a settings menu page.

Kami perlu menambahkan sebuah halaman anak (sub-page) di bawah menu “Settings” (Pengaturan) di panel administrasi WordPress. Untuk melakukan ini, kami perlu menggunakan…add_options_page()Fungsi tersebut biasanya “ditempatkan” (dimount) di…admin_menuDi hook aksi tersebut.

Pertama-tama, tambahkan sebuah metode baru dalam kelas plugin untuk mendaftarkan menu dan halaman:

class My_First_Plugin {
    // ... 之前的构造函数和方法 ...

public function __construct() {
        add_filter( 'the_content', array( $this, 'add_footer_to_content' ) );
        // 挂载后台管理菜单
        add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
        // 挂载初始化设置选项
        add_action( 'admin_init', array( $this, 'settings_init' ) );
    }

public function add_admin_menu() {
        add_options_page(
            '我的第一个插件设置', // 页面标题
            '自定义页脚设置',     // 菜单标题
            'manage_options',     // 所需权限
            'my-first-plugin',    // 菜单slug
            array( $this, 'options_page_html' ) // 回调函数,用于输出页面HTML
        );
    }
}

Field untuk pengaturan pendaftaran dan halaman yang ditampilkan (rendered page)

Selanjutnya, kita perlu menggunakan WordPress Settings API untuk secara aman mendaftarkan, menyimpan, dan memverifikasi opsi tersebut. Proses ini melibatkan…register_setting(), add_settings_section()add_settings_field()Fungsi-fungsi seperti itu.

推荐阅读 Apa itu WooCommerce? Penjelasan lengkap tentang fitur-fitur inti dan skenario penggunaannya.

public function settings_init() {
    // 注册一个设置选项组
    register_setting( 'my_first_plugin_settings', 'my_first_plugin_options' );

// 在页面中添加一个设置区域
    add_settings_section(
        'my_first_plugin_section',
        '页脚内容配置',
        array( $this, 'section_callback' ),
        'my-first-plugin'
    );

// 向该区域添加一个字段
    add_settings_field(
        'footer_text',
        '页脚显示文本',
        array( $this, 'footer_text_field_render' ),
        'my-first-plugin',
        'my_first_plugin_section'
    );
}

public function section_callback() {
    echo '<p>Di sini, Anda dapat mengonfigurasi teks yang akan ditampilkan di akhir artikel.</p>';
}

public function footer_text_field_render() {
    $options = get_option( 'my_first_plugin_options' );
    $value = $options['footer_text'] ?? '感谢阅读本文!由【我的第一个插件】生成。'; // 默认值
    ?&gt;
    <input type='text' name='my_first_plugin_options[footer_text]' value='<?php echo esc_attr( $value ); ?>' style='width: 400px;'>
    <p class="description">Mendukung tag HTML sederhana, seperti <strong>, <em>, <a>。<p></p>
    <?php
}

public function options_page_html() {
    // 检查用户权限
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }
    ?>
    <div class="wrap">
        <h1>\n</h1>
        <form action='/id/options.php/' method='post' data-trp-original-action="options.php">
            <?php
            settings_fields( 'my_first_plugin_settings' );
            do_settings_sections( 'my-first-plugin' );
            submit_button();
            ?>
        <input type="hidden" name="trp-form-language" value="id"/></form>
    </div>
    \n&lt;?php
}

Terakhir, modifikasi fungsi output di sisi frontend.add_footer_to_contentGunakan fitur tersebut untuk membaca teks dari opsi basis data.

public function add_footer_to_content( $content ) {
    if ( is_single() &amp;&amp; in_the_loop() &amp;&amp; is_main_query() ) {
        $options = get_option( 'my_first_plugin_options' );
        $footer_text = $options['footer_text'] ?? '感谢阅读本文!由【我的第一个插件】生成。';
        $custom_footer = '<div class="my-plugin-footer"><p>'`. wp_kses_post($footer_text)`.'</p></div>';
        $content .= $custom_footer;
    }
    return $content;
}

wp_kses_post()Fungsi tersebut memastikan bahwa hanya tag HTML yang aman yang diizinkan muncul dalam teks yang dimasukkan oleh pengguna, yang merupakan langkah penting dalam hal keamanan.

Hosting bersama InterServer.
Hosting bersama seharga $2,50 USD per bulan, diskon $0,1 USD untuk bulan pertama dengan kode promo tryinterserver, serta 461 skrip aplikasi cloud yang dapat diinstal dengan sekali klik.

Internasionalisasi Plugin dan Praktik Terbaik

Agar plugin dapat digunakan oleh pengguna di seluruh dunia, internasionalisasi (i18n) merupakan langkah yang sangat penting. WordPress menggunakan kerangka kerja GNU gettext untuk melakukan proses penerjemahan.

Field for user input and translation function

Pertama-tama, pastikan bahwa definisi tersebut telah didefinisikan dalam komentar di bagian awal kode plugin Anda.Text DomainContohnya,my-first-pluginKemudian, di semua bagian dalam plugin yang memerlukan penerjemahan, gunakan fungsi khusus untuk membungkus (mengelilingi) string tersebut.

Ubah kode kita sebelumnya untuk menambahkan dukungan terhadap penerjemahan teks yang dihasilkan.

// 在构造函数中加载翻译文件
public function __construct() {
    // ... 其他钩子 ...
    add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
}

public function load_textdomain() {
    load_plugin_textdomain(
        'my-first-plugin',
        false,
        dirname( plugin_basename( __FILE__ ) ) . '/languages/'
    );
}

// 修改设置页面的字符串
public function section_callback() {
    echo '<p>' . esc_html__( '在这里配置显示在文章末尾的文本内容。', 'my-first-plugin' ) . '</p>';
}

public function footer_text_field_render() {
    $options = get_option( 'my_first_plugin_options' );
    $value = $options['footer_text'] ?? __( '感谢阅读本文!由【我的第一个插件】生成。', 'my-first-plugin' );
    ?&gt;
    <input type='text' name='my_first_plugin_options[footer_text]' value='<?php echo esc_attr( $value ); ?>' style='width: 400px;'>
    <p class="description">&lt;?php esc_html_e( &#039;支持简单的HTML标签,如 <strong>, <em>, <a>。', 'my-first-plugin' ); ?&gt;</p>
    &lt;?php
}

// 注意:用户在前台输入的“页脚文本”本身通常不需要翻译,因为它是由管理员设置的具体内容。

__()Digunakan untuk menerjemahkan dan mengembalikan sebuah string.esc_html__()Digunakan untuk menerjemahkan dan mengubah format output HTML menjadi format yang dapat ditampilkan dengan benar di berbagai perangkat._e()Fungsi ini digunakan untuk menerjemahkan dan langsung menampilkan sebuah string. Parameter kedua dari fungsi tersebut adalah bidang teks (text field), yang harus sesuai dengan definisi yang diberikan oleh plugin.

Keamanan, Kinerja, dan Organisasi Kode

Selain internasionalisasi, Anda juga perlu mengikuti praktik terbaik berikut:
1. 安全:对所有用户输入进行验证、清理和转义。使用sanitize_text_field(), esc_html(), wp_kses_post()Fungsi-fungsi seperti itu. Gunakanlah.wp_nonce_field()Mencegah serangan CSRF (Cross-Site Request Forgery).
2. 性能:合理使用钩子,避免在每次页面加载时执行不必要的数据库查询。可以考虑对输出结果进行 transient 缓存。
3. 代码组织:对于复杂的插件,应将文件按功能模块拆分。主文件负责引导,类和方法放在includes/Daftar isi; Aset front-end (CSS, JS) diletakkan di…assets/Indeks.
4. 卸载清理:如果你的插件创建了数据库表或选项,应该提供卸载功能来清理数据。可以通过一个独立的uninstall.phpFile tersebut digunakan untuk melaksanakan (implementasi) fungsi tertentu.

Menyimpulkan.

Dalam tutorial ini, kita telah menyelesaikan seluruh proses pengembangan plugin WordPress kustom yang memiliki fungsi dasar: mulai dari membangun lingkungan pengembangan, membuat kerangka dasar plugin, menambahkan fitur menggunakan sistem hook, mengimplementasikan halaman pengaturan di backend, hingga mencakup aspek internasionalisasi dan praktik keamanan. Anda telah belajar cara melakukannya.add_filteradd_actionBerinteraksi dengan inti WordPress, bagaimana menggunakan API Settings untuk membuat halaman opsi yang andal, serta bagaimana melakukannya…load_plugin_textdomainPastikan bahwa plugin yang Anda buat mendukung berbagai bahasa. Ingatlah bahwa saat mengembangkan plugin, aspek keamanan, kemudahan pemeliharaan (maintainability), dan pengalaman pengguna (user experience) merupakan faktor utama yang perlu dipertimbangkan. Dengan dasar ini, Anda dapat terus mengeksplorasi fitur-fitur lebih lanjut seperti jenis artikel khusus, metadata, kode singkat (shortcodes), dan endpoint REST API, untuk membuat ekstensi WordPress yang lebih kuat.

FAQ - Pertanyaan yang Sering Diajukan.

Mengapa plugin saya tidak terlihat di menu latar belakang?

Ini biasanya disebabkan oleh masalah hak akses atau kesalahan kode. Pertama-tama, pastikan bahwa…add_options_pageadd_menu_pageParameter hak akses yang ditentukan dalam fungsi (seperti…)‘manage_options’Hal tersebut sesuai dengan peran pengguna yang Anda gunakan saat saat ini. Selanjutnya, periksa…admin_menuApakah hook tersebut terpasang dengan benar, dan apakah fungsi callback tidak mengandung kesalahan sintaks yang menyebabkan eksekusi PHP terhenti? Cara termudah adalah dengan mengaktifkannya melalui panel administrasi WordPress.WP_DEBUGPeriksa apakah ada pesan kesalahan yang terkait yang ditampilkan.

Bagaimana cara menambahkan file CSS dan JavaScript khusus (custom) untuk sebuah plugin?

Cara yang benar adalah dengan menggunakan…wp_enqueue_style()wp_enqueue_script()Fungsi tersebut. Untuk sumber daya front-end, harus diunggah (dimount) ke…wp_enqueue_scriptsDi hook aksi; untuk sumber daya di backend manajemen, maka akan di-mount (dipasang) ke sana.admin_enqueue_scriptsDi atas kait itu.

Di dalam kelas plugin Anda, Anda dapat menambahkan metode berikut:

public function enqueue_frontend_assets() {
    wp_enqueue_style( ‘my-plugin-style’, plugin_dir_url( __FILE__ ) . ‘assets/css/style.css’, array(), ‘1.0.0’ );
}

Kemudian, dalam fungsi konstruktor, hal tersebut dilakukan melalui…add_action( ‘wp_enqueue_scripts’, array( $this, ‘enqueue_frontend_assets’ ) );Daftarkan diri. Dengan cara ini, pengelolaan dependensi dapat dilakukan dengan benar, dan tidak akan terjadi konflik dengan plugin atau tema lainnya.

Bagaimana cara membersihkan opsi data yang saya buat ketika pengguna menguninstal plugin tersebut?

WordPress menyediakan dua metode utama untuk melakukan hal tersebut. Yang pertama adalah dengan mendaftarkan sebuah “uninstall hook” (pemicu proses pengunduhan/penghapusan plugin), namun metode ini tidak sering digunakan dalam plugin yang berbasis pendekatan objek (object-oriented). Metode yang lebih disarankan dan juga lebih standar adalah dengan membuat sebuah…uninstall.phpFile tersebut berada pada tingkat yang sama dengan file plugin utama Anda.

Ketika pengguna menghapus plugin melalui panel administrasi WordPress, WordPress akan secara otomatis memeriksa dan menjalankan file yang terkait dengan plugin tersebut.uninstall.phpDi dalamnya, Anda perlu memeriksa terlebih dahulu.WP_UNINSTALL_PLUGINApakah konstanta tersebut telah didefinisikan terlebih dahulu, sehingga semua opsi yang dibuat oleh plugin, tabel basis data yang disesuaikan, dan data lainnya dapat dihapus dengan aman?

if ( ! defined( ‘WP_UNINSTALL_PLUGIN’ ) ) {
    exit;
}
delete_option( ‘my_first_plugin_options’ );
// 如果有自定义表:$wpdb->query( “DROP TABLE IF EXISTS {$wpdb->prefix}my_table” );

Bagaimana cara agar plugin saya kompatibel dengan lebih banyak versi WordPress?

Kunci untuk menjaga kompatibilitas adalah dengan menggunakan fungsi dan fitur versi baru dengan hati-hati, serta menyediakan alternatif untuk versi lama. Sebelum memanggil sebuah fungsi yang mungkin hanya ada di versi baru, pastikan untuk memeriksa terlebih dahulu.function_exists()Lakukan pemeriksaan. Misalnya, jika Anda ingin menggunakan fitur yang diperkenalkan dalam versi 5.0…wp_dateFungsi dapat:

if ( function_exists( ‘wp_date’ ) ) {
    $date = wp_date( get_option( ‘date_format’ ), $timestamp );
} else {
    $date = date_i18n( get_option( ‘date_format’ ), $timestamp );
}

Sementara itu, cantumkan dengan jelas versi WordPress terendah yang telah diuji dalam komentar di bagian atas plugin dan dalam file readme. Melakukan pengujian secara teratur pada versi WordPress yang lebih lama merupakan cara terbaik untuk memastikan kompatibilitas.