Skip to content

Kaikki WordPressistä, web-kehityksestä — ja paljon muuta

🔧 Kuinka luoda malli mukautetulle sisältötyypille WordPressissä

🔧 Kuinka luoda malli mukautetulle sisältötyypille WordPressissä

Luoit sivustollesi mukautetun sisältötyypin, vaikkapa "Kampanjat", "Portfolio" tai "Suosittelut". Kaikki toimii: sisältöjä luodaan, metakentät täytetään. Mutta kun avaat yhden näistä sisällöistä julkisella puolella, se näyttää aivan tavalliselta blogiartikkelilta. Sama asettelu, samat sivupalkit, ei mitään eroa. Kuitenkin loit mukautetun sisältötyypin juuri siksi, että sisältö esitettäisiin eri tavalla.

Ongelma on, että WordPress renderöi oletuksena minkä tahansa mukautetun sisällön single.php-tiedoston kautta, joka on kaikkien yksittäisten sisältöjen yleispohja. Saadaksesi uniikin asettelun tietylle tyypille tarvitset oman pohjatiedoston. Ja se osoittautuu yllättävän helpoksi.

Alla on vaiheittainen erittely: pohjahierarkiasta kahteen luontitapaan (teematiedoston kautta ja template_include-suodattimella), toimivine koodiesimerkkeineen.

💡 Nopea yleiskatsaus:

  • Miten WordPress etsii pohjaa mukautetulle sisältötyypille ja mikä on single-{post_type}.php-tiedoston prioriteetti
  • Teemasi single.php-tiedoston kopiointi, sen nimeäminen uudelleen CPT:täsi varten ja muokkaaminen
  • Vaihtoehtoinen tapa template_include-suodattimen kautta (kätevä, jos et halua koskea teemaan)
  • Itse mukautetun sisältötyypin luominen Custom Post Type UI -lisäosalla, nopeasti ja ilman koodia

1. Miten WordPress valitsee pohjan mukautetulle sisältötyypille

WordPressin pohjahierarkia on ketju tiedostoja, jotka ydin käy läpi löytääkseen oikean pohjan sivun renderöintiin. Tavallisille artikkeleille ketju on pitkä: single-post.phpsingle.phpsingular.phpindex.php. Mukautetuille sisältötyypeille se on lyhyempi, mutta logiikka on sama.

Kun kävijä avaa mukautetun sisällön, jonka tyyppi on aktsii, WordPress tarkistaa tiedostot tässä järjestyksessä:

  • single-aktsii.php, pohja erityisesti tälle mukautetulle sisältötyypille
  • single.php, yleinen yksittäisen sisällön pohja
  • singular.php, pohja mille tahansa yksittäiselle sisällölle (artikkeli, sivu, CPT)
  • index.php, lopullinen varavaihtoehto

Ensimmäinen ketjusta löytyvä tiedosto käytetään renderöintiin. Jos single-aktsii.php on olemassa, WordPress poimii sen ja pysähtyy. Jos sitä ei löydy, ydin siirtyy single.php-tiedostoon. Juuri siksi mukautettu sisältötyyppisi näyttää tavalliselta artikkelilta: single-aktsii.php-tiedostoa ei ole, joten ydin turvautuu yleiseen single.php-tiedostoon.

Ratkaisu seuraa tästä suoraan: luo single-{post_type}.php, ja WordPress poimii sen automaattisesti.

2. Pohjatiedoston luominen: kopioi single.php ja nimeä se uudelleen

Tämä on yksinkertaisin ja luotettavin lähestymistapa. Se toimii minkä tahansa perinteisen teeman kanssa eikä vaadi lisäosia tai suodattimia.

Vaihe 1: etsi teemasi single.php. Se sijaitsee teemakansion juuressa: /wp-content/themes/your-theme/single.php. Jos teema käyttää FSE:tä (Full Site Editing) ja on rakennettu lohkoilla, tätä tiedostoa ei ehkä ole, ja suodatinmenetelmä (template_include) on kätevämpi (osio 4).

Vaihe 2: kopioi ja nimeä uudelleen. Kopioi single.php ja nimeä se kaavan single-{slug}.php mukaan: korvaa {slug} mukautetun sisältötyyppisi polkutunnuksella (se, joka määritettiin rekisteröinnin yhteydessä, latinalaisin kirjaimin). Esimerkiksi tyypille, jonka polkutunnus on aktsii:

1single-aktsii.php

Tyypille, jonka polkutunnus on portfolio, tiedoston nimi olisi single-portfolio.php. testimonials-tyypille siitä tulee single-testimonials.php. Tärkeää: polkutunnuksen on vastattava sitä, joka on määritetty 'rewrite' => array('slug' => '...') -parametrissa rekisteröinnin yhteydessä.

Vaihe 3: aseta tiedosto takaisin teemakansioon. WordPress poimii sen automaattisesti kaikille tämän tyypin sisällöille. Mitään lisämäärityksiä ei tarvita; pohjahierarkia hoitaa sen automaattisesti.

Vaihe 4: varmista. Avaa mikä tahansa mukautetun tyypin sisältö julkisella puolella. Jos näet saman sivun kuin aiemmin, tarkista tiedoston nimi (kirjainkoko, yhdysviivat alaviivojen sijaan) ja tyhjennä välimuisti. Jos tiedosto luotiin lapsiteemaan ja vanhempi teema sisältää myös single-{post_type}.php-tiedoston, lapsiteema on etusijalla.

3. Pohjan sisällön muokkaaminen

Kopioitu single.php on edelleen identtinen alkuperäisen kanssa; se vain renderöi saman yleisen asettelun. Nyt täytämme sen mukautetulle sisältötyypille ominaisella sisällöllä.

3.1. Perusrakenne: mukautettujen kenttien tulostus

Oletetaan, että mukautetulla sisältötyypillä aktsii on kentät aktsiya_data_start, aktsiya_data_end ja aktsiya_skidka (luotu ACF:llä, Meta Boxilla tai manuaalisesti). Tässä on minimaalinen pohja, joka tulostaa ne:

1<?php
2/**
3 * Template for custom type "Promotions" (single-aktsii.php)
4 */
5
6get_header();
7?>
8
9<main id="main" class="site-main" role="main">
10
11 <?php while ( have_posts() ) : the_post(); ?>
12
13 <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
14
15 <header class="entry-header">
16 <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
17 </header>
18
19 <?php if ( has_post_thumbnail() ) : ?>
20 <div class="post-thumbnail">
21 <?php the_post_thumbnail( 'large' ); ?>
22 </div>
23 <?php endif; ?>
24
25 <div class="entry-content">
26 <?php the_content(); ?>
27
28 <div class="custom-fields">
29 <?php
30 $data_start = get_post_meta( get_the_ID(), 'aktsiya_data_start', true );
31 $data_end = get_post_meta( get_the_ID(), 'aktsiya_data_end', true );
32 $skidka = get_post_meta( get_the_ID(), 'aktsiya_skidka', true );
33
34 if ( $data_start ) {
35 echo '<p><strong>Start Date:</strong> ' . esc_html( $data_start ) . '</p>';
36 }
37 if ( $data_end ) {
38 echo '<p><strong>End Date:</strong> ' . esc_html( $data_end ) . '</p>';
39 }
40 if ( $skidka ) {
41 echo '<p><strong>Discount:</strong> ' . esc_html( $skidka ) . '%</p>';
42 }
43 ?>
44 </div>
45 </div>
46
47 </article>
48
49 <?php
50 if ( comments_open() || get_comments_number() ) :
51 comments_template();
52 endif;
53 ?>
54
55 <?php endwhile; ?>
56
57</main>
58
59<?php
60get_sidebar();
61get_footer();

Tämä on täysin toimiva pohja, jonka voit pudottaa teemaasi sellaisenaan. Se tulostaa otsikon, artikkelikuvan, sisällön ja kolme mukautettua kenttää omassa lohkossaan.

3.2. Mitä muuta voit tehdä pohjalla

Tästä eteenpäin muokkausmahdollisuudet ovat käytännössä rajattomat:

  • Poista sivupalkki: poista yksinkertaisesti get_sidebar()-kutsu.
  • Vaihda HTML-kääre: korvaa <article> <div>-elementillä, jolla on tarvitsemasi luokka, lisää oma grid.
  • Kutsu tiettyä pohjan osaa: esimerkiksi get_template_part( 'template-parts/content', 'aktsii' ) ja pidä logiikka erillisessä tiedostossa.
  • Lisää mukautettuja tyylejä: wp_enqueue_style()-funktiolla functions.php-tiedostossa, käyttäen is_singular( 'aktsii' ) -tarkistusta.

Tärkeä huomio: jos teema päivitetään, vanhemman teeman tiedosto voidaan ylikirjoittaa. Työskentele siis joko lapsiteemassa tai käytä seuraavan osion suodatinmenetelmää.

4. Vaihtoehtoinen lähestymistapa: template_include-suodatin

Jos et halua muokata teematiedostoja (tai teema on lohkopohjainen eikä siinä ole perinteistä single.php-tiedostoa), voit määrittää pohjan template_include-koukun kautta. Se laukeaa ennen kuin WordPress sisällyttää pohjatiedoston ja antaa sinun ohittaa polun.

Haittapuoli: sinun on säilytettävä pohjatiedosto joko lisäosassa tai lapsiteemassa, ja koodin on osoitettava oikeaan polkuun. Hyötypuoli: logiikka ei katoa, kun vanhempi teema päivitetään.

4.1. Esimerkki: yksi CPT, yksi pohja

Lisää tämä lapsiteeman functions.php-tiedostoon (tai MU-lisäosaan):

1add_filter( 'template_include', 'techblog_cpt_template', 99 );
2
3function techblog_cpt_template( $template ) {
4 if ( is_singular( 'aktsii' ) ) {
5 $custom_template = get_stylesheet_directory() . '/single-aktsii.php';
6 if ( file_exists( $custom_template ) ) {
7 return $custom_template;
8 }
9 }
10 return $template;
11}

Koodi tarkistaa, kuuluuko nykyinen sivu mukautettuun sisältötyyppiin aktsii. Jos kuuluu, se etsii tiedostoa single-aktsii.php lapsiteemakansiosta (get_stylesheet_directory()) ja palauttaa sen. Jos tiedostoa ei löydy, se palauttaa oletusarvoisen $template-muuttujan muuttumattomana.

4.2. Esimerkki: useita CPT:itä yhdellä käsittelijällä

Jos sinulla on useita mukautettuja sisältötyyppejä, on kätevää yhdistää logiikka yhteen suodattimeen:

1add_filter( 'template_include', 'techblog_cpt_templates', 99 );
2
3function techblog_cpt_templates( $template ) {
4 $cpt_templates = array(
5 'aktsii' => 'single-aktsii.php',
6 'portfolio' => 'single-portfolio.php',
7 'testimonials' => 'single-testimonials.php',
8 );
9
10 foreach ( $cpt_templates as $cpt => $template_file ) {
11 if ( is_singular( $cpt ) ) {
12 $custom_template = get_stylesheet_directory() . '/' . $template_file;
13 if ( file_exists( $custom_template ) ) {
14 return $custom_template;
15 }
16 }
17 }
18
19 return $template;
20}

Nyt jokainen CPT saa oman pohjansa, ja kaikki logiikka on yhdessä funktiossa.

4.3. Pohjien säilyttäminen lisäosassa

Jos jaat mukautetun sisältötyypin lisäosana (eikä osana teemaa), on järkevää säilyttää pohja lisäosakansiossa. Siinä tapauksessa määritä polku plugin_dir_path( __FILE__ )-funktiolla:

1add_filter( 'template_include', 'myplugin_cpt_template', 99 );
2
3function myplugin_cpt_template( $template ) {
4 if ( is_singular( 'aktsii' ) ) {
5 $custom_template = plugin_dir_path( __FILE__ ) . 'templates/single-aktsii.php';
6 if ( file_exists( $custom_template ) ) {
7 return $custom_template;
8 }
9 }
10 return $template;
11}

Tätä mallia käyttävät monet suositut lisäosat (WooCommerce, Easy Digital Downloads, The Events Calendar): ne toimittavat pohjat sisäisesti ja sisällyttävät ne suodattimen kautta.

5. Mukautetun sisältötyypin luominen

Pohja on valmis, mutta täydellisyyden vuoksi muutama sana siitä, mistä itse mukautettu sisältötyyppi tulee.

5.1. Rekisteröinti koodilla

Minimaalinen CPT-rekisteröinti functions.php-tiedostossa tai MU-lisäosassa:

1add_action( 'init', 'techblog_register_cpt_aktsii' );
2
3function techblog_register_cpt_aktsii() {
4 $labels = array(
5 'name' => 'Promotions',
6 'singular_name' => 'Promotion',
7 'menu_name' => 'Promotions',
8 );
9
10 $args = array(
11 'labels' => $labels,
12 'public' => true,
13 'has_archive' => true,
14 'supports' => array( 'title', 'editor', 'thumbnail' ),
15 'rewrite' => array( 'slug' => 'aktsii' ),
16 'show_in_rest' => true,
17 );
18
19 register_post_type( 'aktsii', $args );
20}

Avainkohta tässä on, että 'rewrite' => array( 'slug' => 'aktsii' ) -parametri asettaa polkutunnuksen, jota käytetään sekä URL-osoitteessa että pohjatiedoston nimessä. Jos polkutunnus on aktsii, pohjatiedoston nimi on oltava single-aktsii.php.

5.2. Custom Post Type UI -lisäosan käyttö

Jos et halua muokata functions.php-tiedostoa, voit luoda CPT:n visuaalisesti ilmaisella Custom Post Type UI -lisäosalla WordPress.orgissa. Asennuksen jälkeen:

  • Siirry hallintapaneelissa kohtaan CPT UI → Add/Edit Post Types
  • Täytä kentät: Post Type Slug (latinalaisia kirjaimia), Plural Label, Singular Label
  • Settings-välilehdellä valitse, mitä editorin ominaisuuksia tarvitset (otsikko, editori, artikkeli kuva)
  • Klikkaa Add Post Type

Lisäosa tuottaa PHP-rekisteröintikoodin, jonka voit viedä ja liittää functions.php-tiedostoon. Tämä on kätevää, jos haluat myöhemmin poistaa lisäosariippuvuuden. CPT UI:ssa määrittämäsi polkutunnus on sama, joka menee pohjatiedoston nimeen.

⁉️🤔 Usein kysytyt kysymykset

Mitä teen, jos pohjaa ei poimita tiedoston luomisen jälkeen?

Tyhjennä permalinkit: siirry kohtaan Asetukset → Permalinkit ja klikkaa "Tallenna muutokset" (mitään ei tarvitse muuttaa). WordPress rakentaa reitityssääntönsä uudelleen. Jos tämä ei auta, tarkista tiedoston nimi: mukautetun sisältötyypin polkutunnuksen ja tiedoston nimen on vastattava toisiaan (kirjainkoko, yhdysviivat ja alaviivat). Kolmantena vaiheena tyhjennä välimuistilisäosan välimuisti, jos sellainen on asennettu. Permalinkit tulisi tyhjentää jokaisen uuden mukautetun sisältötyypin rekisteröinnin jälkeen, ei vain silloin, kun törmäät pohjaongelmiin. Tämä on vakiokäytäntö: siirry kohtaan Asetukset → Permalinkit → Tallenna, ja uudet URL-osoitteet alkavat toimia välittömästi.

Voinko käyttää yhtä pohjaa useille mukautetuille sisältötyypeille?

