Skip to content

Commit f5114f3

Browse files
committed
Updated breadcrumbs handling for product
1 parent 3cb5fda commit f5114f3

File tree

1 file changed

+116
-64
lines changed

1 file changed

+116
-64
lines changed

includes/frontend/class-breadcrumbs.php

Lines changed: 116 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,45 @@ private static function unicode_to_char( $unicode ) {
3434
return html_entity_decode( '&#x' . $unicode . ';', ENT_COMPAT, 'UTF-8' );
3535
}
3636

37+
/**
38+
* Get the product term for the current context.
39+
*
40+
* @return \WP_Term|false
41+
*/
42+
private static function get_product_for_context() {
43+
if ( is_tax( 'wzkb_category' ) || is_tax( 'wzkb_tag' ) ) {
44+
$tax = get_queried_object();
45+
if ( $tax && isset( $tax->term_id ) ) {
46+
$product_id = get_term_meta( $tax->term_id, 'product_id', true );
47+
if ( $product_id ) {
48+
$product = get_term( $product_id, 'wzkb_product' );
49+
if ( $product && ! is_wp_error( $product ) ) {
50+
return $product;
51+
}
52+
}
53+
}
54+
}
55+
if ( is_singular( 'wz_knowledgebase' ) ) {
56+
$post = get_queried_object();
57+
$terms = get_the_terms( $post, 'wzkb_category' );
58+
if ( is_array( $terms ) && ! empty( $terms ) ) {
59+
$primary_term = $terms[0];
60+
$ancestor = $primary_term;
61+
while ( $ancestor->parent ) {
62+
$ancestor = get_term( $ancestor->parent, $ancestor->taxonomy );
63+
}
64+
$product_id = get_term_meta( $ancestor->term_id, 'product_id', true );
65+
if ( $product_id ) {
66+
$product = get_term( $product_id, 'wzkb_product' );
67+
if ( $product && ! is_wp_error( $product ) ) {
68+
return $product;
69+
}
70+
}
71+
}
72+
}
73+
return false;
74+
}
75+
3776
/**
3877
* Creates the breadcrumb.
3978
*
@@ -48,15 +87,12 @@ public static function get_breadcrumb( $args = array() ) {
4887
'separator' => '»',
4988
);
5089

51-
// Parse incoming $args into an array and merge it with $defaults.
5290
$args = wp_parse_args( $args, $defaults );
5391

54-
// Convert Unicode sequence if provided.
5592
if ( strpos( $args['separator'], '\\' ) === 0 ) {
5693
$args['separator'] = self::unicode_to_char( $args['separator'] );
5794
}
5895

59-
// Return if not a WZKB post type archive or single page.
6096
if ( ( ! is_admin() && ! wp_is_json_request() ) &&
6197
! is_post_type_archive( 'wz_knowledgebase' ) &&
6298
! is_singular( 'wz_knowledgebase' ) &&
@@ -66,95 +102,111 @@ public static function get_breadcrumb( $args = array() ) {
66102
return '';
67103
}
68104

69-
$output = '<nav class="wzkb_breadcrumb" aria-label="' . esc_attr__( 'Breadcrumb', 'knowledgebase' ) . '">';
70-
$output .= '<ol class="wzkb_breadcrumb-list" itemscope itemtype="https://schema.org/BreadcrumbList">';
105+
$items = array();
106+
$items[] = array(
107+
'url' => home_url(),
108+
'label' => esc_html__( 'Home', 'knowledgebase' ),
109+
'position' => 1,
110+
'current' => false,
111+
);
112+
$items[] = array(
113+
'url' => wzkb_get_kb_url(),
114+
'label' => esc_html( wzkb_get_option( 'kb_title' ) ),
115+
'position' => 2,
116+
'current' => false,
117+
);
118+
119+
$position = 3;
120+
if ( wzkb_get_option( 'multi_product' ) ) {
121+
$product = self::get_product_for_context();
122+
if ( $product ) {
123+
$items[] = array(
124+
'url' => get_term_link( $product ),
125+
'label' => esc_html( $product->name ),
126+
'position' => $position,
127+
'current' => false,
128+
);
129+
++$position;
130+
}
131+
}
71132

72-
// First output the link to home page.
73-
$output .= '<li class="wzkb_breadcrumb-item" data-separator="' . esc_attr( $args['separator'] ) . '" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
74-
$output .= '<a href="' . esc_url( home_url() ) . '" itemprop="item">';
75-
$output .= '<span itemprop="name">' . esc_html__( 'Home', 'knowledgebase' ) . '</span>';
76-
$output .= '</a>';
77-
$output .= '<meta itemprop="position" content="1" />';
78-
$output .= '</li>';
79-
80-
// Link to the knowledge base.
81-
$output .= '<li class="wzkb_breadcrumb-item" data-separator="' . esc_attr( $args['separator'] ) . '" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
82-
$output .= '<a href="' . esc_url( wzkb_get_kb_url() ) . '" itemprop="item">';
83-
$output .= '<span itemprop="name">' . esc_html( wzkb_get_option( 'kb_title' ) ) . '</span>';
84-
$output .= '</a>';
85-
$output .= '<meta itemprop="position" content="2" />';
86-
$output .= '</li>';
87-
88-
// Output the category or tag.
89133
if ( is_tax( 'wzkb_category' ) || is_tax( 'wzkb_tag' ) ) {
90-
$tax = get_queried_object();
91-
$output .= self::get_hierarchical_term_trail( $tax, $args, 3 );
134+
$tax = get_queried_object();
135+
$trail = self::get_hierarchical_term_trail_array( $tax, $args, $position );
136+
foreach ( $trail as $item ) {
137+
$items[] = $item;
138+
++$position;
139+
}
92140
}
93141

94-
// Output link to single post.
95142
if ( is_singular( 'wz_knowledgebase' ) ) {
96-
$post = get_queried_object();
97-
143+
$post = get_queried_object();
98144
$terms = get_the_terms( $post, 'wzkb_category' );
99145
if ( is_array( $terms ) && ! empty( $terms ) ) {
100-
$tax = $terms[0];
101-
$output .= self::get_hierarchical_term_trail( $tax, $args, 3 );
146+
$tax = $terms[0];
147+
$trail = self::get_hierarchical_term_trail_array( $tax, $args, $position );
148+
foreach ( $trail as $item ) {
149+
$items[] = $item;
150+
++$position;
151+
}
102152
}
153+
$items[] = array(
154+
'url' => get_permalink( $post ),
155+
'label' => esc_html( $post->post_title ),
156+
'position' => $position,
157+
'current' => true,
158+
);
159+
}
103160

104-
$output .= '<li class="wzkb_breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
105-
$output .= '<a href="' . esc_url( get_permalink( $post ) ) . '" itemprop="item">';
106-
$output .= '<span itemprop="name">' . esc_html( $post->post_title ) . '</span>';
161+
$items = apply_filters( 'wzkb_breadcrumb_items', $items, $args );
162+
163+
$output = '<nav class="wzkb_breadcrumb" aria-label="' . esc_attr__( 'Breadcrumb', 'knowledgebase' ) . '">';
164+
$output .= '<ol class="wzkb_breadcrumb-list" itemscope itemtype="https://schema.org/BreadcrumbList">';
165+
$sep = esc_attr( $args['separator'] );
166+
foreach ( $items as $item ) {
167+
$output .= '<li class="wzkb_breadcrumb-item" data-separator="' . $sep . '" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
168+
$output .= '<a href="' . esc_url( $item['url'] ) . '" itemprop="item"' . ( ! empty( $item['current'] ) ? ' aria-current="page"' : '' ) . '>';
169+
$output .= '<span itemprop="name">' . $item['label'] . '</span>';
107170
$output .= '</a>';
108-
$output .= '<meta itemprop="position" content="4" />';
171+
$output .= '<meta itemprop="position" content="' . intval( $item['position'] ) . '" />';
109172
$output .= '</li>';
110173
}
111-
112174
$output .= '</ol>';
113175
$output .= '</nav>';
114176

115-
/**
116-
* Filter the formatted shortcode output.
117-
*
118-
* @since 1.6.0
119-
*
120-
* @param string $output Formatted HTML output.
121-
* @param array $args Parameters array.
122-
*/
123177
return apply_filters( 'wzkb_get_breadcrumb', $output, $args );
124178
}
125179

