| @@ -100,11 +100,10 @@ | ||
| 100 | 100 | protected function filter( $output ) { |
| 101 | 101 | /** |
| 102 | 102 | * Filter: 'wpseo_breadcrumb_output' - Allow changing the HTML output of the Yoast SEO breadcrumbs class. |
| 103 | 103 | * |
| 104 | + * @param string $output The HTML output. | |
| 104 | 105 | * @param Indexable_Presentation $presentation The presentation of an indexable. |
| 105 | - * | |
| 106 | - * @api string $output The HTML output. | |
| 107 | 106 | */ |
| 108 | 107 | return \apply_filters( 'wpseo_breadcrumb_output', $output, $this->presentation ); |
| 109 | 108 | } |
| 110 | 109 | |
| @@ -137,35 +136,35 @@ | ||
| 137 | 136 | ) { |
| 138 | 137 | // If it's not the last element and we have a url. |
| 139 | 138 | $link .= '<' . $this->get_element() . '>'; |
| 140 | 139 | $title_attr = isset( $breadcrumb['title'] ) ? ' title="' . \esc_attr( $breadcrumb['title'] ) . '"' : ''; |
| 141 | - $link .= '<a href="' . \esc_url( $breadcrumb['url'] ) . '"' . $title_attr . '>' . $text . '</a>'; | |
| 140 | + $link .= '<a'; | |
| 141 | + | |
| 142 | + if ( $this->should_link_target_blank() ) { | |
| 143 | + $link .= ' target="_blank"'; | |
| 144 | + } | |
| 145 | + $link .= ' href="' . \esc_url( $breadcrumb['url'] ) . '"' . $title_attr . '>' . $text . '</a>'; | |
| 146 | + $link .= '</' . $this->get_element() . '>'; | |
| 142 | 147 | } |
| 143 | 148 | elseif ( $index === ( $total - 1 ) ) { |
| 144 | 149 | // If it's the last element. |
| 145 | - $inner_elm = 'span'; | |
| 150 | + | |
| 146 | 151 | if ( $this->helpers->options->get( 'breadcrumbs-boldlast' ) === true ) { |
| 147 | - $inner_elm = 'strong'; | |
| 152 | + $text = '<strong>' . $text . '</strong>'; | |
| 148 | 153 | } |
| 149 | 154 | |
| 150 | - $link .= '<' . $inner_elm . ' class="breadcrumb_last" aria-current="page">' . $text . '</' . $inner_elm . '>'; | |
| 151 | - // This is the last element, now close all previous elements. | |
| 152 | - while ( $index > 0 ) { | |
| 153 | - $link .= '</' . $this->get_element() . '>'; | |
| 154 | - --$index; | |
| 155 | - } | |
| 155 | + $link .= '<' . $this->get_element() . ' class="breadcrumb_last" aria-current="page">' . $text . '</' . $this->get_element() . '>'; | |
| 156 | 156 | } |
| 157 | 157 | else { |
| 158 | 158 | // It's not the last element and has no url. |
| 159 | - $link .= '<span>' . $text . '</span>'; | |
| 159 | + $link .= '<' . $this->get_element() . '>' . $text . '</' . $this->get_element() . '>'; | |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | 162 | /** |
| 163 | 163 | * Filter: 'wpseo_breadcrumb_single_link' - Allow changing of each link being put out by the Yoast SEO breadcrumbs class. |
| 164 | 164 | * |
| 165 | - * @param array $link The link array. | |
| 166 | - * | |
| 167 | - * @api string $link_output The output string. | |
| 165 | + * @param string $link_output The output string. | |
| 166 | + * @param array $link The breadcrumb link array. | |
| 168 | 167 | */ |
| 169 | 168 | return \apply_filters( 'wpseo_breadcrumb_single_link', $link, $breadcrumb ); |
| 170 | 169 | } |
| 171 | 170 | |
| @@ -178,9 +177,9 @@ | ||
| 178 | 177 | if ( ! $this->id ) { |
| 179 | 178 | /** |
| 180 | 179 | * Filter: 'wpseo_breadcrumb_output_id' - Allow changing the HTML ID on the Yoast SEO breadcrumbs wrapper element. |
| 181 | 180 | * |
| 182 | - * @api string $unsigned ID to add to the wrapper element. | |
| 181 | + * @param string $unsigned ID to add to the wrapper element. | |
| 183 | 182 | */ |
| 184 | 183 | $this->id = \apply_filters( 'wpseo_breadcrumb_output_id', '' ); |
| 185 | 184 | if ( ! \is_string( $this->id ) ) { |
| 186 | 185 | return ''; |
| @@ -203,9 +202,9 @@ | ||
| 203 | 202 | if ( ! $this->class ) { |
| 204 | 203 | /** |
| 205 | 204 | * Filter: 'wpseo_breadcrumb_output_class' - Allow changing the HTML class on the Yoast SEO breadcrumbs wrapper element. |
| 206 | 205 | * |
| 207 | - * @api string $unsigned Class to add to the wrapper element. | |
| 206 | + * @param string $unsigned Class to add to the wrapper element. | |
| 208 | 207 | */ |
| 209 | 208 | $this->class = \apply_filters( 'wpseo_breadcrumb_output_class', '' ); |
| 210 | 209 | if ( ! \is_string( $this->class ) ) { |
| 211 | 210 | return ''; |
| @@ -260,6 +259,23 @@ | ||
| 260 | 259 | $this->element = \esc_attr( \apply_filters( 'wpseo_breadcrumb_single_link_wrapper', 'span' ) ); |
| 261 | 260 | } |
| 262 | 261 | |
| 263 | 262 | return $this->element; |
| 263 | + } | |
| 264 | + | |
| 265 | + /** | |
| 266 | + * This is needed because when the editor is loaded in an Iframe the link needs to open in a different browser window. | |
| 267 | + * We don't want this behaviour in the front-end and the way to check this is to check if the block is rendered in a REST request with the `context` set as 'edit'. Thus being in the editor. | |
| 268 | + * | |
| 269 | + * @return bool returns if the breadcrumb should be opened in another window. | |
| 270 | + */ | |
| 271 | + private function should_link_target_blank(): bool { | |
| 272 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. | |
| 273 | + if ( isset( $_GET['context'] ) && \is_string( $_GET['context'] ) ) { | |
| 274 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form information, We are only strictly comparing. | |
| 275 | + if ( \wp_unslash( $_GET['context'] ) === 'edit' ) { | |
| 276 | + return true; | |
| 277 | + } | |
| 278 | + } | |
| 279 | + return false; | |
| 264 | 280 | } |
| 265 | 281 | } |