Jak stworzyć własny motyw WordPress?

8 minut
How to develop a custom theme in WordPress

Własny motyw WordPress oznacza zbudowanie warstwy prezentacji samodzielnie, zamiast dostosowywania cudzej. W 2026 roku ta decyzja zaczyna się od drugiej: czy budujesz motyw blokowy, klasyczny, czy hybrydę obu. Odpowiedź zmienia to, jakich plików potrzebujesz, gdzie mieszka warstwa stylów i jaką kontrolę dostają redaktorzy. Ten przewodnik opisuje obie ścieżki, wymagane pliki, hierarchię szablonów oraz praktyki bezpieczeństwa i testowania, które odróżniają motyw do utrzymania od takiego, który za rok napiszesz od nowa.

Jaki rodzaj motywu wybrać?

WordPress obsługuje dwie architektury motywów i nie są one wymienne.

Motywy blokowe definiują szablony jako pliki HTML złożone z bloków, ze stylami scentralizowanymi w pliku theme.json. Redaktorzy zmieniają układ i szablony przez edytor witryny, bez dotykania kodu. To kierunek rozwoju platformy, a domyślne motywy WordPressa są blokowe od wersji Twenty Twenty-Two.

Motywy klasyczne definiują szablony jako pliki PHP i stylują je zwykłym CSS-em. Dają precyzyjną kontrolę nad tym, co się ładuje, i opierają się na hierarchii, którą większość programistów WordPressa już zna. Pozostają uzasadnionym wyborem, zwłaszcza gdy chcesz ograniczyć zakres zmian dostępny dla redakcji.

Motywy hybrydowe to motywy klasyczne korzystające z theme.json do zdefiniowania tokenów projektowych, bez przenoszenia szablonów do edytora witryny. W praktyce to częste i pragmatyczne rozwiązanie: dostajesz system projektowy respektowany przez edytor bloków, zachowując szablony w PHP.

Wybierz motyw blokowy, gdy redakcja potrzebuje realnej kontroli nad układem, a projekt da się wyrazić blokami. Wybierz klasyczny lub hybrydowy, gdy szablony zawierają rozbudowaną logikę, gdy potrzebujesz ścisłej kontroli nad tym, co się ładuje, albo gdy klient wprost oczekuje ograniczonego zakresu edycji.

Jakie pliki są faktycznie wymagane?

Minimum zależy od wybranej architektury.

Typ motywuWymaganeZalecane
Blokowystyle.css, templates/index.htmltheme.json, parts/header.html, parts/footer.html, functions.php
Klasycznystyle.css, index.phpfunctions.php, header.php, footer.php, theme.json

style.css jest wymagany w obu przypadkach, bo to jego nagłówek pozwala WordPressowi rozpoznać motyw:

css

/*
Theme Name: Acme
Theme URI: https://example.com/acme
Author: Acme
Description: Motyw dedykowany dla Acme.
Version: 1.0.0
Requires at least: 6.6
Requires PHP: 8.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: acme
*/

Bez tego nagłówka WordPress nie pokaże katalogu na liście motywów.

Struktura motywu blokowego wygląda zwykle tak:

acme/
  style.css
  theme.json
  functions.php
  templates/
    index.html
    single.html
    page.html
    archive.html
    404.html
  parts/
    header.html
    footer.html
  patterns/
    hero.php
  styles/
    dark.json

Motyw klasyczny trzyma szablony jako pliki PHP w katalogu głównym: index.php, single.php, page.php, archive.php, search.php, 404.php, plus header.php i footer.php jako części wspólne.

Jak poprawnie przygotować functions.php?

functions.php zachowuje się jak wtyczka dołączona do motywu. Dwie zasady wywołują więcej nieporozumień niż cokolwiek innego w tworzeniu motywów, więc warto je podać wprost.

Otwierający znacznik <?php jest wymagany. Zamykającego ?> nie umieszczamy, ponieważ znaki puste po nim mogą wygenerować wyjście przed wysłaniem nagłówków i zepsuć serwis w sposób trudny do zdiagnozowania.

php

<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

add_action( 'after_setup_theme', 'acme_setup' );
function acme_setup() {
	add_theme_support( 'post-thumbnails' );
	add_theme_support( 'title-tag' );
	add_theme_support( 'html5', array( 'search-form', 'comment-form', 'gallery', 'caption' ) );
	load_theme_textdomain( 'acme', get_template_directory() . '/languages' );
}

