Skip to content

Instantly share code, notes, and snippets.

@jdamner
Created November 13, 2023 12:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdamner/b6c178d825b8e673aaa5c9608c69f399 to your computer and use it in GitHub Desktop.
Save jdamner/b6c178d825b8e673aaa5c9608c69f399 to your computer and use it in GitHub Desktop.
<?php
/**
* A method to persist template changes to disk
*
* This helper writes template changes to their appropriate HTML file instead of saving
* them to the DB, helping make local theme development of block based themes more
* efficient.
*/
declare ( strict_types = 1 );
/**
* TemplatePersistence
*/
class TemplatePersistence {
/**
* Init Hooks
*
* @return void
*/
public function init(): void {
add_action( 'save_post', [ $this, 'persist_template' ], 10, 2 );
}
/**
* Persist Template
*
* @param int $post_id Post ID.
* @param \WP_Post $post The post.
*
* @return void
*/
public function persist_template( int $post_id, \WP_Post $post ): void {
$filename = self::get_template_filename( $post );
if ( false === $filename || ! self::is_writeable( $filename ) ) {
return;
}
if ( file_put_contents( $filename, $post->post_content ) ) {
wp_delete_post( $post->ID, true );
}
}
/**
* Gets the filename for a template.
*
* @param \WP_Post $post The post object.
*
* @return string|false The filename or false if the post is not a template.
*/
public static function get_template_filename( \WP_Post $post ): string|false {
// We only want to persist templates.
$template_dir = match ( $post->post_type ) {
'wp_template' => 'templates',
'wp_template_part' => 'parts',
default => false,
};
if ( false === $template_dir ) {
return false;
}
return join(
'/',
[
rtrim( get_stylesheet_directory(), '/' ),
$template_dir,
$post->post_name . '.html',
]
);
}
/**
* Checks if a file is writeable
*
* @param string $filename The filename.
*
* @return bool True if the file is writeable, false otherwise.
*/
public static function is_writeable( string $filename ): bool {
$directory = dirname( $filename );
if ( ! is_dir( $directory ) ) {
mkdir( $directory, 0755, true );
}
return is_writeable( $directory ) && touch( $filename );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment