Selles õpetuses vaatlen, kuidas saate luua kohandatud juhtelemendi, et laiendada WebDevStudios CMB2 (Custom Meta Boxes 2) funktsionaalsust.
Arendan veebisaite (ja veebirakendusi) WordPress CMS-iga (sisuhaldussüsteem) ning uue projekti jõudmisel võite garanteerida, et mul on nõue arendada välja kohandatud metakastid, mis võimaldavad kasutajal täpselt kontrollida saidi sisu ja paigutuse üle.
Kirjeldan üksikasjalikult, kuidas ma CMB2 jaoks CMB2 juhtlingi valija loosin (saadaval kõigist headest WordPressi pistikprogrammide hoidlatest). Ekraanipilti sellest saab näha allpool.
"Lingivalija" CMB2 juhtnupp töös
Lingivalija käivitab WordPressi sisseehitatud dialoogi „Lingi lisamine/muutmine", kui klõpsate nupul „Vali”. Seda on näha alloleval ekraanipildil:
Nupu vajutamine võimaldab valida lingi hulgast (või lisada oma)
Olen kindel, et nõustute sellega, et selline juhtseade on väga mugav, kui soovite anda oma saidi toimetajatele võimaluse lisada linki ja otsida ka WordPressist selle sisemisi linke, selle asemel, et nad peaksid lingid lingiks lõikama ja kleepima. valdkonnas.
Sissejuhatus / Ajalugu
Neile, kes ei tea, on WordPressi postituse redigeerimisekraanil metakast ja see sisaldab tõenäoliselt mitmesuguseid vormi juhtelemente (tekstikastid, ripploendid, märkeruudud jne). Need juhtelemendid võimaldavad teie veebisaidi kasutajatel hõlpsasti muuta saidi kohandatud tekstiosa või funktsioone.

