Skip to content

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

🛠 Yksinomaiset taksonomiat WordPressissä: miten korvata valintaruudut valintanapeilla

🛠 Yksinomaiset taksonomiat WordPressissä: miten korvata valintaruudut valintanapeilla

Oletuksena WordPress sallii sinun liittää julkaisuun niin monta termiä yhdestä taksonomiasta kuin haluat. Valintaruudut sivupalkissa, ja homma on valmis. Mutta entä jos asiakas tarvitsee, että toimittaja valitsee täsmälleen yhden vaihtoehdon? Esimerkiksi "Projektityyppi": case study, landing page tai verkkokauppa. Kolme vaihtoehtoa, eikä kahden valitseminen yhtä aikaa ole järkevää.

WordPressissä ei ole sisäänrakennettua "tee taksonomiasta yksinomainen" -kytkintä. Tracissa on ollut tiketti vuodesta 2010 ilman edistystä. Mutta tehtävä on ratkaistavissa koodilla, ilman lisäosia tai ylimääräisiä riippuvuuksia.

Tämän artikkelin loppuun mennessä muutat vakiona olevan valintaruutulaatikon paneeliksi, jossa on valintanapit: täsmälleen yksi termi per julkaisu, vähemmän toimittajan virheitä.

💡 Nopea yleiskatsaus:

  • Rekisteröi taksonomia meta_box_cb-parametrilla, jotta vakiolaatikkoa ei näytetä.
  • Luo add_meta_boxes-koukussa oma lohko, jossa on valintanapit.
  • Käytä save_post-koukkua kirjoittaaksesi valitun termin tietokantaan.
  • Koko koodin voi kopioida lapsiteeman functions.php-tiedostoon, ja se toimii heti.

Mitä taksonomiat ovat ja miksi yksinomaisuudella on väliä

Taksonomia WordPressissä on mekanismi julkaisujen ryhmittelyyn. Vakiona olevat "Kategoriat" ja "Avainsanat" ovat myös taksonomioita. Mukautettu taksonomia luodaan tiettyä tehtävää varten: "Projektityyppi" portfoliolle, "Alue" toimipistehakemistolle, "Palvelutyyppi" hinnastolle.

Sisäänrakennetut kategoriat toimivat yksinomaisena taksonomiana: julkaisu kuuluu täsmälleen yhteen kategoriaan, ellet käytä laajennuslisäosia. "Ylätaso → alataso" -hierarkia antaa toimittajalle vihjeen valintalogiikasta.

Mikä tahansa register_taxonomy()-funktiolla rekisteröity mukautettu taksonomia on kuitenkin oletuksena ei-yksinomainen. Käyttöliittymä koostuu valintaruuduista tai automaattisen täydennyksen kentästä. Avainsanoille ja tuoteattribuuteille tämä on oikein. Mutta kun jokaisella julkaisulla on oltava täsmälleen yksi termi, valintaruuduista tulee virheiden lähde.

Ratkaisu: piilota vakiona oleva laatikko ja renderöi oma, jossa on valintanapit ja tiukka hallinta. Tämä ei ole kiertotie vaan dokumentoitua WordPress API:a, joka on vain hajautettu useampaan vaiheeseen.

Vaihe 1: rekisteröi mukautettu taksonomia

Perustana on register_taxonomy()-funktio. Koodi lisätään lapsiteeman functions.php-tiedostoon tai Code Snippets -lisäosan kautta. Luodaan project_type-taksonomia tavallisille julkaisuille:

1function sd_register_project_type_taxonomy() {
2 register_taxonomy(
3 'project_type',
4 'post',
5 array(
6 'label' => __( 'Project Type', 'textdomain' ),
7 'public' => true,
8 'show_in_rest' => true,
9 'hierarchical' => true,
10 'show_in_quick_edit' => false,
11 'meta_box_cb' => false,
12 )
13 );
14}
15add_action( 'init', 'sd_register_project_type_taxonomy' );

Keskeiset parametrit:

  • hierarchical => true mahdollistaa puurakenteen, kuten kategorioissa. Termit järjestetään hierarkkisesti: "Design → Landing page", "Kehitys → Verkkokauppa".
  • show_in_rest => true tekee taksonomiasta saatavan REST API:ssa ja lohkoeditorissa. Ilman tätä Gutenberg ei näe laatikkoa.
  • meta_box_cb => false ja show_in_quick_edit => false poistavat kokonaan vakiona olevan terminvalintakäyttöliittymän.

