Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy changes for theme export back to core #2534

Closed
Closed
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 81 additions & 12 deletions src/wp-includes/block-template-utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@ function get_default_block_template_types() {
),
'home' => array(
'title' => _x( 'Home', 'Template name' ),
'description' => __( 'Displays as the site\'s home page, or as the Posts page when a static home page isn\'t set.' ),
'description' => __( 'Displays posts on the homepage, or on the Posts page if a static homepage is set.' ),
),
'front-page' => array(
'title' => _x( 'Front Page', 'Template name' ),
'description' => __( 'Displays as the site\'s home page.' ),
'description' => __( 'Displays the homepage.' ),
),
'singular' => array(
'title' => _x( 'Singular', 'Template name' ),
Expand Down Expand Up @@ -162,12 +162,12 @@ function get_default_block_template_types() {
'description' => __( 'Displays latest posts with a single post tag.' ),
),
'attachment' => array(
'title' => __( 'Attachment' ),
'title' => __( 'Media' ),
'description' => __( 'Displays individual media items or attachments.' ),
),
'search' => array(
'title' => _x( 'Search', 'Template name' ),
'description' => __( 'Template used to display search results.' ),
'description' => __( 'Displays search results.' ),
),
'privacy-policy' => array(
'title' => __( 'Privacy Policy' ),
Expand Down Expand Up @@ -902,12 +902,32 @@ function block_footer_area() {
block_template_part( 'footer' );
}

/**
* Filters theme directories that should be ignored during export.
*
* @since 6.0.0
*
* @param string $path The path of the file in the theme.
* @return Bool Whether this file is in an ignored directory.
*/
function wp_is_theme_directory_ignored( $path ) {
$directories_to_ignore = array( '.svn', '.git', '.hg', '.bzr', 'node_modules', 'vendor' );
foreach ( $directories_to_ignore as $directory ) {
if ( strpos( $path, $directory ) === 0 ) {
return true;
}
}

return false;
}

/**
* 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 the whole theme to the export archive.
*
* @return WP_Error|string Path of the ZIP file or error on failure.
*/
Expand All @@ -916,25 +936,48 @@ function wp_generate_block_templates_export_file() {
return new WP_Error( 'missing_zip_package', __( 'Zip Export not supported.' ) );
}

$obscura = wp_generate_password( 12, false, false );
$filename = get_temp_dir() . 'edit-site-export-' . $obscura . '.zip';
$obscura = wp_generate_password( 12, false, false );
$theme_name = wp_get_theme()->get( 'TextDomain' );
$filename = get_temp_dir() . $theme_name . $obscura . '.zip';

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

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

// Get path of the theme.
$theme_path = wp_normalize_path( get_stylesheet_directory() );

// Create recursive directory iterator.
$theme_files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator( $theme_path ),
RecursiveIteratorIterator::LEAVES_ONLY
);

// Make a copy of the current theme.
foreach ( $theme_files as $file ) {
// Skip directories as they are added automatically.
if ( ! $file->isDir() ) {
// Get real and relative path for current file.
$file_path = wp_normalize_path( $file );
$relative_path = substr( $file_path, strlen( $theme_path ) + 1 );

if ( ! wp_is_theme_directory_ignored( $relative_path ) ) {
$zip->addFile( $file_path, $relative_path );
}
}
}

// Load templates into the zip file.
$templates = 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',
'templates/' . $template->slug . '.html',
$template->content
);
}
Expand All @@ -943,11 +986,37 @@ function wp_generate_block_templates_export_file() {
$template_parts = get_block_templates( array(), 'wp_template_part' );
foreach ( $template_parts as $template_part ) {
$zip->addFromString(
'theme/parts/' . $template_part->slug . '.html',
'parts/' . $template_part->slug . '.html',
$template_part->content
);
}

// Load theme.json into the zip file.
$tree = WP_Theme_JSON_Resolver::get_theme_data( array(), array( 'with_supports' => false ) );
// Merge with user data.
$tree->merge( WP_Theme_JSON_Resolver::get_user_data() );

$theme_json_raw = $tree->get_data();
// If a version is defined, add a schema.
if ( $theme_json_raw['version'] ) {
global $wp_version;
$theme_json_version = 'wp/' . substr( $wp_version, 0, 3 );
$schema = array( '$schema' => 'https://schemas.wp.org/' . $theme_json_version . '/theme.json' );
$theme_json_raw = array_merge( $schema, $theme_json_raw );
}

// Convert to a string.
$theme_json_encoded = wp_json_encode( $theme_json_raw, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );

// Replace 4 spaces with a tab.
$theme_json_tabbed = preg_replace( '~(?:^|\G)\h{4}~m', "\t", $theme_json_encoded );

// Add the theme.json file to the zip.
$zip->addFromString(
'theme.json',
$theme_json_tabbed
);

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

Expand Down
13 changes: 12 additions & 1 deletion src/wp-includes/class-wp-theme-json-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,17 @@ public static function get_core_data() {
*
* @since 5.8.0
* @since 5.9.0 Theme supports have been inlined and the `$theme_support_data` argument removed.
* @since 6.0.0 Adds a second parameter to allow the theme data to be returned without theme supports.
*
* @param array $deprecated Deprecated. Not used.
* @param array $settings Contains a key called with_supports to determine whether to include theme supports in the data.
* @return WP_Theme_JSON Entity that holds theme data.
*/
public static function get_theme_data( $deprecated = array() ) {
public static function get_theme_data( $deprecated = array(), $settings = array( 'with_supports' => true ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't typically follow this pattern in Core. Traditionally this would be an empty array and use wp_parse_args to set defaults.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 2529def

if ( ! empty( $deprecated ) ) {
_deprecated_argument( __METHOD__, '5.9.0' );
}

if ( null === static::$theme ) {
$theme_json_data = static::read_json_file( static::get_file_path_from_theme( 'theme.json' ) );
$theme_json_data = static::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) );
Expand All @@ -177,6 +180,10 @@ public static function get_theme_data( $deprecated = array() ) {
}
}

if ( ! $settings['with_supports'] ) {
return static::$theme;
}

/*
* We want the presets and settings declared in theme.json
* to override the ones declared via theme supports.
Expand Down Expand Up @@ -208,6 +215,9 @@ public static function get_theme_data( $deprecated = array() ) {
$default_gradients = true;
}
$theme_support_data['settings']['color']['defaultGradients'] = $default_gradients;

// Classic themes without a theme.json don't support global duotone.
$theme_support_data['settings']['color']['defaultDuotone'] = false;
}
$with_theme_supports = new WP_Theme_JSON( $theme_support_data );
$with_theme_supports->merge( static::$theme );
Expand Down Expand Up @@ -477,4 +487,5 @@ public static function get_style_variations() {
}
return $variations;
}

}
Loading