Współpraca
Blog Jak stworzyć własną wtyczkę w WordPressie
WordPress · · 10 min czytania

Jak stworzyć własną wtyczkę w WordPressie

Krok po kroku od pustego folderu do działającej wtyczki WordPress — nagłówek, hooki, shortcody, settings API i bezpieczne przechowywanie opcji.

WordPress PHP Plugin

Po co pisać własną wtyczkę?

Wtyczka WordPress to samodzielny moduł, który rozszerza funkcjonalność CMS-a niezależnie od aktywnego motywu. Pisanie własnej wtyczki ma sens gdy:

  • chcesz dodać funkcję, która ma działać niezależnie od zmiany motywu
  • tworzysz coś do wielokrotnego użycia na kilku projektach
  • wbudowane wtyczki z repozytorium są zbyt ciężkie lub mają zbyt wiele funkcji
  • potrzebujesz pełnej kontroli nad kodem i aktualizacjami
💡

Własna wtyczka to też dobra praktyka architektoniczna: logika biznesowa (custom post types, shortcody, integracje API) trzymana w wtyczce pozostaje dostępna nawet gdy zmienisz motyw na zupełnie inny.

Struktura katalogów i pliki

Wtyczka WordPress to minimum jeden plik PHP z nagłówkiem. W praktyce dobrze zorganizowana wtyczka wygląda tak:

wp-content/plugins/moja-wtyczka/
├── moja-wtyczka.php          # plik główny (nagłówek + bootstrap)
├── uninstall.php             # czyszczenie przy odinstalowaniu
├── includes/
│   ├── class-moja-wtyczka.php    # główna klasa
│   ├── shortcodes.php
│   ├── ajax.php
│   └── helpers.php
├── admin/
│   ├── admin-page.php
│   └── settings.php
├── assets/
│   ├── css/
│   └── js/
└── languages/
    └── moja-wtyczka.pot

Nagłówek i bootstrap

Plik główny musi zawierać specjalny komentarz PHP, który WordPress rozpoznaje jako nagłówek wtyczki:

<?php
/**
 * Plugin Name:       Moja Wtyczka
 * Plugin URI:        https://twoja-strona.pl/moja-wtyczka
 * Description:       Krótki opis — widoczny w panelu WordPress.
 * Version:           1.0.0
 * Requires at least: 6.0
 * Requires PHP:      8.0
 * Author:            Lucjan Jaroszewski
 * Author URI:        https://twoja-strona.pl
 * License:           GPL v2 or later
 * Text Domain:       moja-wtyczka
 * Domain Path:       /languages
 */

// Zabezpieczenie — blokuje wywołanie pliku bezpośrednio przez URL
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

// Stałe — dostępne w całej wtyczce
define( 'MOJA_WTYCZKA_VERSION', '1.0.0' );
define( 'MOJA_WTYCZKA_DIR',     plugin_dir_path( __FILE__ ) );
define( 'MOJA_WTYCZKA_URL',     plugin_dir_url( __FILE__ ) );

// Bootstrap — załaduj główną klasę
require_once MOJA_WTYCZKA_DIR . 'includes/class-moja-wtyczka.php';

/**
 * Uruchom wtyczkę.
 */
function moja_wtyczka_run(): void {
    $plugin = new Moja_Wtyczka();
    $plugin->run();
}
moja_wtyczka_run();

Aktywacja i deaktywacja

WordPress udostępnia hooki do kodu wykonywanego przy aktywacji, deaktywacji i odinstalowaniu wtyczki. To miejsce na tworzenie tabel bazy danych, opcji domyślnych i flush rewrite rules:

<?php
// W pliku głównym wtyczki

/**
 * Uruchamiane przy aktywacji w panelu WP.
 */
