Link Picker for CMB2 - Tutorial
<?php
function mkdo_create_meta_boxes() {
$prefix = '_profile_';
/**
* Initiate the metabox
*/
$cmb = new_cmb2_box(
array(
'id' => 'cta',
'title' => __( 'Call to Action', 'cmb2' ),
'object_types' => array( 'profile' ),
'context' => 'normal',
'priority' => 'low',
'show_names' => true,
)
);
/**
* Add the control
*/
$field1 = $cmb->add_field(
array(
'name' => __( 'Link Picker', 'cmb2' ),
'id' => $prefix . 'cta_link',
'type' => 'link_picker', // Here is where we add our control
)
);
}
add_action( 'cmb2_admin_init', 'mkdo_create_meta_boxes' );
jQuery(document).ready(function($) {
/* Set Defaults */
var url = $('body');
var text = $('body');
var blank = $('body');
/* Open the Link Window on button click */
$('body').on('click', '.js-insert-link', function(event) {
/* Stop the defalut event from happening */
event.preventDefault ? event.preventDefault() : event.returnValue = false;
event.stopPropagation();
/* Set the variables to related to the chosen control */
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 ');
/* Open the link picker */
wpActiveEditor = true;
wpLink.open();
wpLink.textarea = url;
return false;
});
/* If the action is canceled, close the link picker pop-up */
$('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;
});
/* Once the link is chosen, populate the control */
$('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;
});
});
<?php
global $post_id;
/* Media */
if ( isset( $post_id ) ) {
wp_enqueue_media( array( 'post' => $post_id ) );
}
/* JS */
$plugin_js_url = plugins_url( 'js/plugin.js', MKDO_LPFC_ROOT );
wp_enqueue_script( MKDO_LPFC_TEXT_DOMAIN, $plugin_js_url, array( 'jquery', 'jquery-ui-core', 'jquery-ui-draggable', 'jquery-ui-droppable', 'thickbox', 'wpdialogs' ), '1.0.0', true );
<?php
/**
* The following snippets are required for allowing the link_picker field
* to work as a repeatable field, or in a repeatable group
*/
public function cmb2_sanitize_link_picker( $check, $meta_value, $object_id, $field_args, $sanitize_object ) {
// if not repeatable, bail out.
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 not repeatable, bail out.
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;
}
<?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
}
<?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>';
<?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,
)
);
<?php
…
'type' => 'url',
…
<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'],
)
);
?>
<?php
$value = wp_parse_args(
$value,
array(
'text' => '',
'url' => '',
'blank' => 'false',
)
);
<?php
/**
* Render 'link_picker' custom field type
*
* @param array $field The passed in `CMB2_Field` object
* @param mixed $value The value of this field escaped.
* It defaults to `sanitize_text_field`.
* If you need the unescaped value, you can access it
* via `$field->value()`
* @param int $object_id The ID of the current object
* @param string $object_type The type of object you are working with.
* Most commonly, `post` (this applies to all post-types),
* but could also be `comment`, `user` or `options-page`.
* @param object $field_type_object The `CMB2_Types` object
*/
public function cmb2_render_link_picker( $field, $value, $object_id, $object_type, $field_type_object ) {
…
}
<?php
add_action( 'cmb2_render_link_picker', array( $this, 'cmb2_render_link_picker' ), 10, 5 );