*
Tab 1 Label
*
Tab 1 content here...
* *
*
Tab 2 Label
*
Tab 2 content here...
*
* [/tabbed_content] * * * NOTES * - First tab is active by default * - Supports nested shortcodes * - Only one panel visible at a time */ add_shortcode( 'tabbed_content', function ( $atts, $content = null ) { static $instance = 0; ++$instance; static $script_enqueued = false; if ( ! $script_enqueued ) { wp_register_script( 'bld-tabbed-content', '', [], false, true ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NoExplicitVersion wp_enqueue_script( 'bld-tabbed-content' ); $script_enqueued = true; } $atts = shortcode_atts( [ 'active' => 0, // Default to first tab ], $atts, 'tabbed_content' ); $active_index = absint( $atts['active'] ); $content = do_shortcode( $content ); $prev = libxml_use_internal_errors( true ); $doc = new DOMDocument(); $doc->loadHTML( '
' . $content . '
' ); libxml_clear_errors(); libxml_use_internal_errors( $prev ); $xpath = new DOMXPath( $doc ); $containers = $xpath->query( '//*[@id="wrapper"]/div' ); $labels = []; $contents = []; foreach ( $containers as $container ) { $children = []; foreach ( $container->childNodes as $child ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase if ( XML_ELEMENT_NODE === $child->nodeType && 'div' === $child->tagName ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase $children[] = $child; } } if ( count( $children ) < 2 ) { continue; } $label_text = trim( $children[0]->textContent ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase $content_html = ''; foreach ( $children[1]->childNodes as $node ) { $content_html .= $doc->saveHTML( $node ); } $labels[] = esc_html( $label_text ); $contents[] = wp_kses_post( $content_html ); } if ( empty( $labels ) ) { return ''; } $output = '
'; // Tabs $output .= '
'; foreach ( $labels as $i => $label ) { $tab_id = 'tab-label-' . $instance . '-' . $i; $panel_id = 'tab-panel-' . $instance . '-' . $i; $active = ( $active_index === $i ); $output .= ''; } $output .= '
'; // Panels $output .= '
'; foreach ( $contents as $i => $html ) { $panel_id = 'tab-panel-' . $instance . '-' . $i; $tab_id = 'tab-label-' . $instance . '-' . $i; $active = ( $active_index === $i ); $output .= '
' . $html . '
'; } $output .= '
'; ob_start(); ?>