cache = Cache::for('faq_block', WEEK_IN_SECONDS)->connect('post', true)->connect('taxonomy', true); add_action('init', [ $this, 'registerBlock' ]); add_action('enqueue_block_editor_assets', [$this, 'localizeData']); } /** * Register the FAQ block */ public function registerBlock() { // Register the block register_block_type( JVB_DIR . '/build/faq', [ 'render_callback' => [$this, 'render'], ] ); // // // Localize script data for the editor // add_action('enqueue_block_editor_assets', [$this, 'enqueue_editor_assets']); // // // Enqueue frontend scripts // add_action('wp_enqueue_scripts', [$this, 'enqueue_frontend_assets']); } /** * Enqueue editor assets */ public static function enqueue_editor_assets() { // Pass section taxonomy name to JavaScript wp_localize_script( 'jvb-faq-editor-script', 'jvbFaq', [ 'sectionTaxonomy' => BASE . 'section', 'faqPostType' => BASE . 'faq', ] ); } /** * Enqueue frontend assets */ public static function enqueue_frontend_assets() { // Check if block is being used on this page if (has_block('jvb/faq')) { wp_enqueue_script( 'jvb-faq-view', JVB_URL . '/build/faq/view.js', [], filemtime(JVB_DIR . '/build/faq/view.js'), true ); } } /** * Localize forms data for block editor */ public function localizeData(): void { // Get all sections $section_taxonomy = BASE . 'section'; $sections_data = $this->cache->remember( 'sections', function() { $sections = get_terms([ 'taxonomy' => BASE.'section', 'hide_empty' => false, 'orderby' => 'name', 'order' => 'ASC', ]); // Format sections for JavaScript $sections_data = []; if (!is_wp_error($sections) && !empty($sections)) { foreach ($sections as $term) { $sections_data[] = [ 'id' => $term->term_id, 'name' => html_entity_decode($term->name), 'slug' => $term->slug, ]; } } return $sections_data; } ); // Pass section taxonomy name and sections to JavaScript wp_localize_script( 'jvb-faq-editor-script', 'jvbFaq', [ 'sectionTaxonomy' => $section_taxonomy, 'faqPostType' => BASE . 'faq', 'sections' => $sections_data, ] ); } /** * Render callback * * @param array $attributes Block attributes * @param string $content Block content * @param WP_Block $block Block instance * @return string Rendered block HTML */ public function render($attributes, $content, $block) { ob_start(); ?> $faq_post_type, 'posts_per_page' => -1, 'post_status' => 'publish', 'orderby' => 'menu_order title', 'order' => 'ASC', ]; // Get FAQs $faq_query = new WP_Query($query_args); } if (!$faq_query->have_posts()) { echo '
'; echo '

' . esc_html__('No FAQs found.', 'jvb') . '

'; echo '
'; return; } // Organize FAQs by section $faqs_by_section = []; while ($faq_query->have_posts()) { $faq_query->the_post(); $post_id = get_the_ID(); $terms = get_the_terms($post_id, $section_taxonomy); if ($terms && !is_wp_error($terms)) { foreach ($terms as $term) { if (!isset($faqs_by_section[$term->term_id])) { $faqs_by_section[$term->term_id] = [ 'term' => $term, 'faqs' => [], ]; } $faqs_by_section[$term->term_id]['faqs'][] = [ 'id' => $post_id, 'title' => get_the_title(), 'content' => get_the_excerpt(), 'url' => get_the_permalink(), ]; } } else { // FAQ without section - add to "uncategorized" if (!isset($faqs_by_section[0])) { $faqs_by_section[0] = [ 'term' => (object) [ 'term_id' => 0, 'name' => __('General', 'jvb'), 'slug' => 'general', ], 'faqs' => [], ]; } $faqs_by_section[0]['faqs'][] = [ 'id' => $post_id, 'title' => get_the_title(), 'content' => get_the_excerpt(), 'url' => get_the_permalink(), ]; } } wp_reset_postdata(); // If on main FAQ archive and we have a custom order, apply it if (!$is_tax_archive && !empty($section_order)) { $ordered_sections = []; // Add sections in custom order foreach ($section_order as $term_id) { if (isset($faqs_by_section[$term_id])) { $ordered_sections[$term_id] = $faqs_by_section[$term_id]; } } // Add any sections not in the custom order at the end foreach ($faqs_by_section as $term_id => $section_data) { if (!isset($ordered_sections[$term_id])) { $ordered_sections[$term_id] = $section_data; } } $faqs_by_section = $ordered_sections; } // Generate unique IDs for accordion functionality $block_id = 'faq-block-' . wp_unique_id(); // Render the block $wrapper_attributes = get_block_wrapper_attributes([ 'class' => 'faq-block', 'data-block-id' => $block_id, ]); $nav = ''; if (!empty($section_order)) { $nav = ''; } ?>
> $section_data): ?>

name); ?>

$faq): ?>
>

Q

Learn More