PHPPamokos.lt


6. Redagavimo lango skydeliai (metaboxes)

Namų darbai

Praėjusį kartą uždaviau pridėti įskiepiui du papildomus meta laukus:

  • tinyrelated_hide
  • tinyrelated_count

Abu jie buvo skirti konkrečiame įraše pakeisti standartinius nustatymus.

tinyrelated_hide pakeitimas yra append_list() metode (46-48 eilutė). Sąlyga patikrina, ar nustatyta šio lauko reikšmė ir, jei taip iš karto užbaigia funkciją gražindama nepakeistą $content;

tinyrelated_count pakeitimas - get_list() metode (93-94, 98, 106 eilutė). Prieš tai metodas tiesiogiai naudojo nustatymo reikšmę savo kode, dabar įvestas papildomas kintamasis $count.

Visas pakeistas tinyRelated v0.3.1 kodas.

Skydeliai

Labai dažnai įskiepių nori sukurti savo grafinę sąsają su įskiepiu susijusių papildomų laukų (ir kitų nustatymų) tvarkymui įrašo redagavimo lange. Jau nuo 2.5 WordPress versijos atsirado specialiai tam skirta funkcija add_meta_box(). O nuo 3.0 versijos atsirado add_meta_boxes ir add_meta_boxes_{post_type} veiksmo kabliai, kuriuose šią funkciją reikėtų išviesti (ankstesnėse versijose reikėtų naudoti admin_init veiksmo kablį).

Argumentai

add_meta_box( $id, $title, $callback, $post_type, $context, $priority, $callback_args );

Kaip matyti iš pavyzdžio, ši funkcija turi tikrai nemažai argumentų - net septynis. Ir tik 3 iš jų yra neprivalomi.

Privalomi argumentai

  • $id - HTML id atributas, kuris bus suteiktas pagrindiniam skydelio elementui;
  • $title - Skydelio antraštė, matoma vartotojui;
  • $callback - kaip ir kablių funkcijose, čia galima perduoti tik callable tipo kintamąjį - funkciją arba klasės metodą. Ši funkcija turės išspausdinti visą skydelio turinį.
  • $post_type - kuriame WP admin ekrane rodyti skydelį. Greta įprastinių įrašo tipų - post, page, {custom_post_type}, dar yra pasirinkimai dashboard (pradinis WP Admin langas), attachment (įkeltų failų redagavimo langas), nav-menus (navigacijos meniu redagavimo langas), link (nuorodų redagavimo langas).

Papildomi argumentai

  • $contenxt - nurodo, kurioje redagavimo lango vietoje pasirodys skydelis:
    • 'normal' - pagrindinis stulpelis, tuoj po įrašo teksto redagavimo lauku;
    • 'advanced' - taip pat pagrindinis stulpelis, bet žemiau, po visais 'normal' konteksto skydeliais (pagal nutylėjimą);
    • 'side' - šoninė juosta, ten kur yra publikavimo, kategorijų, žymų ir kt. skydeliai.
  • $priority - nuorodo eilės tvarką tarp to paties konteksto skydelių. Galimi variantai, žemėjančia tvarka:
    • 'high';
    • 'core';
    • 'default' (pagal nutylėjimą);
    • 'low'.
  • $callback_args - masyvas argumentų, kuriuos reikėtų perduoti $callback argumente nurodytai funkcijai. Šiai funkcijai bus perduotas $post objektas ir visi šiame argumente nurodyti kintamieji.

Pavyzdys

Taigi, pabandykime pridėti paprastutį skydelį su vienu <input> lauku į įrašų ('post') redagavimo langą:

add_action('add_meta_boxes_post','my_add_metabox');

function my_add_metabox(){
  add_meta_box(
    'my_metabox',
    'Mano skydelis',
    'my_print_metabox',
    'post'
  );
}

function my_print_metabox($post) {
  echo '<input type="text" name="my_metabox_text">';
}

Čia minimalus pavyzdys, visur, kur tik įmanoma naudojant numatytasias reikšmes. Dabar kiekvieną kartą atsidarę įrašo kūrimo/redagavimo langą matysime štai tokią dėžutę:

Papildomas skydelis įrašo redagavimo lauke

O jums - maža užduotėlė. Pabandykite šį kodą pataisyti taip, kad dėžutė atsirastų šoninėje juostoje.

Duomenų saugojimas

Kol kas ši dėžutė - tik butaforinė. Jokie joje įvesti duomenys paspaudus Save draft ar Publish nėra išsaugomi. Norint duomenis išsaugoti reikialingas papildomas save_post filtras.

Pabandykime šioje dėžutėje įvestą tekstą išsaugoti į įrašo meta lauką:

add_action('add_meta_boxes_post','my_add_metabox');
function my_add_metabox(){
  add_meta_box(
    'my_metabox',
    'Mano skydelis',
    'my_print_metabox',
    'post'
  );
}
function my_print_metabox($post) {
  echo '<input type="text" name="my_metabox_text" value="'.get_post_meta($post->ID,'_my_metabox_value',true).'">';
}

