How to get value of custom meta boxes - woocommerce

I created some custom meta boxes for products.
In writepanel-product_data.php I added:
woocommerce_wp_text_input( array( 'id' => 'orario', 'class' => '', 'label' => __('Orario', 'woocommerce') ) );
woocommerce_wp_text_input( array( 'id' => 'luogo_evento', 'class' => '', 'label' => __('Luogo Evento', 'woocommerce') ) );
woocommerce_wp_text_input( array( 'id' => 'indirizzo', 'class' => '', 'label' => __('Indirizzo', 'woocommerce') ) );
woocommerce_wp_text_input( array( 'id' => 'zona', 'class' => '', 'label' => __('Zona', 'woocommerce') ) );
woocommerce_wp_text_input( array( 'id' => 'contatti', 'class' => '', 'label' => __('Contatti', 'woocommerce') ) );
and then at row 681
update_post_meta( $post_id, 'orario', stripslashes( $_POST['orario'] ) );
update_post_meta( $post_id, 'luogo_evento', stripslashes( $_POST['luogo_evento'] ) );
update_post_meta( $post_id, 'indirizzo', stripslashes( $_POST['indirizzo'] ) );
update_post_meta( $post_id, 'zona', stripslashes( $_POST['zona'] ) );
update_post_meta( $post_id, 'contatti', stripslashes( $_POST['contatti'] ) );
It save the data I insert in the product page.
I can I print it out in the single-product.php?

You would do the following:
echo get_post_meta(get_the_ID(), 'orario', true );
echo get_post_meta(get_the_ID(), 'luogo_evento', true );
echo get_post_meta(get_the_ID(), 'indirizzo', true );
echo get_post_meta(get_the_ID(), 'zona', true );
echo get_post_meta(get_the_ID(), 'contatti', true );
I hope this helps!

Related

Woocommerce custom_fields(Shipping and Billing) in email_order_meta_fields

I'm trying to store custom shipping and billing fields in order and then to be print in emails ( admin & customer ) but with no success , is there anyone with big heart to help me ?
So as you can see i removed some fields , added other fields in Shipping & Billing then i try to store data of order and at the last i try to send my extra fields in order_email .
Here is my code in functions.php
// Replace billing_email with shipping_email " This because custome don recieve email notification if don't ask invoice "
add_action('woocommerce_checkout_update_order_meta', 'set_billing_email_from_shipping_email', 50, 2 );
function set_billing_email_from_shipping_email( $order_id, $data ) {
// Get customer shipping email
$email = get_post_meta( $order_id, '_shipping_email', true );
// Set billing email from shipping email
update_post_meta( $order_id, '_billing_email', $email );
}
// Remove fields
add_filter( 'woocommerce_checkout_fields', 'wc_remove_checkout_fields' );
function wc_remove_checkout_fields( $fields ) {
// Billing fields
unset( $fields['billing']['billing_first_name'] );
unset( $fields['billing']['billing_last_name'] );
unset( $fields['billing']['billing_address_2'] );
// Shipping fields
unset( $fields['shipping']['shipping_address_2'] );
unset( $fields['shipping']['shipping_company'] );
// Order fields
unset( $fields['order']['order_comments'] );
return $fields;
}
//Add custom fields
add_filter( 'woocommerce_shipping_fields' , 'custom_shipping_fields' );
function custom_shipping_fields( $fields ) {
$fields['shipping_email'] = array(
'label' => __( 'Email', 'woocommerce' ),
'required' =>true,
'class' => array( 'form-row-last' ),
'validate' => array( 'email' ),
);
$fields['shipping_phone'] = array(
'label' => __( 'Telefono', 'woocommerce' ),
'required' => true,
'class' => array( 'form-row-first' ),
'clear' => true,
'validate' => array( 'phone' ),
);
$fields['shipping_invoice'] =array(
'type' => 'checkbox',
'class' => array('form-row-four'),
'label' => __(' Fattura ?'),
'label_class' => array('woocommerce-form__label l_checkbox'),
'input_class' => array('woocommerce-form__input woocommerce-form__input-checkbox i_checkbox'),
);
return $fields;
}
add_filter( 'woocommerce_billing_fields' , 'custom_billing_fields' );
function custom_billing_fields( $fields ) {
$fields['billing_vat'] = array(
'label' => __( 'P.Iva/CF', 'woocommerce' ),
'required' =>false,
'class' => array( 'form-row-last' ),
);
return $fields;
};
function custom_shipping_save_extra_checkout_fields( $order_id, $posted ){
if( isset( $posted['custom_shipping_fields'] ) ) {
update_post_meta( $order_id, '_custom_shipping_fields', sanitize_text_field( $posted['_custom_shipping_fields'] ) );
}
}
function custom_billing_save_extra_checkout_fields( $order_id, $posted ){
if( isset( $posted['custom_shipping_fields'] ) ) {
update_post_meta( $order_id, '_custom_shipping_fields', sanitize_text_field( $posted['_custom_shipping_fields'] ) );
}
}
add_action( 'woocommerce_checkout_update_order_meta', 'custom_save_extra_checkout_fields', 10, 2 );
function custom_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['custom_shipping_fields'] = array(
'label' => __( 'Custom Siping Fields' ),
'value' => get_post_meta( $order->id, '_custom_shipping_fields', true ),
);
return $fields;
}
add_filter('woocommerce_email_order_meta_fields', 'custom_email_order_meta_fields', 10, 3 );
Thank you!