Kyllä, kahdella tavalla. Ensinnäkin, luo fyysinen tiedosto single-aktsii.php, ja toiselle tyypille (esimerkiksi portfolio) kopioi se nimellä single-portfolio.php. Toiseksi, käytä template_include-suodatinta (osio 4): $cpt_templates-taulukossa osoita eri tyypit samaan pohjatiedostoon. Käytännössä eri CPT:illä on kuitenkin lähes aina erilaiset asettelut; kopiointi ja muokkaus on yksinkertaisempaa kuin ehdollisen logiikan rakentaminen yhden pohjan sisälle. Jos sinulla todella on monta tyyppiä, joilla on identtinen logiikka, luo jaettu single-cpt.php, tarkista get_post_type() sen sisällä ja sisällytä vastaava pohjan osa get_template_part( 'template-parts/content', get_post_type() )-kutsulla. Tämä on puhdas ja skaalautuva lähestymistapa.

Tarvitseeko minun luoda archive-{post_type}.php** arkistosivua varten?**

Se on suositeltavaa, mutta ei pakollista. Ilman sitä WordPress käyttää archive.php- tai index.php-tiedostoa. Jos CPT:llä on 'has_archive' => true ja arkisto avautuu osoitteessa /aktsii/, mutta archive-aktsii.php-tiedostoa ei ole, käytetään yleistä archive.php-tiedostoa. Erillisen arkistopohjan luominen on järkevää, kun sisältöruudukon, sarakeasettelun tai sivupalkin tulisi poiketa blogiarkistosta.

Toimiiko tämä lohkoteemojen (FSE) kanssa?

Lohkoteemoissa perinteiset PHP-pohjatiedostot eivät ole ensisijainen lähestymistapa. template_include-suodatin (osio 4) toimii kuitenkin myös FSE:ssä: voit sijoittaa single-aktsii.php-tiedoston lapsiteemaan tai lisäosaan ja sisällyttää sen suodattimen kautta. Vaihtoehtoisesti Site Editorissa voit luoda pohjan tietylle mukautetulle sisältötyypille käyttöliittymän kautta: Ulkoasu → Editori → Pohjat → Lisää uusi pohja → Yksittäinen kohde: Aktsii. WordPress tallentaa sen HTML-pohjana tietokantaan, ja se toimii ilman tiedostoja teemassa.

Mitä valita vuonna 2026: tiedosto vai suodatin?

Nopea päätösmatriisi lähestymistavan valintaan:

Skenaario

Mitä käyttää

Perinteinen teema, yksi tai kaksi CPT:tä

single-{post_type}.php-tiedosto, minimaalinen koodi, automaattinen poiminta

Lapsiteema, olet lisäämässä CPT:tä

Tiedosto lapsiteemassa, säilyy vanhemman teeman päivityksissä

Lohkoteema (FSE), CPT lisäosan kautta

template_include-suodatin, riippumaton teeman rakenteesta

Lisäosana jaettava CPT

Suodatin + pohja lisäosakansion sisällä

Monta CPT:tä, joilla samankaltainen rakenne

Suodatin + jaettu single-cpt.php + pohjan osat

Käytännössä techblog.sdstudio.topissa käytämme useimmiten yhdistelmää: rekisteröimme CPT:n koodilla MU-lisäosassa ja sijoitamme pohjat tiedostoina lapsiteemaan. Tämä antaa automaattisen poiminnan ilman ylimääräisiä suodattimia, eivätkä vanhemman teeman päivitykset riko mitään.

Jos olet vasta aloittamassa mukautettujen sisältötyyppien opettelua, aloita single-{post_type}.php-tiedostosta. Se vie viisi minuuttia ja tuottaa välittömiä tuloksia. Kun tunnet, ettei tiedostopohjainen lähestymistapa enää riitä (sinun on ladattava pohjia lisäosasta tai vaihdettava niitä lennossa), siirry template_include-menetelmään. Molemmat tavat ovat täysin hyväksyttyjä ja WordPress-ytimen tukemia.