From c320a83b7225be67a79fa8acd358dea7a28d7ed5 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Mar 2026 15:14:37 +0000 Subject: [PATCH] Load block scripts conditionally via wp_register_script Resolves #123 by refactoring all frontend script enqueueing to follow WordPress best practices: scripts are now registered during init and only enqueued when their corresponding block is actually rendered on the page. Changes per module: - Plugin_Main: register carousel/accordion scripts; enqueue accordion only when an accordion block is rendered via render_block filter. - Carousel: register frontend assets; enqueue glide.min.js and carousel JS/CSS only when a carousel/slider block attribute is detected. - Animations: register CSS/JS; enqueue only when a block with frbl animation, glass-effect, or hover-scale attributes is rendered. - StickyColumn: register CSS/JS; enqueue only when frblStickyEnabled is true on a generateblocks/grid block. - ContainerEdgeAlignment: register CSS/JS; enqueue only when frblEdgeAlignment attribute is present on a container block. - ShapeAnimations: register CSS/JS/Lottie; enqueue only when frblCustomSvgAnimationEnabled is true on a shape block. - GravityFormsInline: register CSS/JS; enqueue only when frblGfInlineEnabled is true on a gravityforms/form block. - Headline: remove global wp_enqueue_scripts hook; enqueue styles on any generateblocks/text or headline block render, and enqueue marquee JS only when frblMarqueeSpeed is set. - InsertPost: register CSS; enqueue inside render_callback so it only loads on pages where the frontblocks/insert-post block is used. https://claude.ai/code/session_01HViCm5WRkqZFKcKRrkJRZN --- includes/Frontend/Animations.php | 28 ++++++----- includes/Frontend/Carousel.php | 31 ++++++++++++ includes/Frontend/ContainerEdgeAlignment.php | 19 ++++--- includes/Frontend/GravityFormsInline.php | 17 +++++-- includes/Frontend/Headline.php | 26 +++++++--- includes/Frontend/InsertPost.php | 13 +++-- includes/Frontend/ShapeAnimations.php | 22 +++++--- includes/Frontend/StickyColumn.php | 19 ++++--- includes/Plugin_Main.php | 53 ++++++++++++++------ 9 files changed, 166 insertions(+), 62 deletions(-) diff --git a/includes/Frontend/Animations.php b/includes/Frontend/Animations.php index 27350fd..8f2e0eb 100644 --- a/includes/Frontend/Animations.php +++ b/includes/Frontend/Animations.php @@ -32,27 +32,26 @@ public function __construct() { * @return void */ private function init_hooks() { - add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), 100 ); + add_action( 'init', array( $this, 'register_scripts' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ), 5 ); add_action( 'enqueue_block_editor_assets', array( $this, 'register_animation_attributes' ), 15 ); add_filter( 'render_block', array( $this, 'add_animation_classes_to_blocks' ), 10, 2 ); } /** - * Enqueue scripts and styles. + * Register frontend scripts and styles for conditional enqueueing. * * @return void */ - public function enqueue_scripts() { - // Enqueue custom animations CSS. - wp_enqueue_style( + public function register_scripts() { + wp_register_style( 'frontblocks-animations', FRBL_PLUGIN_URL . 'assets/animations/frontblocks-animations.css', array(), FRBL_VERSION ); - wp_enqueue_script( + wp_register_script( 'frontblocks-animations-custom', FRBL_PLUGIN_URL . 'assets/animations/frontblocks-animations.js', array(), @@ -67,13 +66,8 @@ public function enqueue_scripts() { * @return void */ public function enqueue_block_editor_assets() { - // Enqueue custom animations CSS for editor. - wp_enqueue_style( - 'frontblocks-animations-editor', - FRBL_PLUGIN_URL . 'assets/animations/frontblocks-animations.css', - array(), - FRBL_VERSION - ); + // Enqueue custom animations CSS for editor (reuse registered frontend style). + wp_enqueue_style( 'frontblocks-animations' ); // Enqueue custom block editor script. wp_enqueue_script( @@ -208,6 +202,14 @@ public function add_animation_classes_to_blocks( $block_content, $block ) { return $block_content; } + // Enqueue frontend assets only when a block with animation features is present. + if ( ! wp_style_is( 'frontblocks-animations', 'enqueued' ) ) { + wp_enqueue_style( 'frontblocks-animations' ); + } + if ( ! wp_script_is( 'frontblocks-animations-custom', 'enqueued' ) ) { + wp_enqueue_script( 'frontblocks-animations-custom' ); + } + $properties = array(); // Animation properties. diff --git a/includes/Frontend/Carousel.php b/includes/Frontend/Carousel.php index e5320e6..a0df198 100644 --- a/includes/Frontend/Carousel.php +++ b/includes/Frontend/Carousel.php @@ -32,6 +32,7 @@ public function __construct() { * @return void */ private function init_hooks() { + add_action( 'init', array( $this, 'register_frontend_assets' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) ); add_action( 'enqueue_block_assets', array( $this, 'enqueue_block_canvas_assets' ) ); add_filter( 'render_block_generateblocks/grid', array( $this, 'add_custom_attributes_to_grid_block' ), 10, 2 ); @@ -40,6 +41,30 @@ private function init_hooks() { add_action( 'init', array( $this, 'register_custom_attributes' ), 5 ); } + /** + * Register frontend carousel assets for conditional enqueueing. + * + * @return void + */ + public function register_frontend_assets() { + // Assets are registered in Plugin_Main::register_scripts(). + // This method exists as a hook point for any additional registration needs. + } + + /** + * Enqueue carousel frontend assets when a carousel block is detected. + * + * @return void + */ + private function enqueue_carousel_assets() { + if ( ! wp_style_is( 'frontblocks-carousel', 'enqueued' ) ) { + wp_enqueue_style( 'frontblocks-carousel' ); + } + if ( ! wp_script_is( 'frontblocks-carousel-custom', 'enqueued' ) ) { + wp_enqueue_script( 'frontblocks-carousel-custom' ); + } + } + /** * Enqueue carousel CSS in the editor canvas (iframe). * @@ -129,6 +154,8 @@ public function add_custom_attributes_to_grid_block( $block_content, $block ) { $block_content, 1 // Only replace the first occurrence. ); + + $this->enqueue_carousel_assets(); } return $block_content; @@ -195,6 +222,8 @@ public function add_custom_attributes_to_element_block( $block_content, $block ) $block_content, 1 // Only replace the first occurrence. ); + + $this->enqueue_carousel_assets(); } return $block_content; @@ -261,6 +290,8 @@ public function add_custom_attributes_to_core_group_block( $block_content, $bloc $block_content, 1 // Only replace the first occurrence. ); + + $this->enqueue_carousel_assets(); } return $block_content; diff --git a/includes/Frontend/ContainerEdgeAlignment.php b/includes/Frontend/ContainerEdgeAlignment.php index 13dec52..2301b97 100644 --- a/includes/Frontend/ContainerEdgeAlignment.php +++ b/includes/Frontend/ContainerEdgeAlignment.php @@ -25,8 +25,8 @@ class ContainerEdgeAlignment { * Constructor. */ public function __construct() { + add_action( 'init', array( $this, 'register_frontend_assets' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_editor_assets' ) ); - add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_assets' ) ); add_filter( 'render_block', array( $this, 'add_edge_alignment_classes' ), 10, 2 ); } @@ -59,20 +59,19 @@ public function enqueue_editor_assets() { } /** - * Enqueue frontend assets. + * Register frontend assets for conditional enqueueing. * * @return void */ - public function enqueue_frontend_assets() { - wp_enqueue_style( + public function register_frontend_assets() { + wp_register_style( 'frbl-edge-alignment', FRBL_PLUGIN_URL . 'assets/container-edge-alignment/frontblocks-edge-alignment.css', array(), FRBL_VERSION ); - // Add inline script to calculate margins dynamically. - wp_enqueue_script( + wp_register_script( 'frbl-edge-alignment-js', FRBL_PLUGIN_URL . 'assets/container-edge-alignment/frontblocks-edge-alignment-frontend.js', array(), @@ -116,6 +115,14 @@ public function add_edge_alignment_classes( $block_content, $block ) { return $block_content; } + // Enqueue frontend assets only when an edge-aligned block is detected. + if ( ! wp_style_is( 'frbl-edge-alignment', 'enqueued' ) ) { + wp_enqueue_style( 'frbl-edge-alignment' ); + } + if ( ! wp_script_is( 'frbl-edge-alignment-js', 'enqueued' ) ) { + wp_enqueue_script( 'frbl-edge-alignment-js' ); + } + // Add class to the block. // Find the first occurrence of class=" and add our class. if ( false !== strpos( $block_content, 'class="' ) ) { diff --git a/includes/Frontend/GravityFormsInline.php b/includes/Frontend/GravityFormsInline.php index 2e67e46..5aac8c2 100644 --- a/includes/Frontend/GravityFormsInline.php +++ b/includes/Frontend/GravityFormsInline.php @@ -34,26 +34,26 @@ public function __construct() { * @return void */ private function init_hooks() { - add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), 99 ); + add_action( 'init', array( $this, 'register_scripts' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) ); add_filter( 'render_block', array( $this, 'add_inline_attributes_to_gf_block' ), 10, 2 ); add_action( 'init', array( $this, 'register_custom_attributes' ), 5 ); } /** - * Enqueue scripts and styles. + * Register frontend scripts and styles for conditional enqueueing. * * @return void */ - public function enqueue_scripts() { - wp_enqueue_style( + public function register_scripts() { + wp_register_style( 'frontblocks-gf-inline', FRBL_PLUGIN_URL . 'assets/gravityforms-inline/frontblocks-gf-inline.css', array(), FRBL_VERSION ); - wp_enqueue_script( + wp_register_script( 'frontblocks-gf-inline-runtime', FRBL_PLUGIN_URL . 'assets/gravityforms-inline/frontblocks-gf-inline.js', array(), @@ -110,6 +110,13 @@ public function add_inline_attributes_to_gf_block( $block_content, $block ) { // Add inline class and attributes if enabled. if ( $inline_enabled ) { + // Enqueue frontend assets only when the GF inline feature is active. + if ( ! wp_style_is( 'frontblocks-gf-inline', 'enqueued' ) ) { + wp_enqueue_style( 'frontblocks-gf-inline' ); + } + if ( ! wp_script_is( 'frontblocks-gf-inline-runtime', 'enqueued' ) ) { + wp_enqueue_script( 'frontblocks-gf-inline-runtime' ); + } // Try multiple approaches to add the class. // Method 1: Add to wp-block-gravityforms-form wrapper. if ( strpos( $block_content, 'wp-block-gravityforms-form' ) !== false ) { diff --git a/includes/Frontend/Headline.php b/includes/Frontend/Headline.php index 010d72e..a101fbd 100644 --- a/includes/Frontend/Headline.php +++ b/includes/Frontend/Headline.php @@ -24,9 +24,10 @@ class Headline { public function __construct() { add_action( 'init', array( $this, 'register_assets' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_editor_assets' ) ); - add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_styles' ), 100 ); add_filter( 'generateblocks_attr_headline', array( $this, 'add_line_class_attribute' ), 10 ); add_filter( 'generateblocks_attr_text', array( $this, 'add_marquee_speed_attribute' ), 10, 2 ); + add_filter( 'render_block_generateblocks/text', array( $this, 'maybe_enqueue_frontend_assets' ), 10, 2 ); + add_filter( 'render_block_generateblocks/headline', array( $this, 'maybe_enqueue_frontend_assets' ), 10, 2 ); } /** @@ -84,13 +85,26 @@ public function enqueue_editor_assets() { } /** - * Enqueue frontend styles and scripts. + * Conditionally enqueue frontend assets when a GenerateBlocks headline/text block is rendered. * - * @return void + * @param string $block_content Block content. + * @param array $block Block data. + * @return string */ - public function enqueue_frontend_styles() { - wp_enqueue_style( 'frontblocks-headline-styles' ); - wp_enqueue_script( 'frontblocks-headline-marquee' ); + public function maybe_enqueue_frontend_assets( $block_content, $block ) { + $attrs = $block['attrs'] ?? array(); + + // Enqueue headline styles when any headline/text block with frbl features is rendered. + if ( ! wp_style_is( 'frontblocks-headline-styles', 'enqueued' ) ) { + wp_enqueue_style( 'frontblocks-headline-styles' ); + } + + // Enqueue marquee script only when marquee is active on this block. + if ( ! empty( $attrs['frblMarqueeSpeed'] ) && ! wp_script_is( 'frontblocks-headline-marquee', 'enqueued' ) ) { + wp_enqueue_script( 'frontblocks-headline-marquee' ); + } + + return $block_content; } /** diff --git a/includes/Frontend/InsertPost.php b/includes/Frontend/InsertPost.php index 6fa3b73..675bceb 100644 --- a/includes/Frontend/InsertPost.php +++ b/includes/Frontend/InsertPost.php @@ -32,7 +32,7 @@ public function __construct() { * @return void */ private function init_hooks() { - add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), 99 ); + add_action( 'init', array( $this, 'register_scripts' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) ); add_action( 'wp_ajax_frbl_search_posts', array( $this, 'search_posts_callback' ) ); add_action( 'wp_ajax_nopriv_frbl_search_posts', array( $this, 'search_posts_callback' ) ); @@ -42,12 +42,12 @@ private function init_hooks() { } /** - * Enqueue scripts and styles. + * Register frontend scripts and styles for conditional enqueueing. * * @return void */ - public function enqueue_scripts() { - wp_enqueue_style( + public function register_scripts() { + wp_register_style( 'frontblocks-insert-post', FRBL_PLUGIN_URL . 'assets/insert-post/frontblocks-insert-post.css', array(), @@ -180,6 +180,11 @@ public function register_insert_post_block() { * @return string HTML output. */ public function render_insert_post_block( $attributes ) { + // Enqueue frontend styles only when this block is rendered. + if ( ! wp_style_is( 'frontblocks-insert-post', 'enqueued' ) ) { + wp_enqueue_style( 'frontblocks-insert-post' ); + } + $post_id = $attributes['selectedPostId'] ?? 0; if ( ! $post_id ) { diff --git a/includes/Frontend/ShapeAnimations.php b/includes/Frontend/ShapeAnimations.php index b3eb1c0..431aec0 100644 --- a/includes/Frontend/ShapeAnimations.php +++ b/includes/Frontend/ShapeAnimations.php @@ -34,27 +34,27 @@ public function __construct() { * @return void */ private function init_hooks() { - add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), 100 ); + add_action( 'init', array( $this, 'register_scripts' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ), 5 ); add_action( 'enqueue_block_editor_assets', array( $this, 'register_shape_animation_attributes' ), 15 ); add_filter( 'render_block', array( $this, 'add_animation_classes_to_shape' ), 10, 2 ); } /** - * Enqueue frontend scripts and styles. + * Register frontend scripts and styles for conditional enqueueing. * * @return void */ - public function enqueue_scripts() { - wp_enqueue_style( + public function register_scripts() { + wp_register_style( 'frontblocks-shape-animations', FRBL_PLUGIN_URL . 'assets/shape-animations/frontblocks-shape-animations.css', array(), FRBL_VERSION ); - // Enqueue Lottie library from CDN. - wp_enqueue_script( + // Register Lottie library from CDN. + wp_register_script( 'lottie-player', 'https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js', array(), @@ -62,7 +62,7 @@ public function enqueue_scripts() { true ); - wp_enqueue_script( + wp_register_script( 'frontblocks-shape-animations', FRBL_PLUGIN_URL . 'assets/shape-animations/frontblocks-shape-animations.js', array( 'lottie-player' ), @@ -183,6 +183,14 @@ public function add_animation_classes_to_shape( $block_content, $block ) { return $block_content; } + // Enqueue frontend assets only when a shape animation block is detected. + if ( ! wp_style_is( 'frontblocks-shape-animations', 'enqueued' ) ) { + wp_enqueue_style( 'frontblocks-shape-animations' ); + } + if ( ! wp_script_is( 'frontblocks-shape-animations', 'enqueued' ) ) { + wp_enqueue_script( 'frontblocks-shape-animations' ); + } + // Parse JSON data. $json_data = json_decode( $attrs['frblCustomSvgAnimationJson'], true ); diff --git a/includes/Frontend/StickyColumn.php b/includes/Frontend/StickyColumn.php index 3afcd4d..99a2344 100644 --- a/includes/Frontend/StickyColumn.php +++ b/includes/Frontend/StickyColumn.php @@ -32,27 +32,26 @@ public function __construct() { * @return void */ private function init_hooks() { - add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), 99 ); + add_action( 'init', array( $this, 'register_scripts' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) ); add_filter( 'render_block_generateblocks/grid', array( $this, 'add_sticky_attributes_to_grid_block' ), 10, 2 ); add_action( 'init', array( $this, 'register_custom_attributes' ), 5 ); } /** - * Enqueue scripts and styles. + * Register frontend scripts and styles for conditional enqueueing. * * @return void */ - public function enqueue_scripts() { - - wp_enqueue_style( + public function register_scripts() { + wp_register_style( 'frontblocks-sticky-column', FRBL_PLUGIN_URL . 'assets/sticky-column/frontblocks-sticky-column.css', array(), FRBL_VERSION ); - wp_enqueue_script( + wp_register_script( 'frontblocks-sticky-column-custom', FRBL_PLUGIN_URL . 'assets/sticky-column/frontblocks-sticky-column.js', array(), @@ -107,6 +106,14 @@ public function add_sticky_attributes_to_grid_block( $block_content, $block ) { $block_content, 1 // Only replace the first occurrence. ); + + // Enqueue frontend assets only when a sticky column block is detected. + if ( ! wp_style_is( 'frontblocks-sticky-column', 'enqueued' ) ) { + wp_enqueue_style( 'frontblocks-sticky-column' ); + } + if ( ! wp_script_is( 'frontblocks-sticky-column-custom', 'enqueued' ) ) { + wp_enqueue_script( 'frontblocks-sticky-column-custom' ); + } } return $block_content; diff --git a/includes/Plugin_Main.php b/includes/Plugin_Main.php index fdfab19..58b0dc1 100644 --- a/includes/Plugin_Main.php +++ b/includes/Plugin_Main.php @@ -54,8 +54,10 @@ private function init() { // Load modules. $this->load_modules(); - // General enqueue scripts. - add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), 99 ); + // Register scripts for conditional enqueueing. + add_action( 'init', array( $this, 'register_scripts' ) ); + // Conditionally enqueue accordion script when an accordion block is rendered. + add_filter( 'render_block', array( $this, 'maybe_enqueue_accordion_script' ), 10, 2 ); } /** @@ -135,36 +137,36 @@ private function load_modules() { } /** - * Enqueue scripts. + * Register scripts for conditional enqueueing. * * @return void */ - public function enqueue_scripts() { - wp_enqueue_style( + public function register_scripts() { + wp_register_style( 'frontblocks-carousel', FRBL_PLUGIN_URL . 'assets/carousel/frontblocks-carousel.css', array(), FRBL_VERSION ); - wp_enqueue_script( - 'frontblocks-carousel-custom', - FRBL_PLUGIN_URL . 'assets/carousel/frontblocks-carousel.js', - array( 'frontblocks-carousel' ), + wp_register_script( + 'frontblocks-carousel', + FRBL_PLUGIN_URL . 'assets/carousel/glide.min.js', + array(), FRBL_VERSION, true ); - wp_enqueue_script( - 'frontblocks-carousel', - FRBL_PLUGIN_URL . 'assets/carousel/glide.min.js', - array(), + wp_register_script( + 'frontblocks-carousel-custom', + FRBL_PLUGIN_URL . 'assets/carousel/frontblocks-carousel.js', + array( 'frontblocks-carousel' ), FRBL_VERSION, true ); - // GenerateBlocks Accordion fix – ensures accordions work when FrontBlocks is active. - wp_enqueue_script( + // GenerateBlocks Accordion fix – registers script for conditional enqueueing. + wp_register_script( 'frontblocks-accordion', FRBL_PLUGIN_URL . 'assets/accordion/frontblocks-accordion.js', array(), @@ -172,4 +174,25 @@ public function enqueue_scripts() { true ); } + + /** + * Enqueue accordion script only when an accordion block is present on the page. + * + * @param string $block_content Block content. + * @param array $block Block data. + * @return string + */ + public function maybe_enqueue_accordion_script( $block_content, $block ) { + if ( ! isset( $block['blockName'] ) ) { + return $block_content; + } + + if ( false !== strpos( $block['blockName'], 'accordion' ) ) { + if ( ! wp_script_is( 'frontblocks-accordion', 'enqueued' ) ) { + wp_enqueue_script( 'frontblocks-accordion' ); + } + } + + return $block_content; + } }