Custom Checkout Field for Woocommerce with dynamic options

I want to have dynamic options for my checkout dropdown field. The options must be users of specific roles that are in WordPress users. How can I achieve it? Below is the code that I am working with. In the first function, we can get all administrator users. I want users to be in options of the dropdown in the select field of checkout.
**User Roles**
function get_users_by_role($role, $orderby, $order) {
$args = array(
'role' => 'administrator',
'orderby' => 'user_nicename',
'order' => 'ASC'
);
$users = get_users( $args );
return $users;
}
**Dropdown Field**
function everest_custom_dropdown_fields( $fields ) {
$fields['everestmerchant_extra_dropdown_fields']['dropdown'] = array(
'label' => __('Leader Name', 'woocommerce'),
'placeholder' => _x('Leader Name', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array( 'wps-drop' ),
'clear' => true,
'type' => 'select',
'options' => array(
'option 1' => __('option 1', 'woocommerce' ),
'option 2' => __('option 2', 'woocommerce'
)//end of options
);
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'everest_custom_dropdown_fields' );
Get All Leaders
function get_leaders($role) {
$args = array(
'role' => $role,
'orderby' => 'user_nicename',
'order' => 'ASC'
);
$leaders = ['' => 'Please Select'];
$users = get_users( $args );
if($users){
foreach($users as $user){
$leaders[$user->data->ID] = $user->data->display_name;
}
}
return $leaders;
}
Add Leader field in checkout page
function leader_name_select_field( $checkout ){
woocommerce_form_field( 'leader_name', array(
'type' => 'select',
'required' => true,
'class' => array('form-row-wide'),
'label' => 'Leader Name',
'options' => get_leaders('administrator')
), $checkout->get_value( 'leader_name' ) );
}
add_action( 'woocommerce_after_checkout_billing_form', 'leader_name_select_field' );
Save Selected field in database.
function save_leader_name_of_order( $order_id ){
if( !empty( $_POST['leader_name'] ) )
update_post_meta( $order_id, 'leader_name', sanitize_text_field( $_POST['leader_name'] ) );
}
add_action( 'woocommerce_checkout_update_order_meta', 'save_leader_name_of_order' );
Show saved field in order page in dashboard
function leader_name_show_on_order_detail_page($order){
$leader_id = get_post_meta($order->get_id(), 'leader_name', true );
$leader = get_user_by( 'ID', $leader_id );
if($leader_id && $leader){
echo '<p class="form-field form-field-wide">';
echo '<label>Leader Name</label>';
echo '<p> ' . $leader->data->display_name . '</p>';
echo '</p>';
}
}
add_action( 'woocommerce_admin_order_data_after_order_details', 'leader_name_show_on_order_detail_page', 10, 1 );

How to add woocommerce-pagination and woocommerce-ordering dropdown to custom shortcode

I've created a custom shortcode to display products with a minimum stock amount and would like to add pagination to the results as well as calling the woocommerce-ordering dropdown to be displayed on the page.
Here's the shortcode:
// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );
function minimum_stock_shortcode( $atts ) {
global $woocommerce_loop;
// Attributes
$atts = shortcode_atts(
array(
'limit' => '40',
'columns' => '5',
'orderby' => 'title',
'order' => 'asc',
'category' => '',
'cat_operator' => 'IN',
'stock' => '',
),
$atts, 'minimum_stock'
);
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['limit'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'meta_query' => array(
array(
'key' => '_stock',
'value' => $atts['stock'],
'compare' => '>='
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
)
)
);
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $atts['columns'];
if ( $products->have_posts() ) : ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php woocommerce_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
wp_reset_postdata();
return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
Any help would be very much appreciated!
Kind regards,
JP
Okay, so I've got pagination working and tidied things up a bit (it was throwing some errors in the debug log), the code now looks like this:
// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );
function minimum_stock_shortcode( $atts ) {
global $product, $woocommerce, $woocommerce_loop;
// Attributes
$atts = shortcode_atts(
array(
'limit' => '40',
'columns' => '5',
'orderby' => 'title',
'order' => 'asc',
'category' => '',
'cat_operator' => 'IN',
'stock' => '',
),
$atts, 'minimum_stock'
);
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['limit'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'paged' => $paged,
'meta_query' => array(
array(
'key' => '_stock',
'value' => $atts['stock'],
'compare' => '>='
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
)
)
);
if ( isset( $ordering_args['meta_key'] ) ) {
$args['meta_key'] = $ordering_args['meta_key'];
}
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $atts['columns'];
if ( $products->have_posts() ) : ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
if($products->max_num_pages>1){
?>
<nav class="woocommerce-pagination">
<?php echo paginate_links( apply_filters(
'woocommerce_pagination_args', array(
'base' => esc_url( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) ),
'format' => '',
'current' => max( 1, get_query_var( 'paged' ) ),
'total' => $products->max_num_pages,
'prev_text' => '←',
'next_text' => '→',
'type' => 'list',
'end_size' => 3,
'mid_size' => 3
)
)
);
?>
</nav>
<?php }
woocommerce_reset_loop();
wp_reset_postdata();
$return = '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
// Remove ordering query arguments
WC()->query->remove_ordering_args();
return $return;
}
Does anyone know how I can now call the woocommerce-ordering dropdown?
I've tried adding:
<?php do_action( 'woocommerce_before_shop_loop' ); ?>
But this doesn't seem to work, when I check the page it does have the 'woocommerce-notices-wrapper' but there's no sign of the 'woocommerce_catalog_ordering' that I thought should also be called with 'woocommerce_before_shop_loop'.
Any and all help will be very much appreciated :)
Update:
I found this question Adding 'sort by' drop down on custom page using woocommerce short code which gave me the answer I needed to add the woocommerce-ordering dropdown.
Here's my updated code:
// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );
function minimum_stock_shortcode( $atts ) {
global $woocommerce_loop;
// Attributes
$atts = shortcode_atts(
array(
'limit' => '40',
'columns' => '5',
'orderby' => 'date',
'order' => 'desc',
'category' => '',
'cat_operator' => 'IN',
'stock' => '',
), $atts );
if ( ! $atts['category'] ) {
return '';
}
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
// Default ordering args
$ordering_args = WC()->query->get_catalog_ordering_args( $atts['orderby'],
$atts['order'] );
$orderby = 'date';
$order = 'desc';
if ( isset( $_GET['orderby'] ) ) {
$getorderby = $_GET['orderby'];
}
if ($getorderby == 'date') {
$orderby = 'date';
$order = 'desc';
} elseif ($getorderby == 'sku_desc') {
$orderby = 'meta_value';
$order = 'desc';
$meta_key = '_sku';
} elseif ($getorderby == 'sku_asc') {
$orderby = 'meta_value';
$order = 'asc';
$meta_key = '_sku';
}
$args = array(
'post_type' => array( 'product', 'product_variation' ),
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['limit'],
'orderby' => $orderby, // $ordering_args['orderby'],
'order' => $order, // $ordering_args['order'],
'paged' => $paged,
'meta_query' => array(
array(
'key' => '_stock',
'value' => $atts['stock'],
'compare' => '>='
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
)
)
);
if ( isset( $ordering_args['meta_key'] ) ) {
$args['meta_key'] = $ordering_args['meta_key'];
}
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $atts['columns'];
if ( $products->have_posts() ) : ?>
<div style="width:100%;">
<div style="float:right">
<form class="woocommerce-ordering" method="get">
<select name="orderby" class="orderby">
<?php
$catalog_orderby = apply_filters( 'woocommerce_catalog_orderby', array(
'date' => __( 'Sort by latest', 'woocommerce' ),
'sku_asc' => __( 'A-Z / Low to High Numbers', 'woocommerce' ),
'sku_desc' => __( 'Z-A / High to Low Numbers', 'woocommerce' )
) );
foreach ( $catalog_orderby as $id => $name )
echo '<option value="' . esc_attr( $id ) . '" ' . selected( $getorderby, $id, false ) . '>' . esc_attr( $name ) . '</option>';
?>
</select>
<?php
// Keep query string vars intact
foreach ( $_GET as $key => $val ) {
if ( 'orderby' === $key || 'submit' === $key )
continue;
if ( is_array( $val ) ) {
foreach( $val as $innerVal ) {
echo '<input type="hidden" name="' . esc_attr( $key ) . '[]" value="' . esc_attr( $innerVal ) . '" />';
}
} else {
echo '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $val ) . '" />';
}
}
?>
</form>
</div>
</div>
<div style="clear:both;"></div>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
if($products->max_num_pages>1){
?>
<nav class="woocommerce-pagination">
<?php echo paginate_links( apply_filters(
'woocommerce_pagination_args', array(
'base' => esc_url( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) ),
'format' => '',
'current' => max( 1, get_query_var( 'paged' ) ),
'total' => $products->max_num_pages,
'prev_text' => '←',
'next_text' => '→',
'type' => 'list',
'end_size' => 3,
'mid_size' => 3
)
)
);
?>
</nav>
<?php }
woocommerce_reset_loop();
wp_reset_postdata();
$return = '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
// Remove ordering query arguments
WC()->query->remove_ordering_args();
return $return;
}
I hope someone might find this helpful :)
Kind regards,
JP

