Czym jest functions.php?
Plik functions.php to centrum dowodzenia każdego motywu WordPress.
Działa jak wtyczka — jest ładowany automatycznie przy każdym zapytaniu i może
zawierać dowolny kod PHP. To tutaj definiujesz, jak motyw zachowuje się od strony
funkcjonalnej: jakie menu, skrypty i style rejestruje, jakie hooki wykonuje i jakie
funkcje pomocnicze udostępnia.
Kluczowa różnica między functions.php a wtyczką jest taka, że kod
w functions.php jest powiązany z motywem — wyłączenie lub zmiana
motywu wyłącza też jego functions.php. Dlatego logika niezależna od wyglądu powinna
trafić do wtyczki, a nie tutaj.
Złota zasada: Jeśli wyłączenie motywu i włączenie innego powinno usunąć daną funkcję — umieść ją w functions.php. Jeśli ma działać niezależnie od motywu — napisz wtyczkę.
Rejestrowanie menu nawigacyjnych
WordPress pozwala zadeklarować nazwane lokalizacje menu, które następnie możesz przypisywać przez Panel → Wygląd → Menu lub Customizer:
<?php
/**
* Rejestracja lokalizacji menu.
*/
function moj_rejestruj_menu(): void {
register_nav_menus([
'primary' => __( 'Menu główne', 'moj-motyw' ),
'footer' => __( 'Menu w stopce', 'moj-motyw' ),
'mobile' => __( 'Menu mobilne', 'moj-motyw' ),
]);
}
add_action( 'after_setup_theme', 'moj_rejestruj_menu' );
W szablonie menu wyświetlasz przez wp_nav_menu():
<?php
wp_nav_menu([
'theme_location' => 'primary',
'container' => 'nav',
'container_class'=> 'site-nav',
'menu_class' => 'nav__list',
'depth' => 2,
'fallback_cb' => false,
]);
Enqueue skryptów i stylów
Nigdy nie dołączaj skryptów i stylów przez tagi <script>
czy <link> wstawiane ręcznie w header.php. WordPress ma do tego
dedykowany system kolejkowania (enqueue), który zarządza zależnościami
i unika duplikatów:
<?php
/**
* Ładowanie stylów i skryptów.
*/
function moj_dodaj_zasoby(): void {
// Główny arkusz stylów motywu
wp_enqueue_style(
'moj-motyw-style', // unikalny uchwyt
get_stylesheet_uri(), // ścieżka do style.css
[], // zależności
wp_get_theme()->get( 'Version' ) // wersja (cache busting)
);
// Osobny plik CSS dla strony głównej
if ( is_front_page() ) {
wp_enqueue_style(
'moj-motyw-home',
get_template_directory_uri() . '/css/home.css',
[ 'moj-motyw-style' ],
'1.0.0'
);
}
// Skrypt JavaScript
wp_enqueue_script(
'moj-motyw-script',
get_template_directory_uri() . '/js/main.js',
[ 'jquery' ], // jquery jako zależność
'1.0.0',
true // true = ładuj w stopce (before </body>)
);
// Przekaż zmienne PHP do skryptu JS
wp_localize_script( 'moj-motyw-script', 'mojConfig', [
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'moj-nonce' ),
'homeUrl' => home_url(),
]);
}
add_action( 'wp_enqueue_scripts', 'moj_dodaj_zasoby' );
Hooki i filtry
WordPress opiera się na systemie zdarzeń: akcje (actions) pozwalają doczepić kod do określonego momentu działania CMS-a, a filtry (filters) pozwalają modyfikować dane w locie.
<?php
// ── Akcja: zmień długość excerptów ──────────────────────────────
function moj_excerpt_dlugosc( int $length ): int {
return 25;
}
add_filter( 'excerpt_length', 'moj_excerpt_dlugosc', 20 );
// ── Akcja: usuń domyślny "..." z końca excerptów ────────────────
function moj_excerpt_more( string $more ): string {
return '…';
}
add_filter( 'excerpt_more', 'moj_excerpt_more' );
// ── Filtr: dodaj własną klasę body ──────────────────────────────
function moj_body_klasy( array $classes ): array {
if ( is_single() ) {
$classes[] = 'strona-wpisu';
}
return $classes;
}
add_filter( 'body_class', 'moj_body_klasy' );
// ── Akcja: obsługa AJAX dla niezalogowanych ─────────────────────
function moj_ajax_handler(): void {
check_ajax_referer( 'moj-nonce', 'nonce' );
// logika...
wp_send_json_success( [ 'msg' => 'OK' ] );
}
add_action( 'wp_ajax_moj_action', 'moj_ajax_handler' );
add_action( 'wp_ajax_nopriv_moj_action', 'moj_ajax_handler' );
Wsparcie funkcji motywu
Przez add_theme_support() deklarujesz, jakie wbudowane
funkcje WordPressa ma aktywować Twój motyw. Bez tego np. miniatura wpisu
czy bloki Gutenberga mogą nie działać poprawnie:
<?php
function moj_wsparcie_funkcji(): void {
// Miniatury wpisów (featured image)
add_theme_support( 'post-thumbnails' );
add_image_size( 'hero', 1440, 600, true );
add_image_size( 'card', 480, 320, true );
add_image_size( 'thumb', 240, 160, true );
// Automatyczny tag <title>
add_theme_support( 'title-tag' );
// Pełna szerokość bloków Gutenberga
add_theme_support( 'align-wide' );
// Kolory własne zastępują paletę edytora
add_theme_support( 'editor-color-palette', [
[ 'name' => 'Primary', 'slug' => 'primary', 'color' => '#a259ff' ],
[ 'name' => 'Dark', 'slug' => 'dark', 'color' => '#0d1117' ],
]);
// HTML5 dla elementów natywnych
add_theme_support( 'html5', [
'search-form', 'comment-form', 'comment-list', 'gallery', 'caption',
]);
}
add_action( 'after_setup_theme', 'moj_wsparcie_funkcji' );
Jak NIE pisać functions.php
Przy rosnącym projekcie plik functions.php potrafi urosnąć do setek linii. Zamiast wrzucać wszystko w jedno miejsce, rozbij kod na pliki tematyczne:
<?php
// functions.php — tylko include'y
require_once get_template_directory() . '/includes/menu.php';
require_once get_template_directory() . '/includes/enqueue.php';
require_once get_template_directory() . '/includes/post-types.php';
require_once get_template_directory() . '/includes/shortcodes.php';
require_once get_template_directory() . '/includes/ajax.php';
require_once get_template_directory() . '/includes/helpers.php';
Wskazówka: Każda funkcja w functions.php powinna mieć
unikalny prefiks (np. inicjały projektu), żeby uniknąć kolizji nazw
z funkcjami WordPressa lub zainstalowanych wtyczek:
moj_function_name() zamiast function_name().
Podsumowanie
Plik functions.php to serce motywu WordPress — od rejestrowania menu
i kolejkowania zasobów, przez hooki i filtry, aż po deklarowanie wsparcia dla
wbudowanych funkcji CMS-a. Kluczem do utrzymywalnego motywu jest dobra organizacja:
własne prefiksy, rozbicie na pliki tematyczne i przestrzeganie zasady —
logika niezależna od wyglądu należy do wtyczki, nie do motywu.