Support

Account

Home Forums Backend Issues (wp-admin) Custom field types: saving and loading values

Solved

Custom field types: saving and loading values

  • I’m making a new language selector field type which creates a <select> field from all languages present in a given WPML instance. It’s based on this:

    https://www.advancedcustomfields.com/resources/creating-a-new-field-type/.

    I was able to follow the instructions fairly well: created the field type, populated it with all the language data from WPML, and made the <select> field appear when editing posts. But I can’t save the selected value to the database.

    There’s probably something very basic missing here, but I can’t figure out what it is. Below is what I wrote in the files which in the starter kit is called acf-FIELD_NAME-v5.php. (The part about constructing the array of languages, it works fine. Please just assume that this returns a run-of-the-mill PHP array.)

    
    <?php
    
    if( ! defined( 'ABSPATH' ) ) exit;
    
    if( !class_exists('acf_field_wpml_languages') ) :
    
    class acf_field_wpml_languages extends acf_field {
    
    	function __construct( $settings ) {
    		
    		$this->name = 'wpml_languages';
    		$this->label = __('WPML Languages', 'acf-wpml_languages');
    		$this->category = 'choice';
    		$this->settings = $settings;
    		parent::__construct();
    		
    	}
    	
    	function render_field( $field ) {
    		
    		global $wpdb;
    
    		function get_all_langs_names( $lang, $wpdb ) {
    
    			$lang_data = array();
    
    			$languages = $wpdb -> get_results( 
    
    				$wpdb -> prepare( "
    					SELECT code, english_name, active, tag, name 
    					FROM {$wpdb -> prefix}icl_languages lang 
    					INNER JOIN {$wpdb -> prefix}icl_languages_translations trans 
    					ON lang.code = trans.language_code 
    					AND trans.display_language_code=%s", 
    				$lang )
    
    			);
    
    			foreach( $languages as $l ) {
    
    				$lang_data[$l -> code] = array(
    					'english_name' => $l -> english_name,
    					'active' => $l -> active,
    					'tag' => $l -> tag,
    					'name' => $l -> name,
    				);
    
    			}
    
    			return $lang_data;
    
    		}
    
    		// get language tag of current site locale...
    		$code = ICL_LANGUAGE_CODE;
    
    		$lang_tag = $wpdb -> get_var("
    			SELECT tag 
    			FROM {$wpdb -> prefix}icl_languages 
    			WHERE code='{$code}'"
    		);
    
    		// ... and then get language names associated with that tag
    		$languages = get_all_langs_names( $lang_tag, $wpdb );
    
    		// sort language array alphabetically, or however current language orders words
    		function sort_languages( $a, $b ) {
    
    			return strcmp( $a['name'], $b['name'] );
    
    		}
    
    		usort( $languages, 'sort_languages' );
    
    		?>
    
    		<select>
    
    			<?php
    
    			foreach ($languages as $language) {
    
    				?><option value=<?php echo '"' . $language['tag'] . '"'; ?>><?php echo $language['name']; ?></option><?php
    
    			}
    
    			?>
    
    		</select>
    
    	<?php
    
    	}
    	
    }
    
    new acf_field_wpml_languages( $this->settings );
    
    endif;
    
    ?>
    
  • did you rename the file acf-FIELD_NAME-v5.php to acf-wpml_languages-v5.php ?

  • I did. Was just referring to the original file name so people could identify it.

  • Your select field has no attributes <select>, like the name, id, other important information. Without a proper field name ACF can’t save your field value. You should take a look at some of the build in ACF fields to get examples of what you should use here.

  • It would be something that simple, wouldn’t it! Below is what I ended up using:

    
    $attrs = array(
        'id'      => $field['id'],
        'name'    => $field['name'],
    );
    
    ?>
    
    <select <?php echo implode( ' ', array_map(function($val, $key) { return sprintf( '%1$s="%2$s"', $key, esc_attr($val) ); }, $attrs, array_keys( $attrs ))); ?>>
    
        <?php
    
        foreach ($languages as $language) {
    
            ?><option value=<?php echo '"' . $language['tag'] . '"'; if($language['tag'] == $field['value']): ?> selected="selected"<?php endif; ?>><?php echo $language['name']; ?></option><?php
    
        }
    
        ?>
    
    </select>
    

    Credit to https://github.com/nlemoine/acf-country.

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.