Recently I have been working on a project where we needed to save CMB2 Colour Picker field as a RGB field. As great as CMB2 is, by default, the field is saved as hexadecimal field (like #FFFFFF
). This makes sense as it is the most common ways to display colours on the internet.
However, should you wish to use the colour for maybe a gradient with an element of transparency, you’ll probably need RGBA values. Luckily, you can modify CMB2 so the RGB value is saved, and saved in an array.
Convert Hex to RGB In PHP
Luckily, converting hexadecimal fields to RGB is quite straightforward. Each 2 numbers are 2 values multiplied together (so FF
is 15 * 15
, which is 225). So we can multiply the first two characters of the hex code, then PHP function hexdec
, to get the decimal value.
That works for 6 character hex codes, but what about 3 character hex codes? Well these are the same number multiplied together, so all we need to do is check if it’s a three or six digit hex code, and act accordingly.
Here’s the function that we are looking to create which converts Hex to RGB.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /** * Change Hex values to RGB * * @link https://www.winwar.co.uk/2016/02/save-cmb2-colour-picker-fields-rgb-values/?utm_source=codesnippet * * @param string $hex the Hex value for a colour. * @return array the RGB value of a colour */ function winwar_hex2rgb( $hex ) { // First of all, remove any # characters. $hex = str_replace( "#", "", $hex ); if( strlen( $hex ) == 3 ) { $r = hexdec( substr( $hex,0,1).substr($hex,0,1)); $g = hexdec(substr($hex,1,1).substr($hex,1,1)); $b = hexdec(substr($hex,2,1).substr($hex,2,1)); } else { $r = hexdec(substr($hex,0,2)); $g = hexdec(substr($hex,2,2)); $b = hexdec(substr($hex,4,2)); } $rgb = array($r, $g, $b); return $rgb; // returns an array with the rgb values } |
Save the RGB Value
Now you need to make sure that the value is saved whenever the post is saved. To the best of my knowledge, there isn’t a CMB2 hook that we can hook into when the post is saved. However, we can use the save_post
hook to save the RGB value.
To do this, simply create a function that finds the hex field, and then saves it as an RGB array
A Word of Warning: This code assumes that the CMB2 nonce is called cmb2_nonce
and the hex field is called cmb2_color_hex
. Please check these before you use them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /** * Sees if the post submits a hex value, if so, save a RGB value. * * @link https://www.winwar.co.uk/2016/02/save-cmb2-colour-picker-fields-rgb-values/?utm_source=codesnippet * * @param integer $post_id the ID of the post just saved * @param object $post the object of the post just saved * @return void */ function winwar_save_hex_value( $post_id, $post ) { /* Verify the nonce before proceeding. */ if ( !isset( $_POST['cmb2_nonce'] ) || !wp_verify_nonce( $_POST['cmb2_nonce'], basename( __FILE__ ) ) ) return $post_id; /* Get the post type object. */ $post_type = get_post_type_object( $post->post_type ); /* Check if the current user has permission to edit the post. */ if ( !current_user_can( $post_type->cap->edit_post, $post_id ) ) return $post_id; /* Check if the hex value has been saved. If so, escape it to make it safe. */ $hex_value = ( isset( $_POST['cmb2_color_hex'] ) ? esc_attr( $_POST['cmb2_color_hex'] ) : '' ); /* If the hex value is present, attempt RGB conversion. If not, save a blank array */ $rgbarray = ( !empty( $hex_value ) ) ? $rgbarray = winwar_hex2rgb( $hex ) : array(); update_meta_value( $post_id, 'cmb2_color_rgb', $rgbarray ); } add_action( 'save_post', 'winwar_save_hex_value', 10, 2 ); |
Modified from How To Create Custom Meta Boxes in WordPress.
To Use
The above saves the array as a custom field. To use, simply call the cmb2_color_rgb
as you normally would:-
1 2 3 4 5 | $rgbarray = get_post_meta( get_the_ID(), 'cmb2_color_rgb', $rgbarray ); //$rgbarray[0] = Red Value //$rgbarray[1] = Green Value //$rgbarray[2] = Blue Value echo $rgbarray[0]; |
I hope you find this code useful. I’m convinced there’s a better way of doing it, so I’d like to hear it if you do have a better way of doing it!
Update
Thanks to Webucator for producing a short video on this blog post. Nice touch! You can see it below.
Comments
Polite Disclaimer: I am welcome, open and willing for corrections to be shared in the comments (with corrections being added to posts and credited), and the comments field should be used to promote discussion and make this post better. I do not know everything and if anybody finds a better way to do something, then by all means please share it below.
However, I'm unable to offer support to posts. The reason being is that WordPress has tens of thousands of plugins and millions of themes. As such, finding out exactly why code doesn't work with your setup is a long process. If you wish for me to look at your code, please use the priority support area.
Comments asking support will be left on the site, but there is no guarantee of answer.
Comments are closed.