Skip to content

Commit

Permalink
Factorize template sync
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad committed Nov 6, 2020
1 parent b67f498 commit 942aac1
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 184 deletions.
4 changes: 2 additions & 2 deletions lib/class-wp-rest-template-parts-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class WP_REST_Template_Parts_Controller extends WP_REST_Posts_Controller {
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function get_items( $request ) {
synchronize_theme_template_parts();
_gutenberg_synchronize_theme_templates( 'template-part' );

return parent::get_items( $request );
}
Expand All @@ -32,7 +32,7 @@ public function get_items( $request ) {
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function get_item( $request ) {
synchronize_theme_template_parts();
_gutenberg_synchronize_theme_templates( 'template-part' );

return parent::get_items( $request );
}
Expand Down
4 changes: 2 additions & 2 deletions lib/edit-site-export.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
function gutenberg_edit_site_export() {
// Theme templates and template parts need to be synchronized
// before the export.
synchronize_theme_template_parts();
synchronize_theme_templates();
_gutenberg_synchronize_theme_templates( 'template-part' );
_gutenberg_synchronize_theme_templates( 'template' );

// Create ZIP file and directories.
$filename = tempnam( get_temp_dir(), 'edit-site-export' );
Expand Down
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require dirname( __FILE__ ) . '/utils.php';

require dirname( __FILE__ ) . '/full-site-editing.php';
require dirname( __FILE__ ) . '/templates-sync.php';
require dirname( __FILE__ ) . '/templates.php';
require dirname( __FILE__ ) . '/template-parts.php';
require dirname( __FILE__ ) . '/template-loader.php';
Expand Down
2 changes: 1 addition & 1 deletion lib/template-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ function gutenberg_resolve_template( $template_type, $template_hierarchy = array
}

// Create auto-drafts for each theme template files.
synchronize_theme_templates();
_gutenberg_synchronize_theme_templates( 'template' );

if ( empty( $template_hierarchy ) ) {
if ( 'index' === $template_type ) {
Expand Down
87 changes: 0 additions & 87 deletions lib/template-parts.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,90 +183,3 @@ function filter_rest_wp_template_part_query( $args, $request ) {
return $args;
}
add_filter( 'rest_wp_template_part_query', 'filter_rest_wp_template_part_query', 99, 2 );

/**
* Creates a template part auto-draft if it doesn't exist yet.
*
* @access private
*
* @param string $slug Template part slug.
* @param string $theme Template part theme.
* @param string $content Template part content.
*/
function create_auto_draft_for_template_part( $slug, $theme, $content ) {
// We check if an auto-draft was already created,
// before running the REST API calls
// because the site editor needs an existing auto-draft
// for each theme template part to work properly.
$template_part_query = new WP_Query(
array(
'post_type' => 'wp_template_part',
'post_status' => array( 'publish', 'auto-draft' ),
'title' => $slug,
'meta_key' => 'theme',
'meta_value' => $theme,
'posts_per_page' => 1,
'no_found_rows' => true,
)
);
$template_part_post = $template_part_query->have_posts() ? $template_part_query->next_post() : null;
if ( ! $template_part_post ) {
wp_insert_post(
array(
'post_content' => $content,
'post_title' => $slug,
'post_status' => 'auto-draft',
'post_type' => 'wp_template_part',
'post_name' => $slug,
'meta_input' => array(
'theme' => $theme,
),
)
);
} else {
// Potentially we could decide to update the content if different.
}
}

/**
* Create the template parts auto-drafts for the current theme.
*
* @access private
*/
function synchronize_theme_template_parts() {
/**
* Finds all nested template part file paths in a theme's directory.
*
* @param string $base_directory The theme's file path.
* @return array $path_list A list of paths to all template part files.
*/
function get_template_part_paths( $base_directory ) {
$path_list = array();
if ( file_exists( $base_directory . '/block-template-parts' ) ) {
$nested_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_directory . '/block-template-parts' ) );
$nested_html_files = new RegexIterator( $nested_files, '/^.+\.html$/i', RecursiveRegexIterator::GET_MATCH );
foreach ( $nested_html_files as $path => $file ) {
$path_list[] = $path;
}
}
return $path_list;
}

// Get file paths for all theme supplied template parts.
$template_part_files = get_template_part_paths( get_stylesheet_directory() );
if ( is_child_theme() ) {
$template_part_files = array_merge( $template_part_files, get_template_part_paths( get_template_directory() ) );
}
// Build and save each template part.
foreach ( $template_part_files as $template_part_file ) {
$content = file_get_contents( $template_part_file );
$slug = substr(
$template_part_file,
// Starting position of slug.
strpos( $template_part_file, 'block-template-parts/' ) + 21,
// Subtract ending '.html'.
-5
);
create_auto_draft_for_template_part( $slug, wp_get_theme()->get( 'TextDomain' ), $content );
}
}
111 changes: 111 additions & 0 deletions lib/templates-sync.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php
/**
* Block templates and template parts auto-draft synchronization utils.
*
* @package gutenberg
*/

/**
* Creates a template (or template part depending on the post type)
* auto-draft if it doesn't exist yet.
*
* @access private
* @internal
*
* @param string $post_type Template post type.
* @param string $slug Template slug.
* @param string $theme Template theme.
* @param string $content Template content.
*/
function _gutenberg_create_auto_draft_for_template( $post_type, $slug, $theme, $content ) {
// We check if an auto-draft was already created,
// before running the REST API calls
// because the site editor needs an existing auto-draft
// for each theme template part to work properly.
$template_query = new WP_Query(
array(
'post_type' => $post_type,
'post_status' => array( 'publish', 'auto-draft' ),
'title' => $slug,
'meta_key' => 'theme',
'meta_value' => $theme,
'posts_per_page' => 1,
'no_found_rows' => true,
)
);
$post = $template_query->have_posts() ? $template_query->next_post() : null;
if ( ! $post ) {
wp_insert_post(
array(
'post_content' => $content,
'post_title' => $slug,
'post_status' => 'auto-draft',
'post_type' => $post_type,
'post_name' => $slug,
'meta_input' => array(
'theme' => $theme,
),
)
);
} else {
// Potentially we could decide to update the content if different.
}
}

/**
* Finds all nested template part file paths in a theme's directory.
*
* @access private
*
* @param string $base_directory The theme's file path.
* @return array $path_list A list of paths to all template part files.
*/
function _gutenberg_get_template_paths( $base_directory ) {
$path_list = array();
if ( file_exists( $base_directory ) ) {
$nested_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_directory ) );
$nested_html_files = new RegexIterator( $nested_files, '/^.+\.html$/i', RecursiveRegexIterator::GET_MATCH );
foreach ( $nested_html_files as $path => $file ) {
$path_list[] = $path;
}
}
return $path_list;
}

/**
* Create the template parts auto-drafts for the current theme.
*
* @access private
* @internal
*
* @param string $template_type The template type (template or template-part).
*/
function _gutenberg_synchronize_theme_templates( $template_type ) {
$template_post_types = array(
'template' => 'wp_template',
'template-part' => 'wp_template_part',
);
$template_base_paths = array(
'template' => 'block-templates',
'template-part' => 'block-template-parts',
);

// Get file paths for all theme supplied template.
$template_files = _gutenberg_get_template_paths( get_stylesheet_directory() . '/' . $template_base_paths[ $template_type ] );
if ( is_child_theme() ) {
$template_files = array_merge( $template_files, _gutenberg_get_template_paths( get_template_directory() . '/' . $template_base_paths[ $template_type ] ) );
}

// Build and save each template part.
foreach ( $template_files as $template_file ) {
$content = file_get_contents( $template_file );
$slug = substr(
$template_file,
// Starting position of slug.
strpos( $template_file, $template_base_paths[ $template_type ] . '/' ) + 1 + strlen( $template_base_paths[ $template_type ] ),
// Subtract ending '.html'.
-5
);
_gutenberg_create_auto_draft_for_template( $template_post_types[ $template_type ], $slug, wp_get_theme()->get( 'TextDomain' ), $content );
}
}
92 changes: 0 additions & 92 deletions lib/templates.php
Original file line number Diff line number Diff line change
Expand Up @@ -236,95 +236,3 @@ function filter_rest_wp_template_query( $args, $request ) {
return $args;
}
add_filter( 'rest_wp_template_query', 'filter_rest_wp_template_query', 99, 2 );

/**
* Creates a template auto-draft if it doesn't exist yet.
*
* @access private
*
* @param string $slug Template slug.
* @param string $theme Template theme.
* @param string $content Template content.
*/
function create_auto_draft_for_template( $slug, $theme, $content ) {
// We check if an auto-draft was already created,
// before running the REST API calls
// because the site editor needs an existing auto-draft
// for each theme template to work properly.
$template_query = new WP_Query(
array(
'post_type' => 'wp_template',
'post_status' => array( 'publish', 'auto-draft' ),
'title' => $slug,
'meta_key' => 'theme',
'meta_value' => $theme,
'posts_per_page' => 1,
'no_found_rows' => true,
)
);
$template_post = $template_query->have_posts() ? $template_query->next_post() : null;
if ( ! $template_post ) {
wp_insert_post(
array(
'post_content' => $content,
'post_title' => $slug,
'post_status' => 'auto-draft',
'post_type' => 'wp_template',
'post_name' => $slug,
'meta_input' => array(
'theme' => $theme,
),
)
);
} else {
// Potentially we could decide to update the content if different.
}
}

/**
* Create the template auto-drafts for the current theme.
*
* @access private
*/
function synchronize_theme_templates() {
/**
* Finds all nested template part file paths in a theme's directory.
*
* @param string $base_directory The theme's file path.
* @return array $path_list A list of paths to all template part files.
*/
function get_template_paths( $base_directory ) {
$path_list = array();
if ( file_exists( $base_directory . '/block-templates' ) ) {
$nested_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_directory . '/block-templates' ) );
$nested_html_files = new RegexIterator( $nested_files, '/^.+\.html$/i', RecursiveRegexIterator::GET_MATCH );
foreach ( $nested_html_files as $path => $file ) {
$path_list[] = $path;
}
}
return $path_list;
}

// Get file paths for all theme supplied template parts.
$template_files = get_template_paths( get_stylesheet_directory() );
if ( is_child_theme() ) {
$template_files = array_merge( $template_files, get_template_paths( get_template_directory() ) );
}
// Build and save each template part.
foreach ( $template_files as $template_file ) {
$content = file_get_contents( $template_file );
$slug = substr(
$template_file,
// Starting position of slug.
strpos( $template_file, 'block-templates/' ) + 16,
// Subtract ending '.html'.
-5
);
create_auto_draft_for_template( $slug, wp_get_theme()->get( 'TextDomain' ), $content );
}

// If we haven't found any block-template by default, create a fallback one.
if ( count( $template_files ) === 0 ) {
create_auto_draft_for_template( 'index', wp_get_theme()->get( 'TextDomain' ), '' );
}
}

0 comments on commit 942aac1

Please sign in to comment.