diff --git a/admin/resolver_additions.php b/admin/resolver_additions.php
index 8d8a6343..3da26fc2 100644
--- a/admin/resolver_additions.php
+++ b/admin/resolver_additions.php
@@ -95,7 +95,6 @@ public static function export_theme_data( $content, $extra_theme_data = null ) {
$data['$schema'] = $schema;
$theme_json = wp_json_encode( $data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
return preg_replace( '~(?:^|\G)\h{4}~m', "\t", $theme_json );
-
}
public static function get_theme_file_contents() {
@@ -128,7 +127,6 @@ public static function clean_cached_data() {
// Does this clear the Gutenberg equivalent?
static::$theme_json_file_cache = array();
}
-
}
}
diff --git a/includes/class-create-block-theme-api.php b/includes/class-create-block-theme-api.php
index 0ed2e4a5..807f24d7 100644
--- a/includes/class-create-block-theme-api.php
+++ b/includes/class-create-block-theme-api.php
@@ -97,6 +97,37 @@ public function register_rest_routes() {
},
)
);
+ register_rest_route(
+ 'create-block-theme/v1',
+ '/get-theme-data',
+ array(
+ 'methods' => 'GET',
+ 'callback' => array( $this, 'rest_get_theme_data' ),
+ 'permission_callback' => function () {
+ return current_user_can( 'edit_theme_options' );
+ },
+ ),
+ );
+ }
+
+ function rest_get_theme_data( $request ) {
+ try {
+ $theme_data = MY_Theme_JSON_Resolver::get_theme_file_contents();
+ return new WP_REST_Response(
+ array(
+ 'status' => 'SUCCESS',
+ 'message' => __( 'Theme data retrieved.', 'create-block-theme' ),
+ 'data' => $theme_data,
+ ),
+ );
+ } catch ( Exception $error ) {
+ return new WP_REST_Response(
+ array(
+ 'status' => 'FAILURE',
+ 'message' => $error->getMessage(),
+ )
+ );
+ }
}
function rest_get_readme_data( $request ) {
diff --git a/package-lock.json b/package-lock.json
index 58534f20..86f37743 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,8 @@
"version": "1.13.8",
"license": "GPL-2.0-or-later",
"dependencies": {
+ "@codemirror/lang-json": "^6.0.1",
+ "@uiw/react-codemirror": "^4.21.24",
"@wordpress/icons": "^9.24.0",
"lib-font": "^2.4.0"
},
@@ -2256,6 +2258,102 @@
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true
},
+ "node_modules/@codemirror/autocomplete": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.14.0.tgz",
+ "integrity": "sha512-Kx9BCSOLKmqNXEvmViuzsBQJ2VEa/wWwOATNpixOa+suttTV3rDnAUtAIt5ObAUFjXvZakWfFfF/EbxELnGLzQ==",
+ "dependencies": {
+ "@codemirror/language": "^6.0.0",
+ "@codemirror/state": "^6.0.0",
+ "@codemirror/view": "^6.17.0",
+ "@lezer/common": "^1.0.0"
+ },
+ "peerDependencies": {
+ "@codemirror/language": "^6.0.0",
+ "@codemirror/state": "^6.0.0",
+ "@codemirror/view": "^6.0.0",
+ "@lezer/common": "^1.0.0"
+ }
+ },
+ "node_modules/@codemirror/commands": {
+ "version": "6.3.3",
+ "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.3.tgz",
+ "integrity": "sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A==",
+ "dependencies": {
+ "@codemirror/language": "^6.0.0",
+ "@codemirror/state": "^6.4.0",
+ "@codemirror/view": "^6.0.0",
+ "@lezer/common": "^1.1.0"
+ }
+ },
+ "node_modules/@codemirror/lang-json": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz",
+ "integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==",
+ "dependencies": {
+ "@codemirror/language": "^6.0.0",
+ "@lezer/json": "^1.0.0"
+ }
+ },
+ "node_modules/@codemirror/language": {
+ "version": "6.10.1",
+ "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.1.tgz",
+ "integrity": "sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==",
+ "dependencies": {
+ "@codemirror/state": "^6.0.0",
+ "@codemirror/view": "^6.23.0",
+ "@lezer/common": "^1.1.0",
+ "@lezer/highlight": "^1.0.0",
+ "@lezer/lr": "^1.0.0",
+ "style-mod": "^4.0.0"
+ }
+ },
+ "node_modules/@codemirror/lint": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.5.0.tgz",
+ "integrity": "sha512-+5YyicIaaAZKU8K43IQi8TBy6mF6giGeWAH7N96Z5LC30Wm5JMjqxOYIE9mxwMG1NbhT2mA3l9hA4uuKUM3E5g==",
+ "dependencies": {
+ "@codemirror/state": "^6.0.0",
+ "@codemirror/view": "^6.0.0",
+ "crelt": "^1.0.5"
+ }
+ },
+ "node_modules/@codemirror/search": {
+ "version": "6.5.6",
+ "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz",
+ "integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==",
+ "dependencies": {
+ "@codemirror/state": "^6.0.0",
+ "@codemirror/view": "^6.0.0",
+ "crelt": "^1.0.5"
+ }
+ },
+ "node_modules/@codemirror/state": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
+ "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
+ },
+ "node_modules/@codemirror/theme-one-dark": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz",
+ "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==",
+ "dependencies": {
+ "@codemirror/language": "^6.0.0",
+ "@codemirror/state": "^6.0.0",
+ "@codemirror/view": "^6.0.0",
+ "@lezer/highlight": "^1.0.0"
+ }
+ },
+ "node_modules/@codemirror/view": {
+ "version": "6.25.1",
+ "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.25.1.tgz",
+ "integrity": "sha512-2LXLxsQnHDdfGzDvjzAwZh2ZviNJm7im6tGpa0IONIDnFd8RZ80D2SNi8PDi6YjKcMoMRK20v6OmKIdsrwsyoQ==",
+ "dependencies": {
+ "@codemirror/state": "^6.4.0",
+ "style-mod": "^4.1.0",
+ "w3c-keyname": "^2.2.4"
+ }
+ },
"node_modules/@csstools/selector-specificity": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz",
@@ -3013,6 +3111,37 @@
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
"dev": true
},
+ "node_modules/@lezer/common": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
+ "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
+ },
+ "node_modules/@lezer/highlight": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
+ "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
+ "dependencies": {
+ "@lezer/common": "^1.0.0"
+ }
+ },
+ "node_modules/@lezer/json": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.2.tgz",
+ "integrity": "sha512-xHT2P4S5eeCYECyKNPhr4cbEL9tc8w83SPwRC373o9uEdrvGKTZoJVAGxpOsZckMlEh9W23Pc72ew918RWQOBQ==",
+ "dependencies": {
+ "@lezer/common": "^1.2.0",
+ "@lezer/highlight": "^1.0.0",
+ "@lezer/lr": "^1.0.0"
+ }
+ },
+ "node_modules/@lezer/lr": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.0.tgz",
+ "integrity": "sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg==",
+ "dependencies": {
+ "@lezer/common": "^1.0.0"
+ }
+ },
"node_modules/@nicolo-ribaudo/eslint-scope-5-internals": {
"version": "5.1.1-v1",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
@@ -4773,6 +4902,57 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@uiw/codemirror-extensions-basic-setup": {
+ "version": "4.21.24",
+ "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.21.24.tgz",
+ "integrity": "sha512-TJYKlPxNAVJNclW1EGumhC7I02jpdMgBon4jZvb5Aju9+tUzS44IwORxUx8BD8ZtH2UHmYS+04rE3kLk/BtnCQ==",
+ "dependencies": {
+ "@codemirror/autocomplete": "^6.0.0",
+ "@codemirror/commands": "^6.0.0",
+ "@codemirror/language": "^6.0.0",
+ "@codemirror/lint": "^6.0.0",
+ "@codemirror/search": "^6.0.0",
+ "@codemirror/state": "^6.0.0",
+ "@codemirror/view": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://jaywcjlove.github.io/#/sponsor"
+ },
+ "peerDependencies": {
+ "@codemirror/autocomplete": ">=6.0.0",
+ "@codemirror/commands": ">=6.0.0",
+ "@codemirror/language": ">=6.0.0",
+ "@codemirror/lint": ">=6.0.0",
+ "@codemirror/search": ">=6.0.0",
+ "@codemirror/state": ">=6.0.0",
+ "@codemirror/view": ">=6.0.0"
+ }
+ },
+ "node_modules/@uiw/react-codemirror": {
+ "version": "4.21.24",
+ "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.21.24.tgz",
+ "integrity": "sha512-8zs5OuxbhikHocHBsVBMuW1vqlv4ccZAkt4rFwr7ebLP2Q6RwHsjpsR9GeGyAigAqonKRoeHugqF78UMrkaTgg==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.6",
+ "@codemirror/commands": "^6.1.0",
+ "@codemirror/state": "^6.1.1",
+ "@codemirror/theme-one-dark": "^6.0.0",
+ "@uiw/codemirror-extensions-basic-setup": "4.21.24",
+ "codemirror": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://jaywcjlove.github.io/#/sponsor"
+ },
+ "peerDependencies": {
+ "@babel/runtime": ">=7.11.0",
+ "@codemirror/state": ">=6.0.0",
+ "@codemirror/theme-one-dark": ">=6.0.0",
+ "@codemirror/view": ">=6.0.0",
+ "codemirror": ">=6.0.0",
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
"node_modules/@ungap/structured-clone": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
@@ -7183,6 +7363,20 @@
"node": ">= 0.12.0"
}
},
+ "node_modules/codemirror": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
+ "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
+ "dependencies": {
+ "@codemirror/autocomplete": "^6.0.0",
+ "@codemirror/commands": "^6.0.0",
+ "@codemirror/language": "^6.0.0",
+ "@codemirror/lint": "^6.0.0",
+ "@codemirror/search": "^6.0.0",
+ "@codemirror/state": "^6.0.0",
+ "@codemirror/view": "^6.0.0"
+ }
+ },
"node_modules/collect-v8-coverage": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
@@ -7605,6 +7799,11 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
+ "node_modules/crelt": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
+ "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="
+ },
"node_modules/cross-fetch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
@@ -18515,6 +18714,11 @@
"node": ">=0.8.0"
}
},
+ "node_modules/style-mod": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
+ "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="
+ },
"node_modules/style-search": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
@@ -19697,6 +19901,11 @@
"node": ">= 0.8"
}
},
+ "node_modules/w3c-keyname": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
+ "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
+ },
"node_modules/w3c-xmlserializer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
diff --git a/package.json b/package.json
index a2cdf238..0a4a2c84 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,8 @@
},
"main": "build/index.js",
"dependencies": {
+ "@codemirror/lang-json": "^6.0.1",
+ "@uiw/react-codemirror": "^4.21.24",
"@wordpress/icons": "^9.24.0",
"lib-font": "^2.4.0"
},
diff --git a/src/editor-sidebar/json-editor-modal.js b/src/editor-sidebar/json-editor-modal.js
new file mode 100644
index 00000000..1b568195
--- /dev/null
+++ b/src/editor-sidebar/json-editor-modal.js
@@ -0,0 +1,38 @@
+import { useState, useEffect } from '@wordpress/element';
+import { Modal } from '@wordpress/components';
+import { useSelect } from '@wordpress/data';
+import CodeMirror from '@uiw/react-codemirror';
+import { json } from '@codemirror/lang-json';
+import { fetchThemeJson } from '../resolvers';
+
+const ThemeJsonEditorModal = ( { onRequestClose } ) => {
+ const [ themeData, setThemeData ] = useState( '' );
+ const themeName = useSelect( ( select ) =>
+ select( 'core' ).getCurrentTheme()
+ )?.name?.raw;
+ const fetchThemeData = async () => {
+ setThemeData( await fetchThemeJson() );
+ };
+ const handleSave = () => {};
+
+ useEffect( () => {
+ fetchThemeData();
+ } );
+
+ return (
+
+
+
+ );
+};
+
+export default ThemeJsonEditorModal;
diff --git a/src/plugin-sidebar.js b/src/plugin-sidebar.js
index 2898291c..20397f15 100644
--- a/src/plugin-sidebar.js
+++ b/src/plugin-sidebar.js
@@ -1,3 +1,4 @@
+import { useState } from '@wordpress/element';
import { registerPlugin } from '@wordpress/plugins';
import { PluginSidebar, PluginSidebarMoreMenuItem } from '@wordpress/edit-site';
import { __, _x } from '@wordpress/i18n';
@@ -28,6 +29,8 @@ import {
import { UpdateThemePanel } from './editor-sidebar/update-panel';
import { CreateThemePanel } from './editor-sidebar/create-panel';
+import ThemeJsonEditorModal from './editor-sidebar/json-editor-modal';
+
import {
tool,
copy,
@@ -38,6 +41,7 @@ import {
} from '@wordpress/icons';
const CreateBlockThemePlugin = () => {
+ const [ isEditorOpen, setIsEditorOpen ] = useState( false );
const { createErrorNotice } = useDispatch( noticesStore );
const handleSaveClick = () => {
@@ -97,6 +101,7 @@ const CreateBlockThemePlugin = () => {
exportTheme();
};
+
return (
<>
{
'create-block-theme'
) }
+
+
+
+ { __(
+ 'Open the theme.json file to inspect theme data.',
+ 'create-block-theme'
+ ) }
+
@@ -201,6 +222,11 @@ const CreateBlockThemePlugin = () => {
+ { isEditorOpen && (
+ setIsEditorOpen( false ) }
+ />
+ ) }
>
);
};
diff --git a/src/resolvers.js b/src/resolvers.js
new file mode 100644
index 00000000..41308384
--- /dev/null
+++ b/src/resolvers.js
@@ -0,0 +1,27 @@
+import apiFetch from '@wordpress/api-fetch';
+
+export async function fetchThemeJson() {
+ const fetchOptions = {
+ path: '/create-block-theme/v1/get-theme-data',
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ };
+
+ try {
+ const response = await apiFetch( fetchOptions );
+
+ if ( ! response?.data || 'SUCCESS' !== response?.status ) {
+ throw new Error(
+ `Failed to fetch theme data: ${
+ response?.message || response?.status
+ }`
+ );
+ }
+
+ return JSON.stringify( response?.data, null, 2 );
+ } catch ( e ) {
+ // @todo: handle error
+ }
+}