renderer = $renderer; } /** * Register hooks. * * @return void */ public function register() { add_action( 'init', array( $this, 'register_block' ) ); } /** * Register the editor script and the block. * * @return void */ public function register_block() { $dir = ACCORDION_FAQ_PATH . 'blocks/faq'; if ( ! is_readable( $dir . '/block.json' ) ) { return; } $js = $dir . '/index.js'; wp_register_script( self::HANDLE, ACCORDION_FAQ_URL . 'blocks/faq/index.js', array( 'wp-blocks', 'wp-element', 'wp-block-editor', 'wp-components', 'wp-server-side-render', 'wp-i18n', 'wp-api-fetch' ), is_readable( $js ) ? (string) filemtime( $js ) : ACCORDION_FAQ_VERSION, true ); wp_localize_script( self::HANDLE, 'AccordionFaqBlock', array( 'categories' => $this->category_options(), 'aiEnabled' => \AccordionFaq\Support\Options::boolean( 'enable_ai' ), 'generateRoute' => '/' . \AccordionFaq\Rest\Controller::NS . '/generate', 'restBase' => 'quick_faq', 'taxRestBase' => Taxonomy::TAXONOMY, 'canCreate' => current_user_can( 'publish_posts' ), ) ); // Register the frontend stylesheet + script so the block loads them via // WordPress core's block-asset mechanism (reliable regardless of render // timing), styled in the editor preview, and only when the block present. $css = ACCORDION_FAQ_PATH . 'assets/css/accordion-faq.css'; $view_js = ACCORDION_FAQ_PATH . 'assets/js/accordion-faq.js'; if ( ! wp_style_is( \AccordionFaq\Frontend\Assets::HANDLE, 'registered' ) ) { wp_register_style( \AccordionFaq\Frontend\Assets::HANDLE, ACCORDION_FAQ_URL . 'assets/css/accordion-faq.css', array(), is_readable( $css ) ? (string) filemtime( $css ) : ACCORDION_FAQ_VERSION ); } if ( ! wp_script_is( \AccordionFaq\Frontend\Assets::HANDLE, 'registered' ) ) { wp_register_script( \AccordionFaq\Frontend\Assets::HANDLE, ACCORDION_FAQ_URL . 'assets/js/accordion-faq.js', array(), is_readable( $view_js ) ? (string) filemtime( $view_js ) : ACCORDION_FAQ_VERSION, true ); \AccordionFaq\Frontend\Assets::localize( \AccordionFaq\Frontend\Assets::HANDLE ); } register_block_type( $dir, array( 'editor_script' => self::HANDLE, 'style' => \AccordionFaq\Frontend\Assets::HANDLE, 'editor_style' => \AccordionFaq\Frontend\Assets::HANDLE, 'view_script' => \AccordionFaq\Frontend\Assets::HANDLE, 'render_callback' => array( $this, 'render' ), ) ); } /** * Provide FAQ categories for the editor Inspector. * * @return array[] */ private function category_options() { $terms = get_terms( array( 'taxonomy' => Taxonomy::TAXONOMY, 'hide_empty' => false, ) ); $out = array(); if ( ! is_wp_error( $terms ) ) { foreach ( $terms as $term ) { $out[] = array( 'id' => (int) $term->term_id, 'slug' => $term->slug, 'name' => $term->name, ); } } return $out; } /** * Server-side render callback. * * @param array $attributes Block attributes. * @return string */ public function render( $attributes ) { $attributes = is_array( $attributes ) ? $attributes : array(); $raw = array( 'term' => isset( $attributes['term'] ) ? absint( $attributes['term'] ) : 0, 'category' => isset( $attributes['category'] ) ? $attributes['category'] : '', 'style' => isset( $attributes['style'] ) ? $attributes['style'] : '', 'mode' => isset( $attributes['mode'] ) ? $attributes['mode'] : '', 'engine' => isset( $attributes['engine'] ) ? $attributes['engine'] : '', 'heading' => isset( $attributes['heading'] ) ? $attributes['heading'] : '', 'icon' => isset( $attributes['icon'] ) ? $attributes['icon'] : '', 'orderby' => isset( $attributes['orderby'] ) ? $attributes['orderby'] : 'date', 'order' => isset( $attributes['order'] ) ? $attributes['order'] : 'ASC', 'limit' => isset( $attributes['limit'] ) ? (int) $attributes['limit'] : -1, 'open_first' => ! empty( $attributes['openFirst'] ), 'search' => ! empty( $attributes['search'] ), 'filter' => ! empty( $attributes['filter'] ), 'expand_all' => ! empty( $attributes['expandAll'] ), 'toc' => ! empty( $attributes['toc'] ), 'schema' => isset( $attributes['schema'] ) ? (bool) $attributes['schema'] : true, ); // Drop empty string overrides so settings defaults apply. foreach ( array( 'style', 'mode', 'engine', 'heading', 'icon' ) as $key ) { if ( '' === $raw[ $key ] ) { unset( $raw[ $key ] ); } } $html = $this->renderer->render( $raw ); if ( '' === $html ) { if ( function_exists( 'wp_is_block_theme' ) && is_admin() ) { return '
' . esc_html__( 'No FAQs found for the selected options.', 'accordion-faq-plugin' ) . '
'; } return ''; } $wrapper = function_exists( 'get_block_wrapper_attributes' ) ? get_block_wrapper_attributes() : ''; return '