Skip to content

Commit

Permalink
Site Editor: Add theme.json to export file (#39048)
Browse files Browse the repository at this point in the history
* Override REST API route

* Port changes from previous PR

* Add export_theme_json method

* Use new method to get exported data

* Rename export_theme_json to get_data

* Improve nesting

* Update the export label

Co-authored-by: André <[email protected]>
Co-authored-by: Ben Dwyer <[email protected]>
  • Loading branch information
3 people authored Mar 2, 2022
1 parent 3041b45 commit 8fbf70c
Show file tree
Hide file tree
Showing 9 changed files with 302 additions and 74 deletions.
54 changes: 0 additions & 54 deletions lib/compat/wordpress-5.9/block-template-utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -894,57 +894,3 @@ function block_footer_area() {
block_template_part( 'footer' );
}
}

if ( ! function_exists( 'wp_generate_block_templates_export_file' ) ) {
/**
* Creates an export of the current templates and
* template parts from the site editor at the
* specified path in a ZIP file.
*
* @since 5.9.0
*
* @return WP_Error|string Path of the ZIP file or error on failure.
*/
function wp_generate_block_templates_export_file() {
if ( ! class_exists( 'ZipArchive' ) ) {
return new WP_Error( 'missing_zip_package', __( 'Zip Export not supported.', 'gutenberg' ) );
}

$obscura = wp_generate_password( 12, false, false );
$filename = get_temp_dir() . 'edit-site-export-' . $obscura . '.zip';

$zip = new ZipArchive();
if ( true !== $zip->open( $filename, ZipArchive::CREATE ) ) {
return new WP_Error( 'unable_to_create_zip', __( 'Unable to open export file (archive) for writing.', 'gutenberg' ) );
}

$zip->addEmptyDir( 'theme' );
$zip->addEmptyDir( 'theme/templates' );
$zip->addEmptyDir( 'theme/parts' );

// Load templates into the zip file.
$templates = gutenberg_get_block_templates();
foreach ( $templates as $template ) {
$template->content = _remove_theme_attribute_in_block_template_content( $template->content );

$zip->addFromString(
'theme/templates/' . $template->slug . '.html',
$template->content
);
}

// Load template parts into the zip file.
$template_parts = gutenberg_get_block_templates( array(), 'wp_template_part' );
foreach ( $template_parts as $template_part ) {
$zip->addFromString(
'theme/parts/' . $template_part->slug . '.html',
$template_part->content
);
}

// Save changes to the zip file.
$zip->close();

return $filename;
}
}
69 changes: 69 additions & 0 deletions lib/compat/wordpress-6.0/block-template-utils.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
/**
* Temporary compatibility shims for features present in Gutenberg.
* This file should be removed when WordPress 6.0.0 becomes the lowest
* supported version by this plugin.
*
* @package gutenberg
*/