add_action( 'save_post', 'my_save_metabox' );
function my_save_metabox( $post_id ) {
  // If this is an autosave, our form has not been submitted, so we don't want to do anything.
  if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
    return;
  }
  $my_data = $_POST['my_metabox_text'];
  update_post_meta( $post_id, '_my_metabox_value', $my_data );
}
// add filter to automatically show related posts after post content
add_filter( 'the_content', array( 'tinyRelated', 'append_list') );

Dabar į laukelį įrašytas tekstas bus išsaugomas kaip meta laukas.

Saugumas

Turiu perspėti, kad aukščiau pateikto pavyzdžio copy/paste būdu nenaudotumėte gyvose svetainėse - siekdamas paprastumo, tame pavyzdyje visiškai nekreipiau dėmesio į saugumo dalykus. Dirbant su tokiais skydeliaisi būtinai reikėtų naudoti nonce laukus, patikrinti ar vartotojas turi reikiamas privilegijas, sanitizuoti vartotojo įvestus duomenis ir, galiausiai, patikrinti, ar tie duomenys iš tiesų įvesti.

Žemiau pateikiu išpėstą, pataisytą kodo gabaliuką, kur atsižvelgta į visus šiuos dalykus.

  • wp_nonce_field() funkcija sukuria apsauginį nonce lauką skydelyje;
  • wp_verify_nonce() funkcija patikrina, ar užklausa tikrai atėjo iš skydelio;
  • current_user_can() funkcija patikrina, ar vartotojas turi reikalingas privilegijas
  • sanitize_text_field() funkcija apsaugo nuo gudrybių vartotojo įvestuose duomenyse
add_action('add_meta_boxes_post','my_add_metabox');

function my_add_metabox(){
  add_meta_box(
    'my_metabox',
    'Mano skydelis',
    'my_print_metabox',
    'post'
  );
}

function my_print_metabox($post) {
  // Set nonce
  wp_nonce_field( 'my_metabox', 'my_metabox_nonce' );
  echo '<input type="text" name="my_metabox_text" value="'.get_post_meta($post->ID,'_my_metabox_value',true).'">';
}

add_action( 'save_post', 'my_save_metabox' );
function my_save_metabox( $post_id ) {
  // Check if our nonce is set.
  if ( ! isset( $_POST['my_metabox_nonce'] ) ) {
    return;
  }
  // Verify that the nonce is valid.
  if ( ! wp_verify_nonce( $_POST['my_metabox_nonce'], 'my_metabox' ) ) {
    return;
  }
  // If this is an autosave, our form has not been submitted, so we don't want to do anything.
  if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
    return;
  }
  // Check permissions
  if ( ! current_user_can( 'edit_post', $post_id ) ) {
    return;
  }  
  // Is field value set
  if ( ! isset( $_POST['my_metabox_text'] ) ) {
    return;
  }
  // Sanitize user input
  $my_data = sanitize_text_field( $_POST['my_metabox_text'] );
  update_post_meta( $post_id, '_my_metabox_value', $my_data );
}

tinyRelated

Šį kartą tinyRelated kodas gerokai išsiplėtė. Ankstesnioji (v0.3.1) versija turėjo 117 kodo eilučių, o naujoji (v0.4.0) - jau net 285 (!) eilutes.

Šis išsiplėtimas daugiausiai susijęs su tuo, kad teko susikurti keletą pagalbinių metodų skydelio HTML generavimui:

  • metabox_field() (nuo 197 eilutės) metodas leidžia lengvai išvesti įvairaus tipo (skaičių, teksto, checkbox, select ir pan.) laukus į skydelį;
  • dropdown() (nuo 239 eilutės) metodoas - vos vos pataisyta wp_dropdown_pages() versija. Mums reikėjo, kad ji veiktų su ne hierarchiniais tipais, tokiais kaip post. Esu tikras, kad tai galima padaryti elegantiškiau, tačiau mūsų poreikiams - pakanka ir tokio hack'o;

Abu šie metodai yra privatūs, t.y. jų negalima panaudoti už klasės ribų.

Taip pat atsirado dvi naujos prikabintos (31-32 eilutė) funkcijos:

  • add_metabox() (nuo 119 eilutės) - skydelio sukūrimui;
  • save_metabox() (nuo 159 eilutės) - skydelio duomenų saugojimui;

Ir galiausiai - print_metabox() funkcija (nuo 128 eilutės), išpausdinanti skydelio HTML kodą.

tinyRelated įskiepio skydelis redagavimo lange

Namų darbai

Ir vėl atėjo metas namų darbams:

  1. Pataisyti įskiepio kodą taip, kad jo sukuriami meta laukai nebūtų rodomi ir valdomi vartotojo sąsajoje - tik šios pamokos metu sukurtame skydelyje.
  2. Pataisyti skydelio generavimo kodą, kad jo generuojami <select> elementai būtų vaizduojami kompaktiškiau ir neužimtų tiek daug vietos ekrane.


(c) 2015-2018. Visais klausimais kreipkitės povilas@laraveldaily.com