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

Block Template persistent cache- transient + object cache. #6369

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
74 changes: 72 additions & 2 deletions src/wp-includes/block-template-utils.php
Expand Up @@ -510,6 +510,76 @@ function _remove_theme_attribute_from_template_part_block( &$block ) {
}
}

/**
* Gets the contents for the given template file path.
*
* @since 6.4.0
* @access private
*
* @param string $template_file_path Absolute path to a theme template file.
* @return string The template file contents.
*/
function _get_block_template_file_content( $template_file_path ) {
$theme = is_theme_file( $template_file_path );
// Bypass cache if the file is not within the theme directory.
if ( ! $theme ) {
return file_get_contents( $template_file_path );
}
$template_file_path = wp_normalize_path( $template_file_path );

$cache_group = 'theme_files';
$cache_key = 'wp_theme_template_contents_' . md5( $theme->get_stylesheet() );
$transient_key = "{$cache_group}_{$cache_key}";

/*
* Bypass cache while developing a theme.
* If there is an existing cache, it should be deleted.
* This ensures that no stale cache values can be served when temporarily
* enabling "theme" development mode and then disabling it again.
*/
if ( wp_is_development_mode( 'theme' ) ) {
if ( wp_using_ext_object_cache() ) {
wp_cache_delete( $cache_key, $cache_group );
} else {
delete_site_transient( $transient_key );
}

return file_get_contents( $template_file_path );
}

// Check theme template cache first (if cached version matches the current theme version).
if ( wp_using_ext_object_cache() ) {
$template_data = wp_cache_get( $cache_key, $cache_group );
} else {
$template_data = get_site_transient( $transient_key );
}

if ( is_array( $template_data ) && $template_data['version'] === $theme->get( 'Version' ) ) {
if ( isset( $template_data['template_content'][ $template_file_path ] ) ) {
return $template_data['template_content'][ $template_file_path ];
}
} else {
$template_data = array(
'version' => $theme->get( 'Version' ),
'template_content' => array(),
);
}

// Retrieve fresh file contents if not found in cache.
$template_data['template_content'][ $template_file_path ] = file_get_contents( $template_file_path );

/** This filter is documented in wp-includes/theme.php */
$cache_expiration = (int) apply_filters( 'wp_cache_themes_persistently', 1800, 'theme_template_file_content' );

if ( wp_using_ext_object_cache() ) {
wp_cache_set( $cache_key, $template_data, $cache_group, $cache_expiration );
} else {
set_site_transient( $transient_key, $template_data, $cache_expiration );
}

return $template_data['template_content'][ $template_file_path ];
}

/**
* Builds a unified template object based on a theme file.
*
Expand All @@ -524,11 +594,11 @@ function _remove_theme_attribute_from_template_part_block( &$block ) {
function _build_block_template_result_from_file( $template_file, $template_type ) {
$default_template_types = get_default_block_template_types();
$theme = get_stylesheet();
$file_content = _get_block_template_file_content( $template_file['path'] );

$template = new WP_Block_Template();
$template->id = $theme . '//' . $template_file['slug'];
$template->theme = $theme;
$template->content = file_get_contents( $template_file['path'] );
$template->slug = $template_file['slug'];
$template->source = 'theme';
$template->type = $template_type;
Expand Down Expand Up @@ -559,7 +629,7 @@ function _build_block_template_result_from_file( $template_file, $template_type
$before_block_visitor = make_before_block_visitor( $hooked_blocks, $template );
$after_block_visitor = make_after_block_visitor( $hooked_blocks, $template );
}
$blocks = parse_blocks( $template->content );
$blocks = parse_blocks( $file_content );
$template->content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );

return $template;
Expand Down
27 changes: 27 additions & 0 deletions src/wp-includes/theme.php
Expand Up @@ -4382,3 +4382,30 @@ static function ( $active, WP_Customize_Panel $panel ) {
2
);
}

/**
* Checks if a file is part of the theme.
*
* @since 6.6.0
*
* @param string $file_path The file path to check.
* @return bool True if the file is part of the theme, false otherwise.
*/
function is_theme_file( $file_path ) {
$theme = wp_get_theme();

$file_path = wp_normalize_path( $file_path );
$theme_dir = wp_normalize_path( $theme->get_stylesheet_directory() ) . '/';

if ( str_starts_with( $file_path, $theme_dir ) ) {
return $theme;
} elseif ( $theme->parent() ) {
$theme = $theme->parent();
$theme_dir = wp_normalize_path( $theme->get_stylesheet_directory() ) . '/';
if ( str_starts_with( $file_path, $theme_dir ) ) {
return $theme;
}
}

return false;
}