From acd6c7a6e7b32e724e2d8c1ce1cdf52aa3851df0 Mon Sep 17 00:00:00 2001 From: Ishita Jagtap <143935560+ishitaj34@users.noreply.github.com> Date: Fri, 16 Oct 2026 18:59:58 +0530 Subject: [PATCH] fix: strip null values from theme.json output --- includes/create-theme/resolver_additions.php | 27 ++++++++++ tests/test-theme-utils.php | 55 ++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/includes/create-theme/resolver_additions.php b/includes/create-theme/resolver_additions.php index 3de2cc25..549d7b87 100644 --- a/includes/create-theme/resolver_additions.php +++ b/includes/create-theme/resolver_additions.php @@ -116,13 +116,40 @@ public static function get_user_data() { : parent::get_user_data(); } + /** + * Recursively remove null values from an array. + * + * The theme.json schema rejects null values and WordPress ignores them. + * Empty arrays and non-null falsy values (false, 0, '') are preserved. + * + * @param mixed $data Data to filter. + * @return mixed Data without null values. + */ + public static function strip_null_values( $data ) { + if ( ! is_array( $data ) ) { + return $data; + } + + $clean = array(); + foreach ( $data as $key => $value ) { + if ( null === $value ) { + continue; + } + $clean[ $key ] = self::strip_null_values( $value ); + } + + return $clean; + } + /** * Stringify the array data. * * $data is an array of data to be converted to a JSON string. + * Null values are stripped since they are invalid in theme.json. * @return string JSON string. */ public static function stringify( $data ) { + $data = self::strip_null_values( $data ); $data = wp_json_encode( $data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); // Convert spaces to tabs return preg_replace( '~(?:^|\G)\h{4}~m', "\t", $data ); diff --git a/tests/test-theme-utils.php b/tests/test-theme-utils.php index 05ab7e7f..31aa69eb 100644 --- a/tests/test-theme-utils.php +++ b/tests/test-theme-utils.php @@ -61,4 +61,59 @@ function oldslug_support() { $this->assertStringContainsString( 'function new_slug_support', $updated_code_string ); $this->assertStringContainsString( "function_exists( 'new_slug_support' )", $updated_code_string ); } + + public function test_stringify_strips_null_values() { + $data = array( + 'version' => 3, + 'styles' => array( + 'blocks' => array( + 'core/quote' => array( + 'border' => array( + 'color' => null, + 'style' => null, + 'width' => null, + 'left' => array( + 'color' => 'currentColor', + 'style' => 'solid', + 'width' => '4px', + ), + ), + ), + ), + ), + ); + + $decoded = json_decode( CBT_Theme_JSON_Resolver::stringify( $data ), true ); + $this->assertSame( + array( + 'left' => array( + 'color' => 'currentColor', + 'style' => 'solid', + 'width' => '4px', + ), + ), + $decoded['styles']['blocks']['core/quote']['border'] + ); + $this->assertStringNotContainsString( 'null', CBT_Theme_JSON_Resolver::stringify( $data ) ); + } + + public function test_strip_null_values_preserves_falsy_values() { + $data = array( + 'custom' => false, + 'zero' => 0, + 'empty' => '', + 'list' => array(), + 'none' => null, + ); + + $this->assertSame( + array( + 'custom' => false, + 'zero' => 0, + 'empty' => '', + 'list' => array(), + ), + CBT_Theme_JSON_Resolver::strip_null_values( $data ) + ); + } }