WordPress a vlastné metadata
V tomto tutoriáli sa naučíme pracovať vo WordPress-e s vlastnými metadata údajmi a to prostredníctvom metaboxov, ktoré doplníme do admin rozhrania. Prehĺbime si tiež znalosti ohľadom vytvárania pluginov a modifikácie štandardného správania cez filter hook a action hook.
Čo sú tu metadata? Metadata sú doplňujúce informácie, ktoré je možné ukladať k objektom WP (článkom, stránkam, multimediálnym prílohám, …). Tieto informácie je potom možné buď priamo zobrazovať na stránke, alebo na ich základe modifikovať správanie WP.
Hide post on homepage
Aby malo toto cvičenie aj nejaký praktický zmysel, vyrobíme si plugin, ktorý nám umožní nastaviť ku každému článku príznak, či sa má daný článok zobrazovať na titulnej stránke alebo nie. Skrytý článok bude normálne existovať, bude dostupný cez svoju url linku, bude tiež zobrazovaný vo výpise kategórie, ale nebude o ňom zmienka na hlavnej stránke. Tento plugin si pracovne nazveme „Hide post on homepage“.
Bežný článok sa štandardne na titulnej stránke zobrazuje, takže toto správanie meniť nebudeme. Metadata doplníme iba k článku, ktorý chceme skryť. Tento príznak = vlastné metadata, budeme preto nazývať „HideOnHomePage“. Ak bude mať hodnotu „1“ bude to znamenať, že predmetný článok sa nemá zobraziť na hlavnej domovskej stránke.
Pridanie metabox-u do admin rozhrania
Ako prvé začnime s tým, aby sa v admin rozhraní na obrazovke editácie článku zobrazil náš vlastný checkbox s popisom „Hide this post on homepage“. To docielime volaním funkcie add_meta_box(…), ktorú aktivujeme cez action hook add_meta_boxes.
function meta_box() { add_meta_box( 'hidepost', // jedinečné ID nášho metaboxu 'Hide on home', // názov metaboxu, zobrazí sa v admine 'render_meta_box', // funkcia s týmto názvom vykreslí náš checkbox null, // bude sa zobrazovať všade - články, stránky, ... 'side', // na obrazovke v pravom stĺpci 'high' // úplne hore, dá sa ale presunúť cez drag-and-drop ); } // action hook na aktiváciu funkcie na vytvorenie vlastného metaboxu add_action( 'add_meta_boxes', 'meta_box' );
Vlastný metabox už máme vytvorený, avšak zatiaľ je prázdny. Povedali sme, že jeho obsah vykreslí funkcia s názvom render_meta_box, takže ju teraz poďme nakódiť.
function render_meta_box( $post ) { // načítame predchádzajúcu hodnotu metadata (ak existuje) $meta = get_post_meta( $post->ID, '_HideOnHomePage', true ); // nastavíme správne vnútornú premennú $hp podľa načítaného metadata if( isset( $meta ) && $meta == '1' ) $hp = 1; else $hp = 0; // pridanie kontrolného reťazca ako skrytého parametra wp_nonce_field( basename( __FILE__ ), 'hp_nonce' ); // vykreslenie vstupného checkbox políčka // a jeho nastavenie podľa aktuálnej hodnoty metadata ?> <p> <input type="checkbox" id="hidepost" name="HidePost" value="1" <?php checked( $hp, 1 ); ?> /> <label for="hidepost">Hide this post on homepage</label> </p> <?php }
Všimnite si názov nášho metadata pri načítavaní cez funkciou get_post_meta(…). Zvolil som „_HideOnHomePage“. Podtrhovník na začiatku zabezpečí, že toto metadata sa nebude zobrazovať v štandardnom okne „Vlastné polia“. Metadata, ktorých názov začína potrhovníkom, považuje WP za technické metadata a ignoruje ich – nedovolí používateľovi ich priamu editáciu.
Uloženie metadát do databázy
Vykresliť metabox sme už zvládli, teraz musíme zabezpečiť, aby sa stav zaškrtnutia checkbox políčka uložil do databázy. Vytvoríme si teda funkciu „save_meta(…)“, ktorá sa naviaže na action hook save_post a postará sa o korektné spracovanie dát pri ukladaní článku. Samotné uloženie údajov do databázy je veľmi jednoduché, používa sa na to funkcia update_post_meta(…), ktorá záznam o metadátach buď aktualizuje, alebo vytvorí ak ešte neexistuje. Všetko ostatné sú len kontroly pred ukladaním dát.
function save_meta( $post_id ) { global $post; // Kontrola existencie parametra nonce // - zabezpečí, že bez predchádzajúceho zobrazenia metabox-u // nie je možné ukladať dáta if ( !isset( $_POST['hp_nonce'] ) || !wp_verify_nonce( $_POST['hp_nonce'], basename(__FILE__) ) ) { return $post_id; } // V prípade, ak prebieha iba autosave, nie je potrebné ukladať if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || ( defined('DOING_AJAX') && DOING_AJAX) || isset($_REQUEST['bulk_edit']) ) { return $post_id; } // V prípade, ak sa jedná o revíziu článku, nie je potrebné ukladať if ( isset( $post->post_type ) && $post->post_type == 'revision' ) { return $post_id; } // Kontrola, či má aktuálny používateľ oprávnenie na editáciu článku if ( !current_user_can( 'edit_post', $post->ID ) ) { return $post_id; } // Samotné uloženie údajov do databázy if( isset( $_POST['HidePost'] ) && $_POST['HidePost'] == '1' ) update_post_meta( $post->ID, '_HideOnHomePage', '1' ); else delete_post_meta( $post->ID, '_HideOnHomePage', '1'); } // aktivácia našej funkcie na ukladanie metadát do databázy add_action( 'save_post', 'save_meta', 10, 2 );
Dávam do pozornosti ešte jednu fintu – použitie funkcie delete_post_meta(…) – a to v prípade, ak náš checkbox „HidePost“ nie je zaškrtnutý. Ak by sme ukladali aj nezaškrtnutý stav do databázy cez update_post_meta(…), ku každému článku by nám odteraz pribudol jeden záznam v tabuľke, ktorý by obsahoval informáciu „0“. Každopádne sme na začiatku povedali, že štandardne sa článok zobrazovať bude, takže túto informáciu nie je potrebné ukladať (a zahlcovať tak zbytočne databázu). Ak záznam o metadátach už existuje, namiesto jeho aktualizácie na hodnotu „0“ ho jednoducho vymažeme. Funkcia delete_post_meta(…) v prípade, ak záznam o metadátach neexistuje, vráti hodnotu false, čo nám ale žili netrhá.
Funkčnosť ukladania informácií si môžete overiť pohľadom do tabuľky postmeta v databáze patriacej k vašej inštalácii WP (napr. cez phpMyAdmin).
Modifikácia zoznamu článkov na titulke
Na titulnej stránke chceme zobrazovať iba články, ktoré nemajú nastavený príznak „_HideOnHomePage“. To zabezpečíme tak, že zavesíme našu funkciu na action hook pre_get_posts a budeme cez ňu modifikovať priamo query, ktorá slúži na výber článkov z databázy. T.j. nerobíme filter až pri zobrazovaní článku, pretože ak by sme články iba skrývali, mohlo by sa stať, že by sme skryli väčšinu článkov na obrazovke, čím by sme zbytočne miatli návštevníkov webu.
function hide_posts( $query ) { // Iba v prípade, ak sa jedná o hlavné volanie, // nie je to volanie v administrácii a jedná sa o titulku if( $query->is_main_query() && !is_admin() && $query->is_home() ){ // načítanie aktuálnej query $meta_query = $query->get( 'meta_query' ); // ak žiadna query ešte neexistuje vytvor novú if( !is_array( $meta_query ) ) $meta_query = array(); // pridaj do query podmienku - zobrazuj článok iba v prípade // ak metadata '_HideOnHomePage' pre daný článok neexistuje, // alebo sa jeho hodnota nerovná "1" $meta_query[] = array( 'relation' => 'OR', array( 'key' => '_HideOnHomePage', 'compare' => 'NOT EXISTS', ), array( 'key' => '_HideOnHomePage', 'value' => 1, 'compare' => '!=', ) ); // Nastav modifikovanú query $query->set( 'meta_query', $meta_query ); } return $query; } // aktivácia našej funkcie cez action hook add_action( 'pre_get_posts', 'hide_posts' );
Súhrnná informácia v admin rozhraní
Na záver ešte jedna bonusovka. Do zoznamu článkov v administrácii WP doplníme stručnú informáciu o tom, či sa článok zobrazuje na titulke alebo nie. Musíme to však urobiť na 2 kroky. Najprv cez filter hook manage_posts_columns pridáme nový stĺpec s názvom „HomePage“.
function add_column( $columns ) { // pridaj nový stĺpec - t.j. pridaj nový záznam do poľa $columns return array_merge( $columns, array('hphp' => 'HomePage') ); } add_filter( 'manage_posts_columns', 'gm_hp_add_column' );
V zozname článkov by sa už mal objaviť nový stĺpec, zatiaľ však bude prázdny. Údaje do neho naplníme cez action hook manage_posts_custom_column.
function column_val( $column ) { global $post; // ak sa jedná o "náš" stĺpec if ( $column == 'hphp') { // načítaj metadata o článku z databázy $metaData = get_post_meta( $post->ID, '_HideOnHomePage', true ); // vypíš informáciu yes/no podľa načítaných metadata if ( $metaData == '1' ) echo ('nie'); else echo ('áno'); } } add_action( 'manage_posts_custom_column' , 'column_val' );
Hotovka!
Kompletný zdrojový kód pre tento plugin si môžete pozrieť / stiahnuť z môjho GitHub repository gendzo/hide-post. Ak ho chcete použiť vo svojej inštalácii WP, v adresári wp-content/plugins vytvorte nový podpriečinok s názvom „gm-hide-post“ a vložte do neho súbor gm-hide-post.php, ktorý si stiahnete z GitHub-u.
Použitá fotografia: blogging-typing-wordpress-macbook / Autor: StockSnap / Licencia: CC0