Support » Plugin: CMB2 » CMB2 Taxonomy Select not saving in database

  • Resolved tomarmstrong

    (@tomarmstrong)


    I am wanting to display a list of downloads from a custom post type through a specific category ID within a template on different pages.

    So far I have created a custom post type, set the fields title and download file(cmb2 metabox). I have created five categories within my ‘forms’ custom post type.

    For the website admin to display certain downloads on specific pages I have created a ‘taxonomy_select’ drop down field using CMB2, this worked fine on the initial build but once the user changes the desired category no posts will then show.

    It seems that the selection of a new category does not create a new table within the database.

    Below is all of the relevant code:

    CMB2 metaboxes.php:

    $meta_boxes[‘service_default_custom_fields’] = array(
    ‘id’ => ‘service_default_custom_fields’,
    ‘title’ => __( ‘Service Custom Fields’, ‘ct’ ),
    ‘object_types’ => array( ‘page’, ), // Post type
    ‘show_on’ => array( ‘key’ => ‘page-template’, ‘value’ => ‘template-service-default.php’ ),
    ‘context’ => ‘normal’,
    ‘priority’ => ‘high’,
    ‘show_names’ => true, // Show field names on the left
    // ‘cmb_styles’ => false, // false to disable the CMB stylesheet
    // ‘closed’ => true, // Keep the metabox closed by default
    ‘fields’ => array(
    array(
    ‘name’ => ‘Downloads Category’,
    ‘desc’ => ‘Select the downloads category.’,
    ‘id’ => $prefix . ‘download_cat’,
    ‘taxonomy’ => ‘form_category’, //Enter Taxonomy Slug
    ‘type’ => ‘taxonomy_select’,
    ),
    ),
    );

    Template file:

    <?php

    $download_category = get_post_meta(get_the_ID(), ‘_ct_download_cat’, true);

    ?>

      <?php
      // the query
      $args = array(
      ‘post_type’ => ‘forms_pt’,
      ‘orderby’=>’title’,
      ‘order’=>’ASC’,
      ‘posts_per_page’ => 7,
      ‘tax_query’ => array(
      array(
      ‘taxonomy’ => ‘form_category’,
      ‘field’ => ‘id’,
      ‘terms’ => $download_category,
      ),
      ),
      );

      $the_query = new WP_Query( $args ); ?>
      <?php if ( $the_query->have_posts() ) : ?>
      <!– pagination here –>
      <!– the loop –>
      <?php while ( $the_query->have_posts() ) : $the_query->the_post();
      $file = get_post_meta(get_the_ID(),’form_download’, true);
      ?>

    • “><?php the_title(); ?>
    • <?php endwhile; ?>
      <!– end of the loop –>
      <!– pagination here –>

      <?php wp_reset_postdata(); ?>
      <?php else : ?>
      <p><?php _e( ‘Sorry, no posts matched your criteria.’ ); ?></p>
      <?php endif; ?>

    • View All Forms

    https://wordpress.org/plugins/cmb2/

