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;
}
}