mirror of
https://gh.wpcy.net/https://github.com/WordPress/create-block-theme.git
synced 2026-04-27 12:22:16 +08:00
179 lines
5.7 KiB
PHP
179 lines
5.7 KiB
PHP
<?php
|
|
|
|
class CBT_Theme_Patterns {
|
|
public static function pattern_from_template( $template, $new_slug = null ) {
|
|
$theme_slug = $new_slug ? $new_slug : wp_get_theme()->get( 'TextDomain' );
|
|
$pattern_slug = $theme_slug . '/' . $template->slug;
|
|
$pattern_content = <<<PHP
|
|
<?php
|
|
/**
|
|
* Title: {$template->slug}
|
|
* Slug: {$pattern_slug}
|
|
* Inserter: no
|
|
*/
|
|
?>
|
|
{$template->content}
|
|
PHP;
|
|
|
|
return array(
|
|
'slug' => $pattern_slug,
|
|
'content' => $pattern_content,
|
|
);
|
|
}
|
|
|
|
public static function pattern_from_wp_block( $pattern_post, $options ) {
|
|
|
|
if ( ! $options ) {
|
|
$options = array(
|
|
'localizeText' => false,
|
|
'removeNavRefs' => true,
|
|
'localizeImages' => true,
|
|
);
|
|
}
|
|
|
|
$pattern = new stdClass();
|
|
$pattern->id = $pattern_post->ID;
|
|
$pattern->title = $pattern_post->post_title;
|
|
$pattern->name = sanitize_title_with_dashes( $pattern_post->post_title );
|
|
$pattern->slug = wp_get_theme()->get( 'TextDomain' ) . '/' . $pattern->name;
|
|
$pattern_category_list = get_the_terms( $pattern->id, 'wp_pattern_category' );
|
|
$pattern->categories = ! empty( $pattern_category_list ) ? join( ', ', wp_list_pluck( $pattern_category_list, 'name' ) ) : '';
|
|
$pattern->sync_status = get_post_meta( $pattern->id, 'wp_pattern_sync_status', true );
|
|
$pattern->is_synced = $pattern->sync_status === 'unsynced' ? 'no' : 'yes';
|
|
$pattern->content = <<<PHP
|
|
<?php
|
|
/**
|
|
* Title: {$pattern->title}
|
|
* Slug: {$pattern->slug}
|
|
* Categories: {$pattern->categories}
|
|
* Synced: {$pattern->is_synced}
|
|
*/
|
|
?>
|
|
{$pattern_post->post_content}
|
|
PHP;
|
|
|
|
$pattern = CBT_Theme_Templates::eliminate_environment_specific_content( $pattern, $options );
|
|
|
|
if ( array_key_exists( 'localizeText', $options ) && $options['localizeText'] ) {
|
|
$pattern = CBT_Theme_Templates::escape_text_in_template( $pattern );
|
|
}
|
|
|
|
if ( array_key_exists( 'localizeImages', $options ) && $options['localizeImages'] ) {
|
|
$pattern = CBT_Theme_Media::make_template_images_local( $pattern );
|
|
|
|
// Write the media assets if there are any
|
|
if ( $pattern->media ) {
|
|
CBT_Theme_Media::add_media_to_local( $pattern->media );
|
|
}
|
|
}
|
|
|
|
return $pattern;
|
|
}
|
|
|
|
public static function escape_alt_for_pattern( $html ) {
|
|
if ( empty( $html ) ) {
|
|
return $html;
|
|
}
|
|
$html = new WP_HTML_Tag_Processor( $html );
|
|
while ( $html->next_tag( 'img' ) ) {
|
|
$alt_attribute = $html->get_attribute( 'alt' );
|
|
if ( ! empty( $alt_attribute ) ) {
|
|
$html->set_attribute( 'alt', self::escape_text_for_pattern( $alt_attribute ) );
|
|
}
|
|
}
|
|
return $html->__toString();
|
|
}
|
|
|
|
public static function escape_text_for_pattern( $text ) {
|
|
if ( $text && trim( $text ) !== '' ) {
|
|
$escaped_text = addslashes( $text );
|
|
return "<?php esc_attr_e('" . $escaped_text . "', '" . wp_get_theme()->get( 'Name' ) . "');?>";
|
|
}
|
|
}
|
|
|
|
public static function create_pattern_link( $attributes ) {
|
|
$block_attributes = array_filter( $attributes );
|
|
$attributes_json = json_encode( $block_attributes, JSON_UNESCAPED_SLASHES );
|
|
return '<!-- wp:pattern ' . $attributes_json . ' /-->';
|
|
}
|
|
|
|
public static function replace_local_synced_pattern_references( $pattern ) {
|
|
|
|
// List all template and pattern files in the theme
|
|
$base_dir = get_stylesheet_directory();
|
|
$patterns = glob( $base_dir . DIRECTORY_SEPARATOR . 'patterns' . DIRECTORY_SEPARATOR . '*.php' );
|
|
$templates = glob( $base_dir . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . '*.html' );
|
|
$template_parts = glob( $base_dir . DIRECTORY_SEPARATOR . 'template-parts' . DIRECTORY_SEPARATOR . '*.html' );
|
|
|
|
$needle = 'wp:block {"ref":' . $pattern->id;
|
|
$replacement = 'wp:pattern {"slug":"' . $pattern->slug . '"';
|
|
// Replace references to the local unsynced patterns in the theme
|
|
foreach ( array_merge( $patterns, $templates, $template_parts ) as $file ) {
|
|
$file_content = file_get_contents( $file );
|
|
$file_content = str_replace( $needle, $replacement, $file_content );
|
|
file_put_contents( $file, $file_content );
|
|
}
|
|
|
|
// if we clear the template customizations for all templates then we have to SAVE all templates.
|
|
CBT_Theme_Templates::clear_user_templates_customizations();
|
|
CBT_Theme_Templates::clear_user_template_parts_customizations();
|
|
}
|
|
|
|
/**
|
|
* Copy the local patterns as well as any media to the theme filesystem.
|
|
*/
|
|
public static function add_patterns_to_theme( $options = null ) {
|
|
|
|
$pattern_query = new WP_Query(
|
|
array(
|
|
'post_type' => 'wp_block',
|
|
'posts_per_page' => -1,
|
|
)
|
|
);
|
|
|
|
if ( $pattern_query->have_posts() ) {
|
|
|
|
$synced_patterns = array();
|
|
|
|
foreach ( $pattern_query->posts as $pattern ) {
|
|
$pattern = self::pattern_from_wp_block( $pattern, $options );
|
|
self::add_pattern_to_theme( $pattern );
|
|
|
|
if ( $pattern->is_synced === 'yes' ) {
|
|
$synced_patterns[] = $pattern;
|
|
}
|
|
}
|
|
|
|
// now replace all instances of synced blocks with pattern blocks
|
|
// we wait uttil all patterns are added to the theme before doing this
|
|
// because some patterns may reference other patterns
|
|
foreach ($synced_patterns as $pattern) {
|
|
self::replace_local_synced_pattern_references($pattern);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
public static function add_pattern_to_theme($pattern)
|
|
{
|
|
$patterns_dir = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'patterns' . DIRECTORY_SEPARATOR;
|
|
$pattern_file = $patterns_dir . $pattern->name . '.php';
|
|
|
|
// If there is no patterns folder, create it.
|
|
if ( ! is_dir( $patterns_dir ) ) {
|
|
wp_mkdir_p( $patterns_dir );
|
|
}
|
|
|
|
// Create the pattern file.
|
|
file_put_contents( $pattern_file, $pattern->content);
|
|
|
|
// update the post_name value to match the pattern slug
|
|
wp_update_post(
|
|
array(
|
|
'ID' => $pattern->id,
|
|
'post_name' => sanitize_title($pattern->slug),
|
|
)
|
|
);
|
|
}
|
|
}
|