diff --git a/inc/class-shortcode-ui.php b/inc/class-shortcode-ui.php index ef24728c..1a54ce02 100644 --- a/inc/class-shortcode-ui.php +++ b/inc/class-shortcode-ui.php @@ -427,7 +427,7 @@ public function handle_ajax_bulk_do_shortcode() { } /** - * Decode any encoded attributes. + * Decode any encoded attributes, and convert true/false strings to their boolean equivalents. * * @param array $out The output array of shortcode attributes. * @param array $pairs The supported attributes and their defaults. @@ -452,13 +452,34 @@ public function filter_shortcode_atts_decode_encoded( $out, $pairs, $atts ) { $default = isset( $fields[ $attr['type'] ]['encode'] ) ? $fields[ $attr['type'] ]['encode'] : false; $encoded = isset( $attr['encode'] ) ? $attr['encode'] : $default; + $explicitbool = isset( $attr['explicitbool'] ) ? $attr['explicitbool'] : false; + if ( $encoded && isset( $out[ $attr['attr'] ] ) ) { $out[ $attr['attr'] ] = rawurldecode( $out[ $attr['attr'] ] ); } + + if ( $explicitbool && in_array( $out[ $attr['attr'] ], array( 'true', 'false' ), true ) ) { + $out[ $attr['attr'] ] = $this->explicitbool( $out[ $attr['attr'] ] ); + } } return $out; } + /** + * Convert 'true' or 'false' strings to their boolean equivalent. + * + * @param string Expected to be either 'true' or 'false' + * @return bool + */ + private function explicitbool( $bool_string ) { + if ( 'true' === $bool_string ) { + return true; + } + if ( 'false' === $bool_string ) { + return false; + } + return null; + } } diff --git a/js-tests/build/specs.js b/js-tests/build/specs.js index 2852c840..56c6053f 100644 --- a/js-tests/build/specs.js +++ b/js-tests/build/specs.js @@ -833,7 +833,12 @@ Shortcode = Backbone.Model.extend({ this.get( 'attrs' ).each( function( attr ) { - // Skip empty attributes. + // Send 'true' and 'false' as checkbox values if 'explicitbool' option is on + if ( attr.get( 'explicitbool' ) && 'boolean' === typeof attr.get( 'value' ) ) { + attr.set( 'value', attr.get( 'value' ) ? 'true' : 'false' ); + } + + // Otherwise, skip empty or false attributes. if ( ! attr.get( 'value' ) || attr.get( 'value' ).length < 1 ) { return; } diff --git a/js/build/shortcode-ui.js b/js/build/shortcode-ui.js index a3c466f0..001e1811 100644 --- a/js/build/shortcode-ui.js +++ b/js/build/shortcode-ui.js @@ -204,7 +204,12 @@ Shortcode = Backbone.Model.extend({ this.get( 'attrs' ).each( function( attr ) { - // Skip empty attributes. + // Send 'true' and 'false' as checkbox values if 'explicitbool' option is on + if ( attr.get( 'explicitbool' ) && 'boolean' === typeof attr.get( 'value' ) ) { + attr.set( 'value', attr.get( 'value' ) ? 'true' : 'false' ); + } + + // Otherwise, skip empty or false attributes. if ( ! attr.get( 'value' ) || attr.get( 'value' ).length < 1 ) { return; } diff --git a/js/src/models/shortcode.js b/js/src/models/shortcode.js index c32c4aa0..29eb3005 100644 --- a/js/src/models/shortcode.js +++ b/js/src/models/shortcode.js @@ -68,7 +68,12 @@ Shortcode = Backbone.Model.extend({ this.get( 'attrs' ).each( function( attr ) { - // Skip empty attributes. + // Send 'true' and 'false' as checkbox values if 'explicitbool' option is on + if ( attr.get( 'explicitbool' ) && 'boolean' === typeof attr.get( 'value' ) ) { + attr.set( 'value', attr.get( 'value' ) ? 'true' : 'false' ); + } + + // Otherwise, skip empty or false attributes. if ( ! attr.get( 'value' ) || attr.get( 'value' ).length < 1 ) { return; }