function moja_wtyczka_aktywacja(): void {
    // Utwórz własną tabelę w bazie
    global $wpdb;
    $table_name      = $wpdb->prefix . 'moje_wpisy';
    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE IF NOT EXISTS {$table_name} (
        id         BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
        user_id    BIGINT UNSIGNED NOT NULL DEFAULT 0,
        tresc      TEXT            NOT NULL,
        data_wpisu DATETIME        NOT NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY user_id (user_id)
    ) {$charset_collate};";

    require_once ABSPATH . 'wp-admin/includes/upgrade.php';
    dbDelta( $sql );

    // Ustaw domyślne opcje
    add_option( 'moja_wtyczka_settings', [
        'aktywna' => true,
        'limit'   => 10,
    ]);

    // Wymuś odświeżenie permalinków
    flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'moja_wtyczka_aktywacja' );

/**
 * Uruchamiane przy deaktywacji — NIE usuwaj danych użytkownika.
 */
function moja_wtyczka_deaktywacja(): void {
    flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'moja_wtyczka_deaktywacja' );
⚠️

Nie usuwaj danych użytkownika przy deaktywacji — użytkownik może deaktywować wtyczkę tymczasowo. Dane i opcje usuń dopiero w uninstall.php, gdy użytkownik jawnie odinstaluje wtyczkę przez panel.

Strona ustawień — Settings API

WordPress ma wbudowane Settings API, które obsługuje formularze, walidację i zapisywanie opcji bezpiecznie (z nonce i sanityzacją):

<?php
/**
 * Rejestracja strony ustawień i pól.
 */
function moja_wtyczka_admin_menu(): void {
    add_options_page(
        'Moja Wtyczka — Ustawienia',
        'Moja Wtyczka',
        'manage_options',
        'moja-wtyczka',
        'moja_wtyczka_render_page'
    );
}
add_action( 'admin_menu', 'moja_wtyczka_admin_menu' );

function moja_wtyczka_settings_init(): void {
    register_setting(
        'moja_wtyczka_group',
        'moja_wtyczka_settings',
        [ 'sanitize_callback' => 'moja_wtyczka_sanitize' ]
    );

    add_settings_section(
        'moja_wtyczka_section',
        'Ustawienia ogólne',
        null,
        'moja-wtyczka'
    );

    add_settings_field(
        'limit',
        'Limit wpisów',
        'moja_wtyczka_field_limit',
        'moja-wtyczka',
        'moja_wtyczka_section'
    );
}
add_action( 'admin_init', 'moja_wtyczka_settings_init' );

function moja_wtyczka_field_limit(): void {
    $options = get_option( 'moja_wtyczka_settings', [] );
    $limit   = (int) ( $options['limit'] ?? 10 );
    echo '<input type="number" name="moja_wtyczka_settings[limit]"
          value="' . esc_attr( $limit ) . '" min="1" max="100" />';
}

function moja_wtyczka_sanitize( array $input ): array {
    return [
        'aktywna' => ! empty( $input['aktywna'] ),
        'limit'   => max( 1, min( 100, (int) ( $input['limit'] ?? 10 ) ) ),
    ];
}

function moja_wtyczka_render_page(): void {
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }
    ?>
    <div class="wrap">
        <h1><?= esc_html( get_admin_page_title() ); ?></h1>
        <form method="post" action="options.php">
            <?php
            settings_fields( 'moja_wtyczka_group' );
            do_settings_sections( 'moja-wtyczka' );
            submit_button();
            ?>
        </form>
    </div>
    <?php
}

Bezpieczeństwo first: Zawsze sprawdzaj uprawnienia (current_user_can()), używaj nonce przy własnych formularzach (wp_nonce_field() / check_admin_referer()) i sanityzuj każde wejście użytkownika.

Podsumowanie

Pierwsza własna wtyczka WordPress może wyglądać skomplikowanie, ale wystarczy kilka plików i znajomość kilku wzorców: nagłówek, hooki aktywacyjne, Settings API. Pisząc własne wtyczki zamiast szukania gotowych, zyskujesz pełną kontrolę nad kodem, brakiem zbędnych funkcji i możliwością wielokrotnego użycia w różnych projektach.