126180
/**
127-
* Generates the HTML for the taxonomy and its children for the breadcrumb.
128-
*
129-
* @since 2.3.0
181+
* Returns the hierarchical term trail as an array of breadcrumb items.
130182
*
131183
* @param \WP_Term $taxonomy Taxonomy object.
132184
* @param array $args Parameters array.
133185
* @param int $position Current position in breadcrumb.
134-
* @return string HTML output.
186+
* @return array Array of breadcrumb items.
135187
*/
136-
private static function get_hierarchical_term_trail( \WP_Term $taxonomy, $args = array(), $position = 2 ) {
188+
private static function get_hierarchical_term_trail_array( \WP_Term $taxonomy, $args = array(), $position = 2 ) {
137189
$defaults = array(
138190
'separator' => '»',
139191
);
140-
141-
$args = wp_parse_args( $args, $defaults );
142-
143-
$output = '<li class="wzkb_breadcrumb-item" data-separator="' . esc_attr( $args['separator'] ) . '" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
144-
$output .= '<a href="' . esc_url( get_term_link( $taxonomy ) ) . '" itemprop="item" title="' . esc_attr( $taxonomy->name ) . '">';
145-
$output .= '<span itemprop="name">' . esc_html( $taxonomy->name ) . '</span>';
146-
$output .= '</a>';
147-
$output .= '<meta itemprop="position" content="' . intval( $position ) . '" />';
148-
$output .= '</li>';
149-
192+
$args = wp_parse_args( $args, $defaults );
193+
$trail = array();
150194
if ( ! empty( $taxonomy->parent ) ) {
151-
$output = self::get_hierarchical_term_trail(
152-
get_term( $taxonomy->parent, $taxonomy->taxonomy ),
153-
$args,
154-
$position - 1
155-
) . $output;
195+
$trail = array_merge(
196+
self::get_hierarchical_term_trail_array(
197+
get_term( $taxonomy->parent, $taxonomy->taxonomy ),
198+
$args,
199+
$position
200+
),
201+
);
202+
$position += count( $trail );
156203
}
157-
158-
return $output;
204+
$trail[] = array(
205+
'url' => get_term_link( $taxonomy ),
206+
'label' => esc_html( $taxonomy->name ),
207+
'position' => $position,
208+
'current' => false,
209+
);
210+
return $trail;
159211
}
160212
}

0 commit comments

Comments
 (0)