Piping CMB2

Piping meta box field content in CMB2.

The idea

This experiment of mine falls directly into the “probably useless” bucket but still poses some challenges I’m willing to dedicate myself to as recreational coding time.
This disclaimer made the idea would be to streamline the use of the Custom Meta Boxes 2 plugin to fill post properties (columns in the database).

By defaults Custom Meta Boxes 2 will take care of saving any value to a a custom post field (a meta data) and that is fine 99% of the times.
I’ve found myself needing to save the content of a text field not as a post custom field but as the post title (literally the post_title field in the `posts’ table); thanks to the hooks Custom Meta Boxes 2 offers that’s easily done.
The code below will add the meta boxes to the post edit screen and will take care of saving the content of the text field to the post title read it from that:


add_action( 'cmb2_init', 'post_meta_boxes' );
function post_meta_boxes() {

        $post_meta_box = new_cmb2_box( array(
            'id'           => 'post-metabox',
            'title'        => __( 'A Meta Box', 'cmb2' ),
            'object_types' => array( 'post' )
        ) );

        $post_meta_box->add_field( array(
            'name' => __( 'The post title', 'cmb2' ),
            'id'   => 'title',
            'type' => 'text_small',
        ) );
    }

add_filter( 'cmb2_override_title_meta_save', 'save_the_post_title', 10, 4 );
function save_the_post_title( $override, $args, $field_args, CMB2_Field $field ) {
        remove_filter( 'cmb2_override_title_meta_save', __FUNCTION__ );
        $args       = (object) $args;
        $post_title = $args->value;
        $post_id    = $args->id;
        wp_update_post( array( 'ID' => $post_id, 'post_title' => $post_title ) );
        
        // do override, do not save the meta
        return true;
    }

add_filter( 'cmb2_override_title_meta_value', 'get_the_post_title', 10, 4 );
function get_the_post_title( $override, $object_id, $args, CMB2_Field $field ) {
        return get_the_title( $object_id );
    }

Then it works already

Yes it does. What I’d like to be able to get rid of is the necessity to manually add the two filters above (save_the_post_title and get_the_post_title in the example) for each field that might work in a similar way. The less painful solution I could come up with is to allow the definition of a meta box meta fields to “tell” where and if a meta field value should be “piped” and in which direction.

A possible syntax

Supposing the imaginary plugin in place I’d like to be able to do this

add_action( 'cmb2_init', 'post_meta_boxes' );
function post_meta_boxes() {

        $post_meta_box = new_cmb2_box( array(
            'id'           => 'post-metabox',
            'title'        => __( 'A Meta Box', 'cmb2' ),
            'object_types' => array( 'post' )
        ) );

        $post_meta_box->add_field( array(
            'name' => __( 'The post title', 'cmb2' ),
            'id'   => 'title',
            'type' => 'text_small  post_title',
        ) );
    }

The line 'type' => 'text_small <> post_title' in particular would mean “save the content of this field to the post title and read it from there”; similarly other directions should be possible.

add_action( 'cmb2_init', 'post_meta_boxes' );
function post_meta_boxes() {

        $post_meta_box = new_cmb2_box( array(
            'id'           => 'post-metabox',
            'title'        => __( 'A Meta Box', 'cmb2' ),
            'object_types' => array( 'post' )
        ) );

        $post_meta_box->add_field( array(
            'name' => __( 'The post title I can change and read', 'cmb2' ),
            'id'   => 'writable_title',
            'type' => 'text_small  post_title',
        ) );

        $post_meta_box->add_field( array(
            'name' => __( 'The post content', 'cmb2' ),
            'desc' => __( 'Display only, editing the post content is not possible', 'cmb2'),
            'id'   => 'read_only_content',
            'type' => 'title add_field( array(
            'name' => __( 'The post title I can write', 'cmb2' ),
            'desc' => __('A duplicate meta data will be save for this field, if post title is changed in other way this field will not update.', 'cmb2'),
            'id'   => 'meta_post_title',
            'type' => 'text_small > post_title',
        ) );
    }

2 thoughts on “Piping CMB2

  1. Hi Luca,

    interesting work. I have the following problem:
    I want to show a front-end form using CMB2 but withe data from the existing first_name and last_name field in user profile section.
    Is this possible with your PIPING extension of CMB2?

    Great work so far!

    Thx for any reply…

    1. I’m currently working on it: me too I have an interest in it and I would do it anyway for a sense of completeness.
      Thanks for your appreciation; if you run into bugs now or in the future please open an issue on GitHub: failure is fundamental for progress!

I appreciate your input