Erinevate vormijuhtelementidega metakasti näide
WordPress võimaldab luua metakaste funktsioonide (nt [add_meta_box](https://developer.wordpress.org/reference/functions/add_meta_box/)) abil, kuid sellisel viisil metakastide loomine võib olla pikk protsess, millega kaasneb palju koodikordusi (eriti kui soovite kasutada samu vormijuhtelemente mitmes projektis).
Miks CMB2?
Mõned teist võib-olla on kuulnud Advanced Custom Fields (ACF), mis pakub GUI-d (graafiline kasutajaliides), mis võimaldab teil luua metakaste otse WordPressiga.
ACF ei ole minu arvates suurepärane tööriist ühegi skaleeritava veebilahenduse jaoks. Pistikprogramm sõltub liiga palju andmebaasis salvestatavatest andmetest. See põhjustab saidil muudatuste juurutamisel valu, kuna te ei saa lihtsalt koodi üles lükata ja muudatusi kohe näha. Selle asemel peate uuesti tegema tööd erinevates juurutuskeskkondades (lavastamine, otseülekanne jne). Seega vajasime lahendust, mis võimaldaks meil programmiliselt metakaste luua. Sisestage CMB2.
Enne CMB2 kasutuselevõttu kasutasime varem nende armsate inimeste HM -i kohandatud metabokse Human Made’is (mis sai alguse WebDevStudio eelkäija CMB2-le).
Meile meeldisid HM kohandatud metakastid ja kõige lihtsamate koodilõikude abil saime kiiresti luua kohandatud metabokse, et teha peaaegu kõike!
HM kohandatud metakastide märgistuse näide (see on Instagrami metaboksi märgistus esimesel ekraanipildil)
Miks siis üle minna CMB2-le? Noh, HM Custom Meta Boxes ei pälvinud kahjuks suurt armastust (rääkisin selle peaarendajaga ja ta on väga hõivatud mees), samas kui CMB2 liikus edasi uute funktsioonide, uute juhtelementidega ja see oli kogunud tõmbejõudu. WordPressi kogukonnas, kus paljud inimesed on selle kasutusele võtnud ja selle laiendamiseks pistikprogrammid välja lasknud (sealhulgas mitmed meie partneragentuurid).
Lõpuks, nagu võisite aru saada, on CMB2-ga töötamine sama uskumatult lihtne, kui olime harjunud, kuna mõlemal platvormil on ühine esivanem.
Õpetus
Enne kui alustame, on igaühel oma ideaalid WordPressi pistikprogrammi loomise kohta ja ma olen proovinud mõndagi, kuid Tom J Nowelli õpetus WordPressi juurkompositsioonist muutis täielikult minu tööviisi. Minu arvates on selle lähenemine puhas, lihtne ja see muudab iga pistikprogrammi tulevase hooldamise lihtsaks. Kui otsite pistikprogrammi Link Picker for CMB2 allikast, näete, milliseid meetodeid ta praktikas õpetab.
Vormi ehitamine
Lingivalijat renderdava vormi loomiseks peame esimese asjana haakima cmb2_render_[control_name]toiminguga. Nagu ma nimetasin seda juhtelementi link_pickeriks, saame konksu lõpule viia järgmiselt:
<?php
add_action( 'cmb2_render_link_picker', array( $this, 'cmb2_render_link_picker' ), 10, 5 );
`
Neile, kes add_actionkonksust tegelikult aru ei saa, toimib see järgmiselt:
- Esimene argument
cmb2_render_link_pickeron konksu nimi, mille külge tahame haakida. - Teine argument
array( $this, 'cmb2_render_link_picker' )on funktsioon, mida tahame selle konksu käivitamisel kutsuda. Pange tähele, et ma mähkin selle massiivi, mille$thisesimene parameeter on, kuna ma kutsun funktsiooni klassi sees. Kui te ei tööta klassidega, võite lihtsalt kasutada funktsiooni nimecmb2_render_link_picker.
3., on10järjekord, mille järgi tahame funktsiooni käivitada (mida väiksem on number, seda varem see toimingu kutsumisel käivitub). - See
5on parameetrite hulk, mis edastatakse funktsioonile, mida ma kutsun (see selgub peagi).
Järgmisena loome funktsiooni, mis vormi renderdab:
<?php
public function cmb2_render_link_picker( $field, $value, $object_id, $object_type, $field_type_object) {
…
}
`
Olen jätnud ülaltoodud koodi "DocBlock", mis kirjeldab, mida iga cmb2_render_link_picker()funktsiooni edastatud parameeter teeb.
Pange tähele, et minu funktsioon algab publicdeklaratsiooniga. See on jällegi sellepärast, et ma töötan klassis. Kui te ei tööta klassidega, võite selle vahele jätta.
Selle välja väärtus edastatakse $valueparameetri kaudu funktsioonile. Selle välja puhul läbime massiivi, kuna meie juhtelemendil on kolm eraldi elementi:
- Tekst
- URL
- Kui link avaneb uues aknas (või mitte)
Kuna $valueei ole alati määratud (näiteks juhtelemendi esmakordsel renderdamisel), peame selle initsialiseerima mõne vaikeväärtusega. Teeme seda järgmise koodibitiga:
<?php
$value = wp_parse_args(
$value,
array(
'text' => '',
'url' => '',
'blank' => 'false',) );
Seejärel saame asuda vormi renderdamisega tegelema. Siin on näide esimesest tekstisisestuse juhtelemendist:
<p>
<label for="<?php echo $field_type_object->_id( '_text' ); ?>'">
<?php echo esc_html( $field_type_object->_text( 'link_picker_text', 'Text') ); ?>
</label>
</p>
<?php
echo $field_type_object->input(
array(
'class' => 'cmb_text',
'name' => $field_type_object->_name( '[text]' ),
'id' => $field_type_object->_id( '_text' ),
'value' => $value['text'],) );
?>
Pheh! See tundub natuke räpane, kas pole? Jaotame selle ridade kaupa:
- Ava lõigu silt.
- Juhtelemendi avasildi märgend, kuid parameetri
forpoolt automaatselt määratud atribuudiga.$field_type_object_idSee genereerib juhtelemendile selle renderdamisel automaatselt ID. - Meie sildi tekst, mis on koostatud juhtelementide massiivi teksti abil (või taandub sõnale „Tekst”).
- Lõpusildi silt
- Lõigu sulgev silt.
- Käivitage PHP deklaratsioon
- Kasutage sisendi juhtelementi (osa
$field_type_objectvormi sisendi loomiseks (vaiketüüp on tekst). - Käivitage parameetrite massiiv
- Määrake sisendi klass.
- Määrake sisendi nimi, kasutades uuesti
$field_type_objectabistajat. - Määrake sisendi ID-ks sama ID, mis määrati sildisildil.
- Hankige väärtus jaotisest
$value, kuna see on massiiv, tahame selle juhtelemendi jaoks tekstiklahvi. - Sulgege massiiv.
- Sulgege sisestusfunktsioon.
- Sulgege PHP deklaratsioon.
URL-i vormi välja märgistus on paljuski sama, ainult HTML5 sisestustüüpide kasutamiseks saame määrata täiendava parameetri ‘type’ väärtuseks ‘url’:
<?php
…
'type' => 'url',
…
Lõpuks tahame rakendada rippmenüüd. Märgistus on väga tuttav:
<?php
echo $field_type_object->select(
array(
'class' => 'cmb_dropdown',
'name' => $field_type_object->_name( '[blank]' ),
'id' => $field_type_object->_id( '_blank' ),
'options' => $blank_options,) );
Pange tähele, et $field_type_objectmeie kasutatav funktsioon on selectrippmenüü loomine. Pange tähele ka seda, et real 6 on meil uus atribuut options. Sellesse me edastame "valikute" jada. See luuakse enne seda juhtelementi järgmiselt:
<?php
$blank_options = '';
$blank_options .= '<option value="false" '. selected( $value['blank'], 'false', false) .'>Opens in same</option>';
$blank_options .= '<option value="true" '. selected( $value['blank'], 'true', false) .'>Opens in new</option>';
Siis ei pea me tegema muud, kui mähkima selle mõnesse <div>ja meil on täielikult renderdatud kontroll:
<?php
public function cmb2_render_link_picker( $field, $value, $object_id, $object_type, $field_type_object) {
$value = wp_parse_args( $value, array(
'text' => '',
'url' => '',
'blank' => 'false',) );
$blank_options = '';
$blank_options .= '<option value="false" '. selected( $value['blank'], 'false', false) .'>Opens in same</option>';
$blank_options .= '<option value="true" '. selected( $value['blank'], 'true', false) .'>Opens in new</option>';
?>
<div class="link-picker">
<div class="text">
<p>
<label for="<?php echo $field_type_object->_id( '_text' ); ?>'">
<?php echo esc_html( $field_type_object->_text( 'link_picker_text', 'Text') ); ?>
</label>
</p>
<?php
echo $field_type_object->input(
array(
'class' => 'cmb_text',
'name' => $field_type_object->_name( '[text]' ),
'id' => $field_type_object->_id( '_text' ),
'value' => $value['text'],
'desc' => '',) );
?>
</div>
<div class="url">
<p>
<label for="<?php echo $field_type_object->_id( '_url' ); ?>'">
<?php echo esc_html( $field_type_object->_text( 'link_picker_url', 'URL') ); ?>
</label>
</p>
<?php
echo $field_type_object->input(
array(
'class' => 'cmb_text_url',
'name' => $field_type_object->_name( '[url]' ),
'id' => $field_type_object->_id( '_url' ),
'value' => $value['url'],
'type' => 'url',
'desc' => '',) );
?>
</div>
<div class="blank">
<p>
<label for="<?php echo $field_type_object->_id( '_blank' ); ?>'">
<?php echo esc_html( $field_type_object->_text( 'link_picker_blank', 'Window') ); ?>
</label>
</p>
<?php
echo $field_type_object->select(
array(
'class' => 'cmb_checkbox',
'name' => $field_type_object->_name( '[blank]' ),
'id' => $field_type_object->_id( '_blank' ),
'options' => $blank_options,
'desc' => '',) );
?>
</div>
<div class="choose">
<p>
<label>Choose</label>
</p>
<button class="dashicons dashicons-admin-links js-insert-link button button-primary" title="<?php esc_html_e( 'Insert Link', 'cmb' ); ?>">
<span class="screen-reader-text"><?php esc_html_e( 'Choose Link', 'cmb' ); ?></span>
</button>
</div>
</div>
<p class="clear">
<?php echo $field_type_object->_desc();?>
</p>
<?php
}
Ja see ongi kõik! Oleme oma kontrolli teinud! CMB2 töötleb automaatselt kõiki andmeid, mida tahame salvestada, seega pole seal midagi teha.
Stiilid
Loodava juhtelemendi ekraanipildil (selle postituse ülaosas) on rakendatud mõned kohandatud stiilid, nii et see kuvatakse tekstisiseselt. Ma ei käsitle täna vormi stiili kujundamist, kuid kui olete uudishimulik, saate pistikprogrammi alla laadida ja allikat vaadata.
Kontrolli korratavaks muutmine
Neile teist, kes soovivad veidi edasi areneda, saate CMB2 korratavate piirkondadega juhtimise tööle panna. Selleks peate veidi massiivi kaardistama. Selleks kasutage allolevat koodi:
<?php
public function cmb2_sanitize_link_picker( $check, $meta_value, $object_id, $field_args, $sanitize_object) {
if (! is_array( $meta_value) ||! $field_args['repeatable']) {
return $check;
}
foreach ($meta_value as $key => $val) {
$meta_value[ $key ] = null;
if(! empty( $val['url'])) {
$meta_value[ $key ] = array_map( 'sanitize_text_field', $val );
}
}
return $meta_value;
}
public function cmb2_types_esc_link_picker( $check, $meta_value, $field_args, $field_object) {
if (! is_array( $meta_value) ||! $field_args['repeatable']) {
return $check;
}
foreach ($meta_value as $key => $val) {
$meta_value[ $key ] = null;
if(! empty( $val['url'])) {
$meta_value[ $key ] = array_map( 'esc_attr', $val );
}
}
return $meta_value;
}
Lingi valimine
Muidugi on lingivalija eesmärk integreerida WordPressi enda lingi valimise funktsiooni, muutes nupul ‘Vali’ klõpsamisel hüpikakna ‘Lingi lisamine/redigeerimine’.
Selle teostamiseks toetume suuresti JavaScriptile. Eelkõige kasutan asjade elluviimiseks jQueryt.
Enne kui näitan teile dialoogi käivitavat JavaScripti, peame esmalt järjekorda panema WordPressi enda sisemise JavaScripti, mis eellaadib modaalid ja teegid, millest meie kood sõltub. See näeb välja umbes selline:
<?php
global $post_id;
if (isset( $post_id)) {
wp_enqueue_media( array( 'post' => $post_id) );
}
$plugin_js_url = plugins_url( 'js/plugin.js', ROOT );
wp_enqueue_script( 'wholesomecode', $plugin_js_url, array( 'jquery', 'jquery-ui-core', 'jquery-ui-draggable', 'jquery-ui-droppable', 'thickbox', 'wpdialogs' ), '1.0.0', true );
Nagu näete, tuginevad paljud sisemised WordPressi teegid hüpikakna laadimiseks jQueryle, seega on mõistlik, et meie hüpikakna käivitaja teeb sama. Seda tehakse /js/plugin.jsülaltoodud näite reale 10 laaditud rakenduse kaudu.
jQuery(document).ready(function($) {
var url = $('body');
var text = $('body');
var blank = $('body');
$('body').on('click', '.js-insert-link', function(event) {
event.preventDefault? event.preventDefault(): event.returnValue = false;
event.stopPropagation();
url = $(this).closest('.link-picker').find('input.cmb_text_url ');
text = $(this).closest('.link-picker').find('input.cmb_text ');
blank = $(this).closest('.link-picker').find('input.cmb_checkbox ');
wpActiveEditor = true;
wpLink.open();
wpLink.textarea = url;
return false;
});
$('body').on('click', '#wp-link-cancel, #wp-link-backdrop, #wp-link-close', function(event) {
wpLink.textarea = url;
wpLink.close();
event.preventDefault? event.preventDefault(): event.returnValue = false;
event.stopPropagation();
return false;
});
$('body').on('click', '#wp-link-submit', function(event) {
console.log(text)
var linkAtts = wpLink.getAttrs();
linkAtts.text = $('#wp-link-text').val();
url.val(linkAtts.href);
if( linkAtts.text != '') {
text.val(linkAtts.text);
}
if (linkAtts.target == '_blank') {
blank.prop('checked', true);
} else {
blank.prop('checked', false);
}
wpLink.textarea = url;
wpLink.close();
event.preventDefault? event.preventDefault(): event.returnValue = false;
event.stopPropagation();
return false;
});
});
Kasutades klasse, mille panime oma vormi juhtelementide ümber, sihib JavaScript juhtelemente ja surub lingivalija hüpikaknas valitud tulemuse asjakohastele juhtväljadele.
Juhtnupu kasutamine
Nii et pärast ülaltoodud õpetuse läbivaatamist ja võib-olla pärast pistikprogrammi Link Picker for CMB2 lähtekoodi ülevaatamist või lihtsalt minu versiooni allalaadimist võite nüüd mõelda, kuidas seda asja CMB2-ga kasutada. Noh, see ei saaks olla lihtsam:
<?php
function wholesomecode_create_meta_boxes() {
$prefix = '_profile_';
$cmb = new_cmb2_box(
array(
'id' => 'cta',
'title' => __( 'Call to Action', 'cmb2' ),
'object_types' => array( 'profile' ),
'context' => 'normal',
'priority' => 'low',
'show_names' => true,) );
$field1 = $cmb->add_field(
array(
'name' => __( 'Link Picker', 'cmb2' ),
'id' => $prefix. 'cta_link',
'type' => 'link_picker',) );
}
add_action( 'cmb2_admin_init', 'wholesomecode_create_meta_boxes' );