features = $features; } public function register(): void { add_shortcode( 'acez_seo_breadcrumbs', array( $this, 'render' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue_styles' ) ); } /** * Lazy-loads the breadcrumb CSS only when the shortcode is actually used * in the post content. Note: shortcodes placed directly in a theme * template (via do_shortcode()) aren't detected this way — the trail * still renders, just without this stylesheet. */ public function maybe_enqueue_styles(): void { if ( ! $this->features->enabled( 'breadcrumbs' ) || ! is_singular() ) { return; } $post = get_queried_object(); if ( ! ( $post instanceof \WP_Post ) || ! has_shortcode( $post->post_content, 'acez_seo_breadcrumbs' ) ) { return; } wp_enqueue_style( 'acez-seo-breadcrumbs', ACEZ_SEO_URL . 'assets/css/breadcrumbs.css', array(), ACEZ_SEO_VERSION ); } public function render(): string { // Shortcode stays registered even when the feature is off, so a // literal "[acez_seo_breadcrumbs]" never leaks into the page — it // just renders nothing. if ( ! $this->features->enabled( 'breadcrumbs' ) || ! is_singular() ) { return ''; } $post = get_queried_object(); if ( ! ( $post instanceof \WP_Post ) ) { return ''; } $items = BreadcrumbTrail::items( $post ); if ( array() === $items ) { return ''; } $last_index = count( $items ) - 1; $html = ''; return $html; } }