Koodin tallentamisen jälkeen project_type-taksonomia ilmestyi "Artikkelit"-valikkoon. Termit lisätään kohdasta "Artikkelit → Projektityyppi" vakioliittymällä, kuten kategorioille.

Vaihe 2: piilota vakiona oleva laatikko

Tämä vaihe on itse asiassa jo tehty vaiheen 1 meta_box_cb- ja show_in_quick_edit-parametreilla. Kertauksena:

  • meta_box_cb => false poistaa laatikon artikkelin muokkaussivulta.
  • show_in_quick_edit => false piilottaa taksonomian pika- ja massamuokkauspaneeleista.

Ilman niitä WordPress lisää oletuskäyttöliittymän: hierarkkisille taksonomioille kategoriavalintaruudut; ei-hierarkkisille avainsanakentän automaattisella täydennyksellä.

meta_box_cb- ja show_in_quick_edit-parametrit register_taxonomy-funktiossa

Termit täytetään erillisen hallintasivun kautta:

Mukautetun taksonomian termien hallintasivu WordPress-hallinnassa

Vaihe 3: luo mukautettu laatikko valintanapeilla

Rekisteröi oma laatikko add_meta_boxes-koukun kautta. Lisää functions.php-tiedostoon:

1add_action( 'add_meta_boxes', 'sd_add_project_type_meta_box' );
2
3function sd_add_project_type_meta_box() {
4 add_meta_box(
5 'project_type_box',
6 __( 'Project Type', 'textdomain' ),
7 'sd_render_project_type_meta_box',
8 'post',
9 'side',
10 'default'
11 );
12}

add_meta_box()-funktion parametrit:

  • project_type_box: sisäinen tunniste (mielivaltainen mutta uniikki).
  • 'Project Type': otsikko hallintapaneelissa.
  • sd_render_project_type_meta_box: renderöintifunktio.
  • 'post': julkaisutyyppi; voi olla taulukko useille CPT:ille.
  • 'side': sivupalkki. Vaihtoehdot: 'normal', 'advanced'.

Funktio, joka renderöi valintanapit:

1function sd_render_project_type_meta_box( $post ) {
2 $terms = get_terms( array(
3 'taxonomy' => 'project_type',
4 'hide_empty' => false,
5 ) );
6
7 if ( empty( $terms ) || is_wp_error( $terms ) ) {
8 echo '<p>First, add terms on the “Project Type” page.</p>';
9 return;
10 }
11
12 $current_terms = get_the_terms( $post->ID, 'project_type' );
13 $current_id = ( ! empty( $current_terms ) && ! is_wp_error( $current_terms ) )
14 ? $current_terms[0]->term_id
15 : 0;
16
17 foreach ( $terms as $term ) : ?>
18 <label style="display:block;margin-bottom:4px;">
19 <input type="radio"
20 name="project_type_term"
21 value="<?php echo esc_attr( $term->term_id ); ?>"
22 <?php checked( $current_id, $term->term_id ); ?>>
23 <?php echo esc_html( $term->name ); ?>
24 </label>
25 <?php endforeach;
26}

Mikä tässä on tärkeää:

  • get_terms() parametrilla hide_empty => false palauttaa kaikki termit, myös käyttämättömät.
  • get_the_terms() palauttaa taulukon; otamme ensimmäisen alkion [0], koska logiikka takaa enintään yhden termin.
  • checked() on sisäänrakennettu WordPress-funktio, joka tulostaa checked="checked", kun osuma löytyy.
  • esc_attr() ja esc_html() ovat pakollista eskapointia.

Lopputuloksena on siisti lohko valintanapeilla:

Mukautettu metalaatikko, jossa valintanapit yhden taksonomiatermin valitsemiseen

Ei valintaruutuja, ei mahdollisuutta valita kahta vaihtoehtoa.

Vaihe 4: tallenna termi, kun julkaisu tallennetaan

Ilman tätä vaihetta laatikko on pelkkä koriste. Käytämme save_post-koukkua:

1add_action( 'save_post', 'sd_save_project_type_term' );
2
3function sd_save_project_type_term( $post_id ) {
4 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
5 return;
6 }
7
8 if ( ! current_user_can( 'edit_post', $post_id ) ) {
9 return;
10 }
11
12 if ( isset( $_POST['project_type_term'] ) ) {
13 $term_id = absint( $_POST['project_type_term'] );
14 wp_set_object_terms( $post_id, $term_id, 'project_type' );
15 }
16}

Yksityiskohdat:

  • DOING_AUTOSAVE: ohitamme automaattitallennukset. Ilman tätä tarkistusta termi ylikirjoitetaan taustalla 60 sekunnin välein.
  • current_user_can( 'edit_post', $post_id ): perustason käyttöoikeustarkistus.
  • absint() muuntaa arvon positiiviseksi kokonaisluvuksi, turvallisempi kuin (int) sanitize_text_field().
  • wp_set_object_terms() yhdellä tunnisteella (ei taulukkona) kirjoittaa täsmälleen yhden termin ja poistaa aiemmat liitokset.

Valmista. Tallenna julkaisu, niin valintanapin valinta lukittuu. Kun avaat sen uudelleen, valittu termi on korostettuna.

Koko koodi kopioitavaksi

Kaikki neljä vaihetta yhdessä pätkässä. Lisää lapsiteemasi functions.php-tiedostoon tai Code Snippets -lisäosan kautta:

1/**
2 * Exclusive taxonomy "Project Type" — one term per post.
3 * Add to child theme's functions.php.
4 */
5function sd_register_project_type_taxonomy() {
6 register_taxonomy(
7 'project_type',
8 'post',
9 array(
10 'label' => __( 'Project Type', 'textdomain' ),
11 'public' => true,
12 'show_in_rest' => true,
13 'hierarchical' => true,
14 'show_in_quick_edit' => false,
15 'meta_box_cb' => false,
16 )
17 );
18}
19add_action( 'init', 'sd_register_project_type_taxonomy' );
20
21add_action( 'add_meta_boxes', 'sd_add_project_type_meta_box' );
22
23function sd_add_project_type_meta_box() {
24 add_meta_box(
25 'project_type_box',
26 __( 'Project Type', 'textdomain' ),
27 'sd_render_project_type_meta_box',
28 'post',
29 'side',
30 'default'
31 );
32}
33
34function sd_render_project_type_meta_box( $post ) {
35 $terms = get_terms( array(
36 'taxonomy' => 'project_type',
37 'hide_empty' => false,
38 ) );
39
40 if ( empty( $terms ) || is_wp_error( $terms ) ) {
41 echo '<p>First, add terms on the “Project Type” page.</p>';
42 return;
43 }
44
45 $current_terms = get_the_terms( $post->ID, 'project_type' );
46 $current_id = ( ! empty( $current_terms ) && ! is_wp_error( $current_terms ) )
47 ? $current_terms[0]->term_id
48 : 0;
49
50 foreach ( $terms as $term ) : ?>
51 <label style="display:block;margin-bottom:4px;">
52 <input type="radio"
53 name="project_type_term"
54 value="<?php echo esc_attr( $term->term_id ); ?>"
55 <?php checked( $current_id, $term->term_id ); ?>>
56 <?php echo esc_html( $term->name ); ?>
57 </label>
58 <?php endforeach;
59}
60
61add_action( 'save_post', 'sd_save_project_type_term' );
62
63function sd_save_project_type_term( $post_id ) {
64 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
65 return;
66 }
67
68 if ( ! current_user_can( 'edit_post', $post_id ) ) {
69 return;
70 }
71
72 if ( isset( $_POST['project_type_term'] ) ) {
73 $term_id = absint( $_POST['project_type_term'] );
74 wp_set_object_terms( $post_id, $term_id, 'project_type' );
75 }
76}

⚠️ Tee täysi varmuuskopio sivustosta ennen liittämistä. Koodi on testattu WordPressin nykyisellä versiolla perinteisellä editorilla. Gutenbergissä mukautettu laatikko näkyy sivupalkissa ilman muutoksia.

