style_dir = $upload_dir[ 'basedir' ] . '/' . $this->prefix . DIRECTORY_SEPARATOR; $this->style_url = set_url_scheme( $upload_dir[ 'baseurl' ] ) . '/' . $this->prefix . '/'; add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_assets' ), 99 ); add_action( 'save_post', array( $this, 'on_save_post' ), 10, 3 ); add_action( 'wp', array( $this, 'generate_post_content' ) ); // Synced patterns in block widgets render on every page; track them // once the widget/sidebar changes of the request are all saved. add_action( 'rest_after_save_widget', array( $this, 'schedule_widget_patterns_refresh' ) ); add_action( 'rest_delete_widget', array( $this, 'schedule_widget_patterns_refresh' ) ); add_action( 'rest_save_sidebar', array( $this, 'schedule_widget_patterns_refresh' ) ); add_action( 'after_switch_theme', array( $this, 'schedule_widget_patterns_refresh' ) ); add_action( 'rest_after_save_widget', array( $this, 'after_save_widget' ), 10, 4 ); add_action( 'rest_delete_widget', array( $this, 'after_save_widget' ) ); add_action( 'rest_save_sidebar', array( $this, 'after_save_widget' ) ); add_action( 'after_switch_theme', array( $this, 'after_save_widget' ) ); // FSE assets generation add_action( 'init', function () { if ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) { add_filter( '404_template', array( $this, 'fse_assets_generation' ), 99, 3 ); add_filter( 'archive_template', array( $this, 'fse_assets_generation' ), 99, 3 ); add_filter( 'category_template', array( $this, 'fse_assets_generation' ), 99, 3 ); add_filter( 'frontpage_template', array( $this, 'fse_assets_generation' ), 99, 3 ); add_filter( 'home_template', array( $this, 'fse_assets_generation' ), 99, 3 ); add_filter( 'index_template', array( $this, 'fse_assets_generation' ), 99, 3 ); add_filter( 'page_template', array( $this, 'fse_assets_generation' ), 99, 3 ); add_filter( 'search_template', array( $this, 'fse_assets_generation' ), 99, 3 ); add_filter( 'single_template', array( $this, 'fse_assets_generation' ), 99, 3 ); add_filter( 'singular_template', array( $this, 'fse_assets_generation' ), 99, 3 ); add_filter( 'tag_template', array( $this, 'fse_assets_generation' ), 99, 3 ); add_filter( 'taxonomy_template', array( $this, 'fse_assets_generation' ), 99, 3 ); } }, 999 ); } /** * Generate FSE Assets */ public function fse_assets_generation( $template, $type, $templates ) { $block_template = resolve_block_template( $type, $templates, $template ); if ( ! empty( $block_template ) ) { $parsed_content = parse_blocks( $block_template->content ); if ( is_array( $parsed_content ) && ! empty( $parsed_content ) ) { foreach ( $parsed_content as $content ) { if ( ( 'core/template-part' == $content[ 'blockName' ] ) || ( 'core/template' == $content[ 'blockName' ] ) ) { $post_ids = isset( $content[ 'attrs' ][ 'slug' ] ) ? self::betterdocs_get_post_content_by_post_name( $content[ 'attrs' ][ 'slug' ] ) : array( ); if ( ! empty( $post_ids ) ) { foreach ( $post_ids as $id ) { $post_id = (int) $id[ 'ID' ]; self::$_fse_template_post_ids[ ] = $post_id; $post = get_post( $post_id ); $parsed_content = parse_blocks( $post->post_content ); $this->write_css_from_content( $post, $post_id, $parsed_content ); } } } else { $post_ids = self::betterdocs_get_post_content_by_post_name( $block_template->slug ); if ( ! empty( $post_ids ) ) { foreach ( $post_ids as $id ) { $post_id = (int) $id[ 'ID' ]; self::$_fse_template_post_ids[ ] = $post_id; $post = get_post( $post_id ); $parsed_content = parse_blocks( $post->post_content ); $this->write_css_from_content( $post, $post_id, $parsed_content ); } } } } } } return $template; } /** * Write CSS */ public function write_css_from_content( $post, $post_id, $parsed_content ) { $betterdocs_blocks = array( ); $recursive_response = CSSParser::betterdocs_block_style_recursive( $parsed_content, $betterdocs_blocks ); $all_reusable_blocks = ! empty( $recursive_response[ 'reusableBlocks' ] ) ? $recursive_response[ 'reusableBlocks' ] : array( ); // remove empty reusable blocks $reusable_Blocks = array_filter( $all_reusable_blocks, function ( $v ) { return ! empty( $v ); } ); unset( $recursive_response[ 'reusableBlocks' ] ); $style = CSSParser::blocks_to_style_array( $recursive_response ); $reusableIds = $reusable_Blocks ? array_keys( $reusable_Blocks ) : array( ); // The option is merged into every page's enqueue, so only FSE // templates / template parts (rendered around every page) may set // it. Ordinary posts keep their ids in post meta below; they used to // overwrite the option too, so whatever the last post with synced // patterns referenced was loaded site-wide. if ( ! empty( $reusableIds ) && $this->is_fse_template( $post ) ) { update_option( '_betterdocs_reusable_block_ids', $reusableIds ); } update_post_meta( $post_id, '_betterdocs_reusable_block_ids', $reusableIds ); $this->write_block_css( $style, $post ); //Write CSS file for this page // Every referenced reusable block, including those with no BetterDocs // styles, so their stale files (e.g. pre-#174 copies of Essential // Blocks' CSS) are removed. foreach ( $all_reusable_blocks as $blockId => $block ) { $style = CSSParser::blocks_to_style_array( $block ); $this->write_reusable_block_css( $style, $blockId ); } } /** * Whether a post is an FSE template or template part. * * @param \WP_Post|null $post Post. * @return bool */ private function is_fse_template( $post ) { return isset( $post->post_type ) && ( 'wp_template_part' === $post->post_type || 'wp_template' === $post->post_type ); } /** * Rebuild the widget CSS when a widget or sidebar is saved or a widget is * deleted — once, at the end of the request: core fires * rest_after_save_widget before it assigns the widget to its sidebar. * @return void * @since 3.5.3 */ public function after_save_widget() { if ( false === has_action( 'shutdown', array( $this, 'rebuild_widget_css' ) ) ) { add_action( 'shutdown', array( $this, 'rebuild_widget_css' ) ); } } /** * Write the widget CSS file from every active block widget's BetterDocs * blocks, or remove it when there are none. It used to hold only the * widget saved last, and was never removed (e.g. stale Essential Blocks * CSS collected before #174 stayed loaded on every page). * @return void */ public function rebuild_widget_css() { $styles = array( ); foreach ( $this->active_block_widget_contents() as $content ) { if ( false === strpos( $content, '