add_action( 'wp_enqueue_scripts', 'acme_assets' );
function acme_assets() {
	$stylesheet = get_stylesheet_directory() . '/style.css';

	wp_enqueue_style(
		'acme-style',
		get_stylesheet_uri(),
		array(),
		file_exists( $stylesheet ) ? filemtime( $stylesheet ) : '1.0.0'
	);
}

Dwie rzeczy warte zapamiętania. Poprzedzaj nazwy funkcji prefiksem, bo przestrzeń nazw jest wspólna z wtyczkami i rdzeniem. Wersjonuj zasoby przez filemtime(), a nie stałym ciągiem, żeby przeglądarki pobierały zmiany bez ręcznej podbitki wersji.

Nigdy nie wpinaj arkuszy stylów i skryptów bezpośrednio w kod szablonu. Kolejkowanie pozwala WordPressowi i warstwie cache zarządzać zależnościami i kolejnością ładowania.

Jak działa theme.json?

theme.json to miejsce, w którym współczesny motyw deklaruje swój system projektowy. WordPress odczytuje ten plik i generuje właściwości niestandardowe CSS, dzięki czemu te same wartości obowiązują na froncie i w edytorze, bez utrzymywania dwóch arkuszy.

json

{
	"$schema": "https://schemas.wp.org/wp/6.6/theme.json",
	"version": 3,
	"settings": {
		"appearanceTools": true,
		"layout": {
			"contentSize": "720px",
			"wideSize": "1200px"
		},
		"color": {
			"custom": false,
			"palette": [
				{ "slug": "base", "color": "#ffffff", "name": "Podstawowy" },
				{ "slug": "contrast", "color": "#111111", "name": "Kontrastowy" },
				{ "slug": "accent", "color": "#0b5cff", "name": "Akcent" }
			]
		},
		"typography": {
			"fluid": true,
			"customFontSize": false
		}
	},
	"styles": {
		"color": {
			"background": "var(--wp--preset--color--base)",
			"text": "var(--wp--preset--color--contrast)"
		}
	}
}

Trzy uwagi.

Klucz version nie oznacza wersji WordPressa. Wskazuje schemat, według którego WordPress interpretuje plik. Wersja 3 wymaga WordPressa 6.6 lub nowszego, wersja 2 jest domyślna od 5.9. Linię $schema ustaw na minimalną wersję WordPressa wspieraną przez motyw, żeby edytor walidował plik względem właściwego zestawu funkcji.

theme.json działa również w motywach klasycznych. Nie musisz przebudowywać motywu, żeby z niego skorzystać. Dodanie pliku daje system projektowy respektowany przez edytor bloków, czyli opisane wcześniej podejście hybrydowe.

Ustawienie custom: false dla kolorów, a analogicznie dla typografii i odstępów, usuwa z edytora dowolne selektory wartości. To sposób na utrzymanie systemu projektowego w całości, gdy zespół marketingu zaczyna publikować.

Czym jest hierarchia szablonów?

Hierarchia szablonów decyduje o tym, który plik obsłuży dane żądanie. WordPress sprawdza pliki od najbardziej szczegółowego do najbardziej ogólnego i używa pierwszego dopasowania.

Dla pojedynczego wpisu kolejność wygląda tak: single-{typ}-{slug}, potem single-{typ}, single, singular, na końcu index. Ta sama logika obowiązuje dla archiwów, taksonomii, autorów i wyników wyszukiwania.

Hierarchia jest identyczna w obu architekturach. Zmienia się tylko rozszerzenie: single.php w motywie klasycznym, templates/single.html w blokowym.

Dwa praktyczne wnioski. Po pierwsze, index jest zawsze istniejącym zabezpieczeniem i dlatego to jedyny wymagany szablon. Po drugie, twórz tylko te szablony, w których zachowanie faktycznie się różni. Dodanie category.php identycznego z archive.php daje drugi plik do utrzymania i zero korzyści.

Jak wyświetlać treść dynamiczną?

W motywie klasycznym treść renderuje pętla.

php

<?php if ( have_posts() ) : ?>

	<?php while ( have_posts() ) : the_post(); ?>
		<article <?php post_class(); ?>>
			<h2>
				<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
			</h2>
			<?php the_excerpt(); ?>
		</article>
	<?php endwhile; ?>

	<?php the_posts_pagination(); ?>

<?php else : ?>

	<p><?php esc_html_e( 'Nic nie znaleziono.', 'acme' ); ?></p>

<?php endif; ?>

Znaczniki szablonów w rodzaju the_title() i the_content() wypisują dane bezpośrednio. Ich odpowiedniki z przedrostkiem get_ zwracają wartość, co jest potrzebne wtedy, gdy przed wyświetleniem trzeba ją przetworzyć.