Woocommerce Product Type Shortcode

What is the syntax to filter products by their type in woocommerce shortcodes? I tried the following unsuccessfully.
[products product_type="simple" per_page="12" columns="3"]
and
[products type="simple" per_page="12" columns="3"]
//products by type shortcode
function products_by_type($atts) {
$atts = shortcode_atts( array(
'columns' => '4',
'orderby' => 'title',
'order' => 'asc',
'ids' => '',
'skus' => '',
'product_type' => 'simple'
), $atts );
$query_args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'posts_per_page' => -1,
'meta_query' => WC()->query->get_meta_query(),
'tax_query' => array(
array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => $atts['product_type'],
),
),
);
if ( ! empty( $atts['skus'] ) ) {
$query_args['meta_query'][] = array(
'key' => '_sku',
'value' => array_map( 'trim', explode( ',', $atts['skus'] ) ),
'compare' => 'IN'
);
}
if ( ! empty( $atts['ids'] ) ) {
$query_args['post__in'] = array_map( 'trim', explode( ',', $atts['ids'] ) );
}
return product_loop( $query_args, $atts, 'products' );
}
function product_loop( $query_args, $atts, $loop_name ) {
global $woocommerce_loop;
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $query_args, $atts, $loop_name ) );
$columns = absint( $atts['columns'] );
$woocommerce_loop['columns'] = $columns;
ob_start();
if ( $products->have_posts() ) {
do_action( "woocommerce_shortcode_before_{$loop_name}_loop" );
woocommerce_product_loop_start();
while ( $products->have_posts() ) {
$products->the_post();
wc_get_template_part( 'content', 'product' );
}
woocommerce_product_loop_end();
do_action( "woocommerce_shortcode_after_{$loop_name}_loop" );
}
woocommerce_reset_loop();
wp_reset_postdata();
return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
}
add_shortcode( apply_filters( "products_by_type_shortcode_tag", "products_by_type" ), "products_by_type" );