Viewing 11 replies - 16 through 26 (of 26 total)
  • Thread Starter tomarmstrong

    (@tomarmstrong)

    Hello Micheal/Justin,

    Thank you for your help and advice with this.

    What may be worth tinkering with, since the taxonomy_* field types already populate for you, would be setting the sanitization_cb parameter so that it does end up saving the chosen slug to post meta, and continue from there. I’m not sure what you mean by this and where to implement this? I’m guessing I need to alter:

    'sanitization_cb' => 'sanitize_text_field'

    but I’m not 100% sure in what way.

    I have tired to use ‘select’ instead of taxonomy_select’ but this is no good as i need the drop down list to be dynamic so for example if the user adds a new category this will appear within the drop down list. I know I’d probably need to write a small function to pull through the categories dynamically then pass it to the add_field method where the option array is but I’ll go on to that if all else fails.

    However, the drop down meta box (taxonomy select) in the page editor does not pull the correct category id from the postmeta table.
    Not quite following here.

    At the moment the front end is working fine, when I select one of the categories within the page editor the categories list appears on the front end.

    If i then change the drop down option within the page editor this will then change the category and list displayed on the front end, that is great but the new selected option does not show on the drop down list, it still appears as the original option before it changes.

    To give you an example, on this page I originally selected the category ‘Short breaks for adults’ I then changed this to ‘Reports’, as you can see from the images below the front end list changed as expected but the drop down box in the back end did not.

    Correct front end list for ‘Reports’ category:
    http://imgur.com/a/p1DJ0

    Incorrect category showing as ‘Short breaks for adults’ this should be showing ‘Reports’:
    http://imgur.com/a/rcYVP

    Here is the list of categories available from the forms custom post type:
    http://imgur.com/a/fgaTD

    Again, thank you for your help and time spent on this issue, I really appreciate it!

    Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    Regarding use of the 'sanitization_cb' field, the value provided is simply the name of a function you want to use. In WordPress Core, there’s a function named "sanitize_text_field()". However, I’m siding with Justin in that it’s best to just not use the "taxonomy_select" field for this, and go with the "select".

    Here’s an example function that would work as is, but can also be customized to fit your need:

    function tomarmstrong_get_all_terms() {
    	$args = array(
    		'taxonomy' => 'form_category',
    		'hide_empty' => false
    	);
    
    	$terms = get_terms( $args );
    
    	foreach( $terms as $term ) {
    		$select_items[ $term->slug ] = $term->name;
    	}
    
    	return $select_items;
    }

    Example using it from previous code provided:

    function ct_register_contact_page_metabox() {
    
    	$prefix = '_ct_contact_';
    
    	$cmb_contact_page = new_cmb2_box( array(
    		'id'           => $prefix . 'metabox',
    		'title'        => __( 'home Page Metabox', 'cmb2' ),
    		'object_types' => array( 'page' ),
    		'context'      => 'normal',
    		'priority'     => 'high',
    		'show_names'   => true,
    		'show_on'      => array( 'key' => 'page-template', 'value' => 'template-service-default.php' ),
    	) );
    
    	$cmb_contact_page->add_field( array(
    		'name'    => __( 'Downloads Categorys', 'cmb2' ),
    		'desc'    => __( 'Select the downloads category.', 'cmb2' ),
    		'id'      => $prefix . 'download_cat',
    		'type'    => 'select',
    		'options' => 'tomarmstrong_get_all_terms',
    	) );
    }
    add_action( 'cmb2_init', 'ct_register_contact_page_metabox' );

    As more form categories get added, the list will update itself dynamically, and save the term slugs to post meta as needed for fetching on the frontend.

    Thread Starter tomarmstrong

    (@tomarmstrong)

    Micheal/Justin,

    Thank you very much for your help on this, after implementing the code supplied…

    function tomarmstrong_get_all_terms() {
    	$args = array(
    		'taxonomy' => 'form_category',
    		'hide_empty' => false
    	);
    
    	$terms = get_terms( $args );
    
    	foreach( $terms as $term ) {
    		$select_items[ $term->slug ] = $term->name;
    	}
    
    	return $select_items;
    }

    and

    $cmb_contact_page->add_field( array(
    		'name'    => __( 'Downloads Categorys', 'cmb2' ),
    		'desc'    => __( 'Select the downloads category.', 'cmb2' ),
    		'id'      => $prefix . 'download_cat',
    		'type'    => 'select',
    		'options' => 'tomarmstrong_get_all_terms',
    	) );

    Everything is now working as expected.

    Outstanding first class support, thanks again for the time spent, speedy replies and of course the amazing plugin!

    Plugin Author Justin Sternberg

    (@jtsternberg)

    The one thing I would change is to change 'options' => 'tomarmstrong_get_all_terms', to 'options_cb' => 'tomarmstrong_get_all_terms',, as using the ‘options’ parameter for a callback will be deprecated in the next few releases.

    Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    I was not personally aware of the eventual deprecation of 'options' so that’s good to know. Justin perhaps we can put a note in the wiki about that detail?

    Wow, awesome. I was having exactly the same issue.

    Now, how do I get the term name instead of the term slug in the frontend?

    I’m getting the term name on my select field in the backend, but it’s showing the term slug in the frontend.

    Thanks.

    Álvaro

    Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    Since the slug is what gets saved in the example above, you may need to either alter the order, or make use of https://developer.wordpress.org/reference/functions/get_term_by/ when at the frontend so that you can get a term object and the name value that way.

    Thank you @tw2113, I wasn’t aware I could do it that way in the above code. So, my function code goes like this:

    function empform_get_all_terms() {
    	$args = array(
    		'taxonomy' => 'courses_place',
    		'hide_empty' => false
    	);
    
    	$terms = get_terms( $args );
    
    	foreach( $terms as $term ) {
    		$select_items[ $term->name ] = $term->name;
    	}
    
    	return $select_items;
    }

    Nice! Thanks.

    Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    Definitely one way to handle that. Only potential caveat, that you may or may not have a problem with, is that capitalized name value will be what’s stored in the db as well. If you end up at a point where you need the slug of the term, you’ll need to use the get_term_by() function pointed out earlier. A bridge to cross at that time though. 🙂

    I am enjoy CMB2, but for work with custom taxonomes i wroute this function,
    it returns array of taxonomes, key – is slug, and item – is title of taxonomy.

    function weblegko_get_array_custom_taxonomies($taxonomy){
    	$args = array(
    		'orderby'=>'asc',
    		'taxonomy' => $taxonomy,
    		'hide_empty'=>true
    	);
    	$term_query = new WP_Term_Query( $args );
    	$t=[];
    
    	$t['all'] = 'All';
    	
    	if (!empty($term_query->terms)) {
    		foreach ($term_query->terms as $term) {
    			$t[$term->slug] = $term->name;
    		}
    		return $t;
    	} else {
    		return false;
    	}
    }

    For example:

    
    $cmb_homepage->add_field( array(
      'name'     => esc_html__( 'Photo category', 'cmb2' ),
      'desc'     => esc_html__( 'Select gallery pluggable to homepage', 'cmb2' ),
      'id'       => $prefix . 'gallery_phototype',
      'type'             => 'select',
      'show_option_none' => true,
      'options'          => weblegko_get_array_custom_taxonomies('phototype'),
    ));
    Plugin Author Justin Sternberg

    (@jtsternberg)

    Hey weblegko, it looks like you’re trying to create an alternative taxonomy term select. To do that, we have a documented solution: https://github.com/WebDevStudios/CMB2/wiki/Tips-&-Tricks#a-dropdown-for-taxonomy-terms-which-does-not-set-the-term-on-the-post

    Note that it’s best to use the options_cb parameter and a callback to return the options. This is so that the term query only happens in-context, when that field needs to display.

Viewing 11 replies - 16 through 26 (of 26 total)
  • The topic ‘CMB2 Taxonomy Select not saving in database’ is closed to new replies.