Dla treści spoza zapytania głównego użyj WP_Query i zawsze zresetuj dane po zakończeniu:

php

$featured = new WP_Query( array(
	'post_type'      => 'post',
	'posts_per_page' => 3,
	'meta_key'       => '_acme_featured',
	'meta_value'     => '1',
) );

if ( $featured->have_posts() ) {
	while ( $featured->have_posts() ) {
		$featured->the_post();
		// wyjście
	}
	wp_reset_postdata();
}

W motywach blokowych większość tej pracy wykonuje blok pętli zapytania, a własne wyjście należy do zarejestrowanego bloku albo powiązania danych, nie do pliku szablonu.

Haki to sposób na rozszerzanie działania bez modyfikowania rdzenia i bez walki z własnymi szablonami w przyszłości. Akcje dokładają zachowanie w zdefiniowanych punktach, filtry modyfikują wartości w locie. Jedno i drugie przetrwa aktualizację, czego nie da się powiedzieć o zmianach wpisanych na sztywno.

Jakie praktyki bezpieczeństwa mają znaczenie?

Dwie zasady pokrywają większość tego, co idzie nie tak w motywach.

Zawsze escapuj przy wyjściu, funkcją dopasowaną do kontekstu.

php

echo esc_html( $title );
echo '<a href="' . esc_url( $link ) . '">';
printf( '<img src="%s" alt="%s">', esc_url( $src ), esc_attr( $alt ) );
echo wp_kses_post( $rich_text );

Sanityzuj i weryfikuj przy wejściu. Sprawdzaj to, co przychodzi, weryfikuj nonce przy każdym formularzu i żądaniu AJAX, a przed wykonaniem działania sprawdzaj uprawnienia użytkownika:

php