Wordpress - Is it possible to add multiple text fields in one row with CMB2?

Using CMB2 we are able to create metaboxes for various post types. Right now, by default, every added custom field will be separated with new row.
For a better usability I would need to add some text fields next to each other, like on the image bellow:
Is that even possible with CMB2?
Code Im using right now is:
$cmb->add_field( array(
'name' => 'Test Text Medium',
'desc' => 'Street',
'default' => '',
'id' => 'street',
'type' => 'text_medium',
) );
In this case cmb has the great feature for creating custom field type.
Hope this link will help you https://github.com/WebDevStudios/CMB2/wiki/Adding-your-own-field-types#use-the-field-in-your-template
you can use multiple fields inside a custom field
Here is the simple code for creating custom field with multiple fields
function cmb2_render_address_field_callback( $field, $value, $object_id, $object_type, $field_type ) {
$value = wp_parse_args( $value, array(
'street1' => '',
'street2' => '',
'street3' => ''
) );
?>
<div class="alignleft"><p><label for="<?php echo $field_type->_id( '_street1' ); ?>">Street</label></p>
<?php echo $field_type->input( array(
'class' => 'cmb_text_small',
'name' => $field_type->_name( '[street1]' ),
'id' => $field_type->_id( '_street1' ),
'type' => 'street1',
'value' => $value['street1'],
) ); ?>
</div>
<div class="alignleft"><p><label for="<?php echo $field_type->_id( '_street2' ); ?>'">Street</label></p>
<?php echo $field_type->input( array(
'class' => 'cmb_text_small',
'name' => $field_type->_name( '[street2]' ),
'id' => 'street2',
'type' => 'text',
'value' => $value['street2'],
) ); ?>
</div>
<div class="alignleft"><p><label for="<?php echo $field_type->_id( '_street3' ); ?>'">Street</label></p>
<?php echo $field_type->input( array(
'class' => 'cmb_text_small',
'name' => $field_type->_name( '[street3]' ),
'id' => $field_type->_id( '_street3' ),
'type' => 'time',
'value' => $value['street3'],
) ); ?>
</div>
<?php
echo $field_type->_desc( true );
}
add_filter( 'cmb2_render_address', 'cmb2_render_address_field_callback', 10, 5 );
Create your own field type as follows
function cmb2_get_state_options( $value = false ) {
$state_list = array( 'AL'=>'Alabama','AK'=>'Alaska','AZ'=>'Arizona','AR'=>'Arkansas','CA'=>'California','CO'=>'Colorado','CT'=>'Connecticut','DE'=>'Delaware','DC'=>'District Of Columbia','FL'=>'Florida','GA'=>'Georgia','HI'=>'Hawaii','ID'=>'Idaho','IL'=>'Illinois','IN'=>'Indiana','IA'=>'Iowa','KS'=>'Kansas','KY'=>'Kentucky','LA'=>'Louisiana','ME'=>'Maine','MD'=>'Maryland','MA'=>'Massachusetts','MI'=>'Michigan','MN'=>'Minnesota','MS'=>'Mississippi','MO'=>'Missouri','MT'=>'Montana','NE'=>'Nebraska','NV'=>'Nevada','NH'=>'New Hampshire','NJ'=>'New Jersey','NM'=>'New Mexico','NY'=>'New York','NC'=>'North Carolina','ND'=>'North Dakota','OH'=>'Ohio','OK'=>'Oklahoma','OR'=>'Oregon','PA'=>'Pennsylvania','RI'=>'Rhode Island','SC'=>'South Carolina','SD'=>'South Dakota','TN'=>'Tennessee','TX'=>'Texas','UT'=>'Utah','VT'=>'Vermont','VA'=>'Virginia','WA'=>'Washington','WV'=>'West Virginia','WI'=>'Wisconsin','WY'=>'Wyoming' );
$state_options = '';
foreach ( $state_list as $abrev => $state ) {
$state_options .= '<option value="'. $abrev .'" '. selected( $value, $abrev, false ) .'>'. $state .'</option>';
}
return $state_options;
}
function cmb2_render_address_field_callback( $field, $value, $object_id, $object_type, $field_type ) {
// make sure we specify each part of the value we need.
$value = wp_parse_args( $value, array(
'address-1' => '',
'address-2' => '',
'city' => '',
'state' => '',
'zip' => '',
) );
?>
<div><p><label for="<?php echo $field_type->_id( '_address_1' ); ?>">Address 1</label></p>
<?php echo $field_type->input( array(
'name' => $field_type->_name( '[address-1]' ),
'id' => $field_type->_id( '_address_1' ),
'value' => $value['address-1'],
'desc' => '',
) ); ?>
</div>
<div><p><label for="<?php echo $field_type->_id( '_address_2' ); ?>'">Address 2</label></p>
<?php echo $field_type->input( array(
'name' => $field_type->_name( '[address-2]' ),
'id' => $field_type->_id( '_address_2' ),
'value' => $value['address-2'],
'desc' => '',
) ); ?>
</div>
<div class="alignleft"><p><label for="<?php echo $field_type->_id( '_city' ); ?>'">City</label></p>
<?php echo $field_type->input( array(
'class' => 'cmb_text_small',
'name' => $field_type->_name( '[city]' ),
'id' => $field_type->_id( '_city' ),
'value' => $value['city'],
'desc' => '',
) ); ?>
</div>
<div class="alignleft"><p><label for="<?php echo $field_type->_id( '_state' ); ?>'">State</label></p>
<?php echo $field_type->select( array(
'name' => $field_type->_name( '[state]' ),
'id' => $field_type->_id( '_state' ),
'options' => cmb2_get_state_options( $value['state'] ),
'desc' => '',
) ); ?>
</div>
<div class="alignleft"><p><label for="<?php echo $field_type->_id( '_zip' ); ?>'">Zip</label></p>
<?php echo $field_type->input( array(
'class' => 'cmb_text_small',
'name' => $field_type->_name( '[zip]' ),
'id' => $field_type->_id( '_zip' ),
'value' => $value['zip'],
'type' => 'number',
'desc' => '',
) ); ?>
</div>
<br class="clear">
<?php
echo $field_type->_desc( true );
}
add_filter( 'cmb2_render_address', 'cmb2_render_address_field_callback', 10, 5 );
To register a new type use below code
...
'fields' => array(
array(
'name' => 'Address',
'desc' => 'Custom Address Field',
'id' => '_cmb2_person_address',
'type' => 'address',
),
),
...
and for displaying we can use as follows
$post_id = get_the_ID();
$address = get_post_meta( $post_id, '_cmb2_person_address', 1 );
// Set default values for each address key
$address = wp_parse_args( $address, array(
'address-1' => '',
'address-2' => '',
'city' => '',
'state' => '',
'zip' => '',
) );
?>
<p><strong>Address:</strong> <?php echo esc_html( $address['address-1'] ); ?></p>
<?php if ( $address['address-2'] ) : ?>
<p><strong>Address 2:</strong> <?php echo esc_html( $address['address-2'] ); ?></p>
<?php endif; ?>
<p><strong>City:</strong> <?php echo esc_html( $address['city'] ); ?></p>
<p><strong>State:</strong> <?php echo esc_html( $address['state'] ); ?></p>
<p><strong>Zip:</strong> <?php echo esc_html( $address['zip'] ); ?></p>
For more details check CMB2 Docs

Resources