start_controls_section( 'section_content', [ 'label' => __( 'Breadcrumbs', 'admore-widgets-suite' ), ] ); $this->add_control( 'home_text', [ 'label' => __( 'Home Label', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::TEXT, 'default' => __( 'Home', 'admore-widgets-suite' ), ] ); $this->add_control( 'separator_type', [ 'label' => __( 'Separator Type', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => 'text', 'options' => [ 'text' => __( 'Text / Character', 'admore-widgets-suite' ), 'icon' => __( 'Icon', 'admore-widgets-suite' ), ], ] ); $this->add_control( 'separator', [ 'label' => __( 'Separator', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::TEXT, 'default' => '/', 'condition' => [ 'separator_type' => 'text' ], ] ); $this->add_control( 'separator_icon', [ 'label' => __( 'Separator Icon', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::ICONS, 'default' => [ 'value' => 'fas fa-chevron-right', 'library' => 'fa-solid' ], 'condition' => [ 'separator_type' => 'icon' ], ] ); $this->add_control( 'show_home', [ 'label' => __( 'Show Home Link', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'label_on' => __( 'Yes', 'admore-widgets-suite' ), 'label_off' => __( 'No', 'admore-widgets-suite' ), 'return_value' => 'yes', 'default' => 'yes', ] ); $this->add_control( 'home_icon', [ 'label' => __( 'Home Icon', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::ICONS, 'condition' => [ 'show_home' => 'yes' ], ] ); $this->add_control( 'show_current', [ 'label' => __( 'Show Current Page', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'label_on' => __( 'Yes', 'admore-widgets-suite' ), 'label_off' => __( 'No', 'admore-widgets-suite' ), 'return_value' => 'yes', 'default' => 'yes', ] ); $this->add_control( 'enable_jsonld', [ 'label' => __( 'JSON-LD Schema', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'default' => 'yes', 'return_value' => 'yes', 'description' => __( 'Output structured data for SEO.', 'admore-widgets-suite' ), 'separator' => 'before', ] ); $this->add_responsive_control( 'alignment', [ 'label' => __( 'Alignment', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::CHOOSE, 'options' => [ 'left' => [ 'title' => __( 'Left', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-left' ], 'center' => [ 'title' => __( 'Center', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-center' ], 'right' => [ 'title' => __( 'Right', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-right' ], ], 'default' => 'center', 'selectors' => [ '{{WRAPPER}} .eppro-breadcrumbs' => 'justify-content: {{VALUE}};' ], ] ); $this->end_controls_section(); /* ── Wrapper ── */ $this->start_controls_section( 'section_style_wrapper', [ 'label' => __( 'Wrapper', 'admore-widgets-suite' ), 'tab' => \Elementor\Controls_Manager::TAB_STYLE, ] ); $this->add_group_control( \Elementor\Group_Control_Background::get_type(), [ 'name' => 'wrapper_bg', 'selector' => '{{WRAPPER}} .eppro-breadcrumbs-wrap', ] ); $this->add_responsive_control( 'wrapper_padding', [ 'label' => __( 'Padding', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', 'em' ], 'selectors' => [ '{{WRAPPER}} .eppro-breadcrumbs-wrap' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], ] ); $this->add_responsive_control( 'wrapper_border_radius', [ 'label' => __( 'Border Radius', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%' ], 'selectors' => [ '{{WRAPPER}} .eppro-breadcrumbs-wrap' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ], ] ); $this->end_controls_section(); /* ── Typography ── */ $this->start_controls_section( 'section_style_text', [ 'label' => __( 'Typography & Color', 'admore-widgets-suite' ), 'tab' => \Elementor\Controls_Manager::TAB_STYLE, ] ); $this->add_group_control( \Elementor\Group_Control_Typography::get_type(), [ 'name' => 'crumb_typography', 'selector' => '{{WRAPPER}} .eppro-breadcrumbs', ] ); $this->add_control( 'link_color', [ 'label' => __( 'Link Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-breadcrumb-link' => 'color: {{VALUE}};' ], ] ); $this->add_control( 'link_hover_color', [ 'label' => __( 'Link Hover Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-breadcrumb-link:hover' => 'color: {{VALUE}};' ], ] ); $this->add_control( 'current_color', [ 'label' => __( 'Current Page Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-breadcrumb-current' => 'color: {{VALUE}};' ], ] ); $this->add_control( 'separator_color', [ 'label' => __( 'Separator Color', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-breadcrumb-sep' => 'color: {{VALUE}};' ], ] ); $this->add_responsive_control( 'item_gap', [ 'label' => __( 'Item Gap', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'range' => [ 'px' => [ 'min' => 0, 'max' => 32 ] ], 'default' => [ 'size' => 8, 'unit' => 'px' ], 'selectors' => [ '{{WRAPPER}} .eppro-breadcrumbs' => 'gap: {{SIZE}}{{UNIT}};' ], ] ); $this->add_responsive_control( 'separator_size', [ 'label' => __( 'Separator Size', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 6, 'max' => 32 ] ], 'selectors' => [ '{{WRAPPER}} .eppro-breadcrumb-sep i' => 'font-size: {{SIZE}}{{UNIT}};', '{{WRAPPER}} .eppro-breadcrumb-sep svg' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};', '{{WRAPPER}} .eppro-breadcrumb-sep' => 'font-size: {{SIZE}}{{UNIT}};', ], 'separator' => 'before', ] ); $this->add_responsive_control( 'home_icon_size', [ 'label' => __( 'Home Icon Size', 'admore-widgets-suite' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'size_units' => [ 'px' ], 'range' => [ 'px' => [ 'min' => 10, 'max' => 40 ] ], 'selectors' => [ '{{WRAPPER}} .eppro-breadcrumb-home-icon i' => 'font-size: {{SIZE}}{{UNIT}};', '{{WRAPPER}} .eppro-breadcrumb-home-icon svg' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};', ], ] ); $this->end_controls_section(); // Entrance animation — inherited from base $this->eppro_register_entrance_animation_controls(); } // ------------------------------------------------------------------------- // Render // ------------------------------------------------------------------------- protected function render(): void { $s = $this->get_settings_for_display(); $show_home = 'yes' === ( $s['show_home'] ?? 'yes' ); $show_current = 'yes' === ( $s['show_current'] ?? 'yes' ); $sep_type = $s['separator_type'] ?? 'text'; $separator = $s['separator'] ? esc_html( $s['separator'] ) : '/'; $home_text = $s['home_text'] ? esc_html( $s['home_text'] ) : esc_html__( 'Home', 'admore-widgets-suite' ); $has_home_icon = ! empty( $s['home_icon']['value'] ); $enable_jsonld = 'yes' === ( $s['enable_jsonld'] ?? 'yes' ); $crumbs = self::build_crumbs(); if ( empty( $crumbs ) ) { if ( \Elementor\Plugin::$instance->editor->is_edit_mode() ) { $sep = $s['separator'] ?: '/'; echo ''; } return; } ?> 'ListItem', 'position' => $pos++, 'name' => $item['label'], 'item' => $item['url'] ?? '', ]; } $jsonld = wp_json_encode( [ '@context' => 'https://schema.org', '@type' => 'BreadcrumbList', 'itemListElement' => $schema_items, ], JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT ); $handle = 'eppro-breadcrumbs-jsonld'; wp_register_script( $handle, false, [], EPPRO_VERSION, true ); wp_enqueue_script( $handle ); wp_add_inline_script( $handle, 'var _eppBreadcrumbSchema=document.createElement("script");_eppBreadcrumbSchema.type="application/ld+json";_eppBreadcrumbSchema.text=' . $jsonld . ';document.head.appendChild(_eppBreadcrumbSchema);' ); endif; ?> post_type ); if ( $pt_obj && $pt_obj->has_archive && 'post' !== $post->post_type ) { $archive_link = get_post_type_archive_link( $post->post_type ); if ( $archive_link ) { $crumbs[] = [ 'url' => $archive_link, 'label' => $pt_obj->labels->name, 'current' => false, ]; } } // Taxonomies (categories, custom taxonomies) $taxonomies = get_object_taxonomies( $post->post_type, 'objects' ); foreach ( $taxonomies as $tax ) { if ( ! $tax->hierarchical && 'category' !== $tax->name ) continue; $terms = get_the_terms( $post->ID, $tax->name ); if ( $terms && ! is_wp_error( $terms ) ) { $term = $terms[0]; // Walk up ancestors $chain = []; $tid = $term->term_id; while ( $tid ) { $t = get_term( $tid, $tax->name ); if ( ! $t || is_wp_error( $t ) ) break; array_unshift( $chain, $t ); $tid = $t->parent; } foreach ( $chain as $t ) { $crumbs[] = [ 'url' => get_term_link( $t ), 'label' => $t->name, 'current' => false, ]; } break; } } // Current post $crumbs[] = [ 'url' => get_permalink( $post->ID ), 'label' => get_the_title( $post->ID ), 'current' => true, ]; } elseif ( is_archive() ) { if ( is_category() || is_tag() || is_tax() ) { $term = get_queried_object(); if ( $term instanceof WP_Term ) { $crumbs[] = [ 'url' => get_term_link( $term ), 'label' => $term->name, 'current' => true ]; } } elseif ( is_post_type_archive() ) { $pt = get_queried_object(); $lbl = ( $pt instanceof WP_Post_Type ) ? $pt->labels->name : ''; $crumbs[] = [ 'url' => get_post_type_archive_link( $pt->name ?? '' ) ?: '#', 'label' => $lbl, 'current' => true ]; } elseif ( is_date() ) { $crumbs[] = [ 'url' => '#', 'label' => get_the_date(), 'current' => true ]; } elseif ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User ) { $crumbs[] = [ 'url' => get_author_posts_url( $author->ID ), 'label' => $author->display_name, 'current' => true ]; } } } elseif ( is_search() ) { $crumbs[] = [ 'url' => '#', /* translators: %s: search query string */ 'label' => sprintf( __( 'Search: %s', 'admore-widgets-suite' ), get_search_query() ), 'current' => true, ]; } elseif ( is_404() ) { $crumbs[] = [ 'url' => '#', 'label' => __( '404 – Not Found', 'admore-widgets-suite' ), 'current' => true ]; } elseif ( is_page() ) { $page = get_queried_object(); if ( $page instanceof WP_Post ) { // Walk up parent pages $chain = []; $pid = $page->post_parent; while ( $pid ) { $p = get_post( $pid ); if ( ! $p ) break; array_unshift( $chain, $p ); $pid = $p->post_parent; } foreach ( $chain as $p ) { $crumbs[] = [ 'url' => get_permalink( $p->ID ), 'label' => get_the_title( $p->ID ), 'current' => false, ]; } $crumbs[] = [ 'url' => get_permalink( $page->ID ), 'label' => get_the_title( $page->ID ), 'current' => true, ]; } } return $crumbs; } }