if ( ! isset( $_POST['acme_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['acme_nonce'] ), 'acme_action' ) ) {
	return;
}

if ( ! current_user_can( 'edit_posts' ) ) {
	return;
}

$value = sanitize_text_field( wp_unslash( $_POST['acme_field'] ) );

Do zapytań bezpośrednich używaj $wpdb->prepare(), a tam gdzie istnieje funkcja z API WordPressa, korzystaj z niej zamiast z własnego SQL. Większość podatności w motywach bierze się z braku escapowania i pominiętej kontroli uprawnień, nie z niczego egzotycznego.

Jak testować i debugować motyw?

Włącz debugowanie w wp-config.php na środowisku deweloperskim i nigdy na produkcji:

php

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'SCRIPT_DEBUG', true );

Poza tym cztery kontrole wyłapują większość problemów, zanim znajdzie je klient.

Testuj na realistycznej treści. Zestaw testowy publikowany przez społeczność WordPressa zawiera długie tytuły, brakujące obrazki wyróżniające, zagnieżdżone listy, nietypowe formaty wpisów i niewygodne wątki komentarzy. Układy wyglądające dobrze na trzech schludnych wpisach demonstracyjnych rozpadają się na prawdziwej treści redakcyjnej.

Obserwuj zapytania. Query Monitor pokazuje liczbę zapytań, zapytania wolne, wykonanie haków i kolejkowane zasoby przy każdym wczytaniu strony. Szablon wykonujący po cichu osiemdziesiąt zapytań łatwiej naprawić w trakcie prac niż po wdrożeniu.

Uruchom Theme Check pod kątem standardów kodowania i użycia funkcji wycofanych, a PHP_CodeSniffer ze standardem WordPressa wpnij w swój proces pracy.

Testuj dostępność rzetelnie. Narzędzia automatyczne wyłapią kontrast i brakujące etykiety. Nawigacja klawiaturą, kolejność fokusu i zachowanie czytników ekranu wymagają testów ręcznych. To dziś wymóg funkcjonalny, nie dopracowanie.

Najczęstsze błędy

  • Wpinanie arkuszy stylów i skryptów w szablony zamiast kolejkowania
  • Pozostawianie zamykającego ?> w plikach PHP
  • Pomijanie escapowania, bo „wartość pochodzi z naszej własnej bazy”
  • Tworzenie szablonów, które powielają zabezpieczenie, niczego nie zmieniając
  • Budowanie motywu bez theme.json, a potem walka z domyślnymi ustawieniami edytora bloków w CSS
  • Edytowanie cudzego motywu bezpośrednio zamiast przez motyw potomny
  • Traktowanie dostępności i wydajności jako etapu po zatwierdzeniu projektu graficznego

FAQ

Jakie pliki są wymagane do stworzenia motywu WordPress?

Motyw klasyczny wymaga style.css i index.php. Motyw blokowy wymaga style.css i templates/index.html. W obu przypadkach functions.php i theme.json są zdecydowanie zalecane przy czymkolwiek poza demonstracją.

Czy functions.php wymaga otwierającego znacznika PHP?

Tak. Otwierający <?php jest wymagany. Konwencja mówi natomiast o pominięciu zamykającego ?> na końcu pliku, ponieważ znaki puste po nim mogą wysłać wyjście przed nagłówkami i zepsuć serwis.

Motyw blokowy czy klasyczny?

Blokowy, gdy redakcja potrzebuje realnej kontroli nad układem i szablonami. Klasyczny lub hybrydowy, gdy szablony zawierają rozbudowaną logikę, gdy potrzebujesz ścisłej kontroli nad ładowanymi zasobami albo gdy założeniem jest celowo ograniczony zakres edycji. Motyw klasyczny z theme.json to rozsądne rozwiązanie pośrednie.

Czy mogę dodać theme.json do istniejącego motywu klasycznego?

Tak i zwykle warto. Plik daje system projektowy respektowany przez edytor bloków, bez przenoszenia szablonów do edytora witryny i bez przebudowy czegokolwiek.

Czy potrzebuję motywu potomnego?

Tylko wtedy, gdy rozszerzasz motyw, którego nie kontrolujesz. Przy własnym motywie potomny dokłada warstwę, nie dokładając niczego więcej. Przy modyfikacji cudzego motywu to on chroni Twoją pracę przed następną aktualizacją.

Ile trwa zbudowanie własnego motywu?

Przy prostym serwisie wizerunkowym z gotowym projektem graficznym kilka dni. Przy platformie z własnymi typami treści, złożonymi szablonami i integracjami tygodnie lub miesiące. Zmienną rzadko jest sama warstwa motywu. Są nią model treści, integracje i liczba odrębnych typów podstron.

Budujesz coś, w czym warstwa motywu jest najmniejszą częścią problemu? Zaczynamy od modelu treści i architektury. → Porozmawiajmy

Pwel Zmyslowski

Paweł Zmysłowski

CEO WLC.team

W WLC odpowiada za proces sprzedaży i zespół sprzedaży, a w przypadku bardziej złożonych projektów pełnię również rolę analityczną i doradczą.

Strona autora

Twój WordPress „działa, ale wolno”?

WIĘCEJ ARTYKUŁÓW

Przeczytaj także

  • AI Search and WordPress How to prepare a large-scale platform for generative search
    13 minut

    AI Search a WordPress: jak przygotować dużą platformę do wyszukiwania generatywnego

    Duże platformy WordPress nie wypadają z odpowiedzi generowanych przez AI dlatego, że mają słabą treść. Wypadają, bo przez lata rozwoju nikt nie odpowiadał za architekturę informacji, a dostęp crawlerów bywa zablokowany na poziomie, którego nie widać w panelu WordPressa. Ten artykuł pokazuje, co da się w tym kontrolować, co jest udokumentowane, a co pozostaje hipotezą.…

    Czytaj

  • WordPress for Education in 2026
    9 minut

    WordPress dla edukacji w 2026 roku: architektura, narzędzia i decyzje, które zadecydują o sukcesie platformy

    WordPress obsługuje ponad 40% stron internetowych na świecie. W segmencie edukacyjnym ta dominacja jest jeszcze wyraźniejsza – platforma stała się de facto standardem dla instytucji, które chcą połączyć stronę szkoły z pełnoprawnym systemem zarządzania kursami bez kosztów licencyjnych rosnących wraz z bazą uczniów. Ale popularność nie oznacza automatycznego sukcesu. WordPress dla edukacji to nie instalacja…

    Czytaj

  • ecommerce store
    12 minut

    Jak zabezpieczyć sklep WooCommerce przed oszustwami związanymi z płatnościami?

    Prowadzenie sklepu WooCommerce stawia Cię w bezpośrednim zasięgu oszustów szukających sposobów na wykorzystanie firm działających online. Oszustwa płatnicze stały się jednym z najpilniejszych wyzwań dla właścicieli sklepów e-commerce, a witryny WooCommerce są szczególnie atrakcyjnym celem ze względu na ich popularność, wolumen przetwarzanych transakcji oraz szeroki zakres dojrzałości bezpieczeństwa między poszczególnymi sklepami.

    Czytaj