Käytännössä otimme tämän pätkän käyttöön kolmessa projektissa, ja se toimi kaikkialla ilman muokkauksia. Jos sinulla on hierarkkinen julkaisutyyppi tai useita toimittajarcoleja, korvaa 'post' omalla polkutunnuksellasi ja varmista käyttöoikeudet save_post-kohdassa.


WordPress Tracissa on ollut avoinna tiketti #14877 vuodesta 2010 natiivia yksinomaisen taksonomian tukea varten. Kun 'exclusive' => true -parametri ilmestyy ytimeen, tämä koko rakennelma kutistuu yhteen riviin. Ennen kuin tiketti etenee, valintanappiratkaisu pysyy ensisijaisena ratkaisuna.

Ja alla lyhyt video aiheesta, jotta näet prosessin toiminnassa:

⁉️🤔 Usein kysytyt kysymykset

Toimiiko tämä Gutenbergissä?

Kyllä. show_in_rest => true -parametri taksonomiaa rekisteröitäessä mahdollistaa yhteensopivuuden lohkoeditorin kanssa. Mukautettu laatikko ilmestyy dokumentin sivupalkkiin, ja valintanapit näkyvät ja tallentuvat oikein.

Voiko tätä lähestymistapaa soveltaa mukautettuihin julkaisutyyppeihin?

Kyllä. Korvaa 'post' kohdissa register_taxonomy() ja add_meta_box() oman CPT:si polkutunnuksella. Muu koodi (taksonomian nimi, selite, parametrit) pysyy samana. Lähestymistapa toimii minkä tahansa rekisteröidyn julkaisutyypin kanssa, mukaan lukien ACF:n tai Custom Post Type UI:n kautta luodut.

Mitä tapahtuu, jos toimittaja ei valitse mitään termiä?

Julkaisu tallentuu ilman määritettyä termiä; save_post ei yksinkertaisesti kutsu wp_set_object_terms()-funktiota. Jos pakollinen valinta on kriittinen, lisää JavaScript-validointi hallintaan tai tarkistus pre_post_update-koukun kautta.

Miksei käyttäisi Radio Buttons for Taxonomies -lisäosaa?

Voit käyttää. Lisäosa ratkaisee tehtävän ilman koodia ja sillä on yli 100 000 aktiivista asennusta. Haittapuolena on yksi riippuvuus lisää. Yhdelle tai kahdelle sivustolle lisäosa on perusteltu. Toimistoille ja multisite-asennuksille teemaan sijoitettu koodi antaa täyden hallinnan ilman ylimääräisiä päivityksiä ja ristiriitoja.

Miten lisään hierarkkisen valinnan (ylätaso → alataso)?

Hierarkkiset taksonomiat (hierarchical => true) saavat automaattisesti ylätaso-alataso-rakenteen. Näyttääksesi hierarkian mukautetussa laatikossa, korvaa get_terms() funktiolla wp_dropdown_categories() käyttäen 'taxonomy' => 'project_type' -parametria; funktio tulostaa valintalistan sisennyksillä.

Lopputulos: milloin koodin kirjoittaminen kannattaa

Yksinomaista taksonomiaa ei tarvita joka projektissa. Jos toimittajat ymmärtävät sivuston logiikan eivätkä tee virheitä valitessaan, tavalliset valintaruudut riittävät. Mutta kun virheiden hinta on korkea (portfolion landing page merkitty vahingossa sekä "verkkokaupaksi" että "case studyksi"), puolen tunnin koodaus maksaa itsensä takaisin sisällön siisteytenä.

  • Jos sinulla on yksi sivusto eikä kehittäjää, asenna Radio Buttons for Taxonomies. Se toimii ilman koodia.
  • Jos olet toimisto tai hallinnoit multisiteä, kopioi yllä oleva koodi perusteemaasi. Vähemmän lisäosia, vähemmän vikaantumispisteitä päivitysten yhteydessä.
  • Jos sivustosi toimii puhtaalla Gutenbergillä, harkitse, tarvitsetko edes taksonomiaa. Ehkä ACF-kenttä valintanapeilla riittää: vähemmän entiteettejä, nopeampi hallinta.

Aloita testisivustolla. Rekisteröi taksonomia, lisää kolme termiä ja luo artikkeli; käyttöliittymä toimii heti. Kirjoita kommentteihin, mihin tehtävään käytit yksinomaista taksonomiaa.