From 4736f29c4a2e8c9d7d1e57ad572d92109164c47c Mon Sep 17 00:00:00 2001 From: eliot-akira Date: Fri, 25 Oct 2024 00:51:15 +0200 Subject: [PATCH] Optional object cache for parsed and pre-processed template posts - Resolves #127 --- admin/settings/index.php | 22 +++++++++- admin/settings/page.php | 1 + admin/template-post/cache.php | 73 ++++++++++++++++++++++++++++++++++ admin/template-post/index.php | 1 + admin/template-post/render.php | 28 +++++++++++-- admin/template-post/save.php | 15 +++++++ 6 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 admin/template-post/cache.php diff --git a/admin/settings/index.php b/admin/settings/index.php index 8596597a..15412a0b 100644 --- a/admin/settings/index.php +++ b/admin/settings/index.php @@ -48,6 +48,14 @@ 'default_value' => false, ], + [ + 'name' => 'object_cache_processed_template_post', + 'field_type' => 'checkbox', + 'label' => 'Object cache for parsed and pre-processed template posts (Experimental)', + 'default_value' => false, + 'beta' => true, + ], + [ 'name' => 'sass_in_browser', 'field_type' => 'checkbox', @@ -106,13 +114,23 @@ function get_settings( $field_name = null, $default_value = null ) { return $settings; } -function set_settings( $settings ) { +// Alias +function get_setting( $field_name = null, $default_value = null ) { + return get_settings($field_name, $default_value); +} +function set_settings( $settings ) { update_option( template_system::$state->settings_key, $settings ); - return $settings; } +function set_setting( $key, $value ) { + $settings = template_system\get_settings(); + if (!is_array($settings)) $settings = []; + $settings[ $key ] = $value; + return template_system\set_settings( $settings ); +} + function settings_page() { require_once __DIR__.'/page.php'; }; diff --git a/admin/settings/page.php b/admin/settings/page.php index eab47784..e0677105 100644 --- a/admin/settings/page.php +++ b/admin/settings/page.php @@ -1,5 +1,6 @@ Use the Transients API if you need to guarantee that your data will be cached. If persistent caching is configured, then the transients functions will use the wp_cache_* functions described in this document. However if persistent caching has not been enabled, then the data will instead be cached to the options table. + * + * @see https://developer.wordpress.org/apis/transients + * @see https://developer.wordpress.org/reference/classes/wp_object_cache/ + * @see https://developer.wordpress.org/advanced-administration/performance/cache/ + */ +namespace tangible\template_system; + +use tangible\html; +use tangible\template_system; + +function is_processed_template_post_cache_enabled() { + // See /admin/settings + return template_system\get_setting('object_cache_processed_template_post'); +} + +function get_template_post_cache_key($post) { + $type = $post->post_type; + $id = $post->ID; + return 'tangible_template_post_' . $type . '_' . $id; +} + +function get_processed_template_post_with_cache( $post ) { + + $cache_key = template_system\get_template_post_cache_key($post); + + // \tangible\see( $post); + + if (($processed = get_transient($cache_key))!==false) { + return $processed; + } + + return template_system\process_and_cache_template_post($post, $cache_key); +} + +/** + * Process and cache post content + */ +function process_and_cache_template_post( $post, $cache_key = null ) { + + if (empty($cache_key)) { + $cache_key = template_system\get_template_post_cache_key($post); + } + + $metadata = [ + 'time' => gmdate('Y-m-d H:i:s'), + 'type' => $post->post_type, + 'id' => $post->ID + ]; + $prefix = '\n"; + $content = html\parse( $prefix . ($post->post_content) ); + $processed = [ + 'parsed_content' => $content, + // ..Possibly other pre-processed template data + ] + $metadata; + + set_transient($cache_key, $processed); + + return $processed; +} + +/** + * Flush cache + */ +function delete_processed_template_post_cache( $post ) { + return delete_transient( + template_system\get_template_post_cache_key($post) + ); +} diff --git a/admin/template-post/index.php b/admin/template-post/index.php index 97745513..b1601e35 100644 --- a/admin/template-post/index.php +++ b/admin/template-post/index.php @@ -1,5 +1,6 @@ render_template_post = function( @@ -16,6 +17,9 @@ $is_post = true; + // Capture any style, script, or unexpected output + ob_start(); + // Direct post data if (is_array($post) && isset($post['content'])) { @@ -24,12 +28,28 @@ } else { if (is_numeric( $post )) $post = get_post( $post ); - if ( ! is_a( $post, 'WP_Post' )) return; + if ( ! is_a( $post, 'WP_Post' )) { + ob_end_clean(); + return; + } + $content = $post->post_content; - } - // Capture any style, script, or unexpected output - ob_start(); + /** + * Post content - Optionally processed and cached + * Passed to `$html->render_with_catch_exit()` which accepts string + * or parsed nodes. + * @see ./cache + */ + if (template_system\is_processed_template_post_cache_enabled()) { + + // Delete cache for testing + // template_system\delete_processed_template_post_cache($post); + + $processed = template_system\get_processed_template_post_with_cache( $post ); + $content = $processed['parsed_content'] ?? $content; + } + } /** * Local variable scope diff --git a/admin/template-post/save.php b/admin/template-post/save.php index 9f95be97..28195c02 100644 --- a/admin/template-post/save.php +++ b/admin/template-post/save.php @@ -1,4 +1,5 @@ is_saving_template_post = false; @@ -97,6 +98,13 @@ if ( isset( $fields['style'] ) ) { $plugin->maybe_save_style_compiled( $post, $fields['style'] ); } + + /** + * Optionally pre-process template post on save + */ + if (template_system\is_processed_template_post_cache_enabled()) { + template_system\process_and_cache_template_post( $post ); + } } return $result; @@ -146,6 +154,13 @@ } } + /** + * Optionally pre-process template post on save + */ + if (template_system\is_processed_template_post_cache_enabled()) { + template_system\process_and_cache_template_post( $post ); + } + }, 10, 3 ); /**