/**
* Creates an export of the current templates and
* template parts from the site editor at the
* specified path in a ZIP file.
*
* @since 5.9.0
* @since 6.0.0 Adds theme.json to the export archive.
*
* @return WP_Error|string Path of the ZIP file or error on failure.
*/
function gutenberg_generate_block_templates_export_file() {
if ( ! class_exists( 'ZipArchive' ) ) {
return new WP_Error( 'missing_zip_package', __( 'Zip Export not supported.', 'gutenberg' ) );
}

$obscura = wp_generate_password( 12, false, false );
$filename = get_temp_dir() . 'edit-site-export-' . $obscura . '.zip';

$zip = new ZipArchive();
if ( true !== $zip->open( $filename, ZipArchive::CREATE ) ) {
return new WP_Error( 'unable_to_create_zip', __( 'Unable to open export file (archive) for writing.', 'gutenberg' ) );
}

$zip->addEmptyDir( 'theme' );
$zip->addEmptyDir( 'theme/templates' );
$zip->addEmptyDir( 'theme/parts' );

// Load templates into the zip file.
$templates = gutenberg_get_block_templates();
foreach ( $templates as $template ) {
$template->content = _remove_theme_attribute_in_block_template_content( $template->content );

$zip->addFromString(
'theme/templates/' . $template->slug . '.html',
$template->content
);
}

// Load template parts into the zip file.
$template_parts = gutenberg_get_block_templates( array(), 'wp_template_part' );
foreach ( $template_parts as $template_part ) {
$zip->addFromString(
'theme/parts/' . $template_part->slug . '.html',
$template_part->content
);
}

$tree = WP_Theme_JSON_Resolver_Gutenberg::get_theme_data();
$tree->merge( WP_Theme_JSON_Resolver_Gutenberg::get_user_data() );

$zip->addFromString(
'theme/theme.json',
wp_json_encode( $tree->get_data(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE )
);

// Save changes to the zip file.
$zip->close();

return $filename;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*
* @see WP_REST_Controller
*/
class WP_REST_Edit_Site_Export_Controller extends WP_REST_Controller {
class Gutenberg_REST_Edit_Site_Export_Controller extends WP_REST_Controller {

/**
* Constructs the controller.
Expand All @@ -37,7 +37,8 @@ public function register_routes() {
'callback' => array( $this, 'export' ),
'permission_callback' => array( $this, 'permissions_check' ),
),
)
),
true // Override core route if already exists (WP 5.9).
);
}

Expand Down Expand Up @@ -66,7 +67,7 @@ public function permissions_check() {
*/
public function export() {
// Generate the export file.
$filename = wp_generate_block_templates_export_file();
$filename = gutenberg_generate_block_templates_export_file();

if ( is_wp_error( $filename ) ) {
$filename->add_data( array( 'status' => 500 ) );
Expand Down
44 changes: 44 additions & 0 deletions lib/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,48 @@ public function get_patterns() {
}
return array();
}

/**
* Returns a valid theme.json for a theme.
* Essentially, it flattens the preset data.
*
* @return array
*/
public function get_data() {
$flattened_theme_json = $this->theme_json;
$nodes = static::get_setting_nodes( $this->theme_json );
foreach ( $nodes as $node ) {
foreach ( static::PRESETS_METADATA as $preset_metadata ) {
$path = array_merge( $node['path'], $preset_metadata['path'] );
$preset = _wp_array_get( $flattened_theme_json, $path, null );
if ( null === $preset ) {
continue;
}

$items = array();
if ( isset( $preset['theme'] ) ) {
foreach ( $preset['theme'] as $item ) {
$slug = $item['slug'];
unset( $item['slug'] );
$items[ $slug ] = $item;
}
}
if ( isset( $preset['custom'] ) ) {
foreach ( $preset['custom'] as $item ) {
$slug = $item['slug'];
unset( $item['slug'] );
$items[ $slug ] = $item;
}
}
$flattened_preset = array();
foreach ( $items as $slug => $value ) {
$flattened_preset[] = array_merge( array( 'slug' => $slug ), $value );
}
_wp_array_set( $flattened_theme_json, $path, $flattened_preset );
}
}

return $flattened_theme_json;
}

}
13 changes: 12 additions & 1 deletion lib/compat/wordpress-6.0/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,15 @@ function gutenberg_register_rest_pattern_directory() {
$pattern_directory_controller = new Gutenberg_REST_Pattern_Directory_Controller();
$pattern_directory_controller->register_routes();
}
add_filter( 'rest_api_init', 'gutenberg_register_rest_pattern_directory' );
add_action( 'rest_api_init', 'gutenberg_register_rest_pattern_directory' );

/**
* Registers the Edit Site's Export REST API routes.
*
* @return void
*/
function gutenberg_register_edit_site_export_endpoint() {
$editor_settings = new Gutenberg_REST_Edit_Site_Export_Controller();
$editor_settings->register_routes();
}
add_action( 'rest_api_init', 'gutenberg_register_edit_site_export_endpoint' );
6 changes: 2 additions & 4 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@ function gutenberg_is_experiment_enabled( $name ) {
require_once __DIR__ . '/class-wp-rest-url-details-controller.php';
}

if ( ! class_exists( 'WP_REST_Edit_Site_Export_Controller' ) ) {
require_once __DIR__ . '/compat/wordpress-5.9/class-wp-rest-edit-site-export-controller.php';
}

require __DIR__ . '/rest-api.php';
}

Expand Down Expand Up @@ -96,8 +92,10 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/compat/wordpress-5.9/move-theme-editor-menu-item.php';
require __DIR__ . '/compat/wordpress-6.0/post-lock.php';
require __DIR__ . '/compat/wordpress-6.0/blocks.php';
require __DIR__ . '/compat/wordpress-6.0/block-template-utils.php';
require __DIR__ . '/compat/wordpress-6.0/class-gutenberg-rest-global-styles-controller.php';
require __DIR__ . '/compat/wordpress-6.0/class-gutenberg-rest-pattern-directory-controller.php';
require __DIR__ . '/compat/wordpress-6.0/class-gutenberg-rest-edit-site-export-controller.php';
require __DIR__ . '/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php';
require __DIR__ . '/compat/wordpress-6.0/rest-api.php';
require __DIR__ . '/compat/wordpress-6.0/block-patterns.php';
Expand Down
11 changes: 0 additions & 11 deletions lib/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,3 @@ function gutenberg_rest_user_collection_params_has_published_posts( $query_param
return $query_params;
}
add_filter( 'rest_user_collection_params', 'gutenberg_rest_user_collection_params_has_published_posts' );

/**
* Registers the Edit Site's Export REST API routes.
*
* @return void
*/
function gutenberg_register_edit_site_export_endpoint() {
$editor_settings = new WP_REST_Edit_Site_Export_Controller();
$editor_settings->register_routes();
}
add_action( 'rest_api_init', 'gutenberg_register_edit_site_export_endpoint' );
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default function SiteExport() {
role="menuitem"
icon={ download }
onClick={ handleExport }
info={ __( 'Download your templates and template parts.' ) }
info={ __( 'Download your templates and styles.' ) }
>
{ _x( 'Export', 'site exporter menu item' ) }
</MenuItem>
Expand Down
Loading

0 comments on commit 8fbf70c

Please sign in to comment.