Współpraca
Blog Custom Post Types w WordPressie
WordPress · · 7 min czytania

Custom Post Types w WordPressie

Jak tworzyć własne typy wpisów (CPT) w WordPressie — rejestracja, etykiety, obsługa w szablonach i integracja z własnym zapytaniem WP_Query.

WordPress PHP CPT

Czym są Custom Post Types?

WordPress domyślnie obsługuje kilka wbudowanych typów treści: wpisy (posts), strony (pages), multimedia i komentarze. Custom Post Types (CPT) to mechanizm, który pozwala ci zarejestrować własne typy treści — np. Portfolio, Recenzje, FAQ czy Nieruchomości — z własnym panelem administracyjnym, polami i zachowaniem.

CPT nie są wtyczką — to natywna funkcja WordPressa dostępna od wersji 3.0. Rejestrujesz je przez wywołanie funkcji register_post_type() w pliku functions.php lub w dedykowanej wtyczce.

💡

Kiedy warto używać CPT? Jeśli treść ma własną strukturę, własne pola i powinna wyświetlać się w oddzielnej sekcji panelu — CPT to właściwe narzędzie. Nie nadużywaj wpisów dla wszystkiego.

Rejestracja własnego typu wpisu

Funkcję rejestrującą wpinamy w hook init, żeby WordPress ją wykonał we właściwym momencie ładowania. Poniżej przykład rejestracji CPT o nazwie Portfolio:

<?php
/**
 * Rejestracja Custom Post Type: Portfolio.
 */
function moj_rejestruj_portfolio(): void {

    $labels = [
        'name'               => 'Portfolio',
        'singular_name'      => 'Projekt',
        'menu_name'          => 'Portfolio',
        'add_new'            => 'Dodaj projekt',
        'add_new_item'       => 'Dodaj nowy projekt',
        'edit_item'          => 'Edytuj projekt',
        'new_item'           => 'Nowy projekt',
        'view_item'          => 'Zobacz projekt',
        'search_items'       => 'Szukaj projektów',
        'not_found'          => 'Nie znaleziono projektów',
        'not_found_in_trash' => 'Brak projektów w koszu',
    ];

    $args = [
        'labels'             => $labels,
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite'            => [ 'slug' => 'portfolio' ],
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => 5,
        'menu_icon'          => 'dashicons-portfolio',
        'supports'           => [ 'title', 'editor', 'thumbnail', 'excerpt' ],
        'show_in_rest'       => true,   // aktywuje blok Gutenberg
    ];

    register_post_type( 'portfolio', $args );
}
add_action( 'init', 'moj_rejestruj_portfolio' );
⚠️

Po zarejestrowaniu nowego CPT pamiętaj o odświeżeniu permalinków: Ustawienia → Bezpośrednie odnośniki → Zapisz zmiany. Bez tego adresy URL nowego typu będą zwracały błąd 404.

Własne taksonomie

Do grupowania wpisów CPT możesz stworzyć własne taksonomie — hierarchiczne (jak kategorie) lub płaskie (jak tagi). Poniżej rejestracja taksonomii Technologia dla CPT Portfolio:

<?php
/**
 * Rejestracja taksonomii: Technologia.
 */
function moj_rejestruj_technologie(): void {

    $labels = [
        'name'              => 'Technologie',
        'singular_name'     => 'Technologia',
        'search_items'      => 'Szukaj technologii',
        'all_items'         => 'Wszystkie technologie',
        'edit_item'         => 'Edytuj technologię',
        'update_item'       => 'Zaktualizuj technologię',
        'add_new_item'      => 'Dodaj nową technologię',
        'new_item_name'     => 'Nazwa nowej technologii',
        'menu_name'         => 'Technologie',
    ];

    register_taxonomy(
        'technologia',          // nazwa taksonomii
        [ 'portfolio' ],        // powiązane CPT
        [
            'hierarchical'      => true,    // true = kategorie, false = tagi
            'labels'            => $labels,
            'show_ui'           => true,
            'show_admin_column' => true,
            'query_var'         => true,
            'rewrite'           => [ 'slug' => 'technologia' ],
            'show_in_rest'      => true,
        ]
    );
}
add_action( 'init', 'moj_rejestruj_technologie' );

Wyświetlanie CPT w szablonie

Domyślna pętla WordPressa (The Loop) nie obejmuje wpisów CPT. Aby pobrać własne typy, używasz klasy WP_Query z jawnym podaniem nazwy CPT:

<?php
$portfolio_query = new WP_Query([
    'post_type'      => 'portfolio',
    'posts_per_page' => 6,
    'orderby'        => 'date',
    'order'          => 'DESC',
    'tax_query'      => [
        [
            'taxonomy' => 'technologia',
            'field'    => 'slug',
            'terms'    => 'php',
        ],
    ],
]);

if ( $portfolio_query->have_posts() ) :
    while ( $portfolio_query->have_posts() ) :
        $portfolio_query->the_post();
        ?>
        <article class="portfolio-card">
            <h2><?php the_title(); ?></h2>
            <?php the_post_thumbnail( 'medium' ); ?>
            <?php the_excerpt(); ?>
            <a href="<?php the_permalink(); ?>">Zobacz projekt</a>
        </article>
        <?php
    endwhile;
    wp_reset_postdata();    // !!! zawsze resetuj po własnym WP_Query
endif;
⚠️

Wywołanie wp_reset_postdata() po własnym WP_Query jest obowiązkowe. Bez niego globalna zmienna $post pozostaje przestawiona na ostatni wpis z Twojego zapytania, co może powodować nieprzewidywalne błędy w dalszej części szablonu.

Pliki szablonów CPT

WordPress automatycznie szuka plików szablonów dla CPT według hierarchii. Dla CPT o nazwie portfolio:

  • single-portfolio.php — szablon pojedynczego projektu
  • archive-portfolio.php — szablon listy projektów
  • taxonomy-technologia.php — szablon listy wg taksonomii

Utwórz te pliki w katalogu motywu i WordPress automatycznie ich użyje zamiast domyślnego single.php czy archive.php.

<?php
// single-portfolio.php — minimal example
get_header();

while ( have_posts() ) :
    the_post();
    ?>
    <main class="portfolio-single">
        <h1><?php the_title(); ?></h1>
        <?php
        $terms = get_the_terms( get_the_ID(), 'technologia' );
        if ( $terms ) {
            foreach ( $terms as $term ) {
                echo '<span class="tag">' . esc_html( $term->name ) . '</span>';
            }
        }
        ?>
        <?php the_content(); ?>
    </main>
    <?php
endwhile;

get_footer();

Wskazówka organizacyjna: Zamiast wrzucać rejestrację CPT bezpośrednio do functions.php, utwórz plik includes/post-types.php i dołącz go przez require_once get_template_directory() . '/includes/post-types.php'. Utrzymasz porządek przy rosnącym projekcie.

Podsumowanie

Custom Post Types to jeden z najważniejszych mechanizmów WordPressa. Kilkadziesiąt linii kodu daje Ci dedykowany section w panelu, własne URL-e, taksonomie, szablony i pełną integrację z blokami Gutenberga oraz REST API.

Klucz do sukcesu to dobre etykiety (użytkownik widzi je codziennie w panelu), przemyślana struktura supports i zawsze — odświeżone permalinki po pierwszej rejestracji.