true] ); wp_register_script( 'texttweener-editor', TEXTTWEENER_PLUGIN_URL . 'assets/editor.js', ['wp-blocks', 'wp-block-editor', 'wp-components', 'wp-element', 'wp-i18n'], TEXTTWEENER_VERSION, ['in_footer' => true] ); wp_register_style( 'texttweener-editor-style', TEXTTWEENER_PLUGIN_URL . 'assets/editor.css', [], TEXTTWEENER_VERSION ); register_block_type(TEXTTWEENER_PLUGIN_DIR . 'block.json', [ 'render_callback' => 'texttweener_render_block', ]); } add_action('init', 'texttweener_register_block'); /** * Server-side render callback for the TextTweener block. * * @param array $attributes Block attributes. * @return string Block HTML output. */ function texttweener_render_block(array $attributes): string { $texts = $attributes['texts'] ?? []; if (count($texts) < 2) { return ''; } $block_id = 'texttweener-' . wp_unique_id(); $duration = (int) ($attributes['duration'] ?? 4000); $transition_duration = (int) ($attributes['transitionDuration'] ?? 800); $stagger = (int) ($attributes['stagger'] ?? 15); $easing = sanitize_text_field($attributes['easing'] ?? 'cubic-bezier(0.16, 1, 0.3, 1)'); $text_align = sanitize_text_field($attributes['textAlign'] ?? 'left'); $font_size = (int) ($attributes['fontSize'] ?? 32); $loop = (bool) ($attributes['loop'] ?? true); // Build text spans (fallback for no-JS) $spans = ''; foreach ($texts as $index => $text) { $escaped = esc_html((string) $text); $hidden = $index > 0 ? ' style="display:none"' : ''; $spans .= sprintf('%s', $hidden, $escaped); } // Sanitize texts for JS $js_texts = wp_json_encode(array_map('sanitize_text_field', $texts)); // Add initialization via wp_add_inline_script (no inline