PluginProbe
Gutenberg / 23.2.0
Gutenberg v23.2.0
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
gutenberg / build / scripts / block-library / navigation-link.php
build/scripts/block-library
accordion 6 months ago accordion-heading 9 months ago accordion-item 4 months ago accordion-panel 7 months ago archives 7 months ago audio 10 months ago avatar 7 months ago block 7 months ago breadcrumbs 7 months ago button 6 months ago buttons 7 months ago calendar 7 months ago categories 7 months ago code 10 months ago column 10 months ago columns 10 months ago comment-author-avatar 10 months ago comment-author-name 7 months ago comment-content 7 months ago comment-date 7 months ago comment-edit-link 7 months ago comment-reply-link 7 months ago comment-template 7 months ago comments 7 months ago comments-pagination 7 months ago comments-pagination-next 7 months ago comments-pagination-numbers 7 months ago comments-pagination-previous 7 months ago comments-title 7 months ago cover 10 months ago details 10 months ago embed 7 months ago file 10 months ago footnotes 7 months ago form 4 months ago form-input 4 months ago form-submission-notification 4 months ago form-submit-button 4 months ago freeform 7 months ago gallery 6 months ago group 4 months ago heading 7 months ago home-link 7 months ago html 5 months ago icon 5 months ago image 6 months ago latest-comments 7 months ago latest-posts 7 months ago list 7 months ago list-item 5 months ago loginout 7 months ago math 7 months ago media-text 10 months ago missing 7 months ago more 7 months ago navigation 6 months ago navigation-link 5 months ago navigation-overlay-close 6 months ago navigation-submenu 6 months ago nextpage 5 months ago page-list 6 months ago page-list-item 6 months ago paragraph 6 months ago pattern 9 months ago playlist 6 months ago playlist-track 6 months ago post-author 6 months ago post-author-biography 6 months ago post-author-name 6 months ago post-comment 10 months ago post-comments-count 6 months ago post-comments-form 6 months ago post-comments-link 6 months ago post-content 7 months ago post-date 5 months ago post-excerpt 5 months ago post-featured-image 7 months ago post-navigation-link 6 months ago post-template 7 months ago post-terms 6 months ago post-time-to-read 6 months ago post-title 6 months ago preformatted 10 months ago pullquote 4 months ago query 6 months ago query-no-results 7 months ago query-pagination 7 months ago query-pagination-next 7 months ago query-pagination-numbers 7 months ago query-pagination-previous 7 months ago query-title 6 months ago query-total 7 months ago quote 10 months ago read-more 7 months ago rss 7 months ago search 4 months ago separator 10 months ago shortcode 5 months ago site-logo 7 months ago site-tagline 6 months ago site-title 6 months ago social-link 7 months ago social-links 7 months ago spacer 10 months ago tab 4 months ago tab-list 4 months ago tab-panel 4 months ago tab-panels 4 months ago table 10 months ago table-of-contents 7 months ago tabs 4 months ago tag-cloud 7 months ago template-part 10 months ago term-count 7 months ago term-description 6 months ago term-name 7 months ago term-template 7 months ago terms-query 7 months ago text-columns 10 months ago verse 6 months ago video 10 months ago accordion-item.php 2.9 KB 5 months ago accordion.php 1.2 KB 10 months ago archives.php 4.4 KB 7 months ago avatar.php 5.6 KB 7 months ago block.php 4.1 KB 10 months ago blocks-manifest.php 213.3 KB 4 months ago breadcrumbs.php 19.0 KB 7 months ago button.php 4.2 KB 6 months ago calendar.php 6.1 KB 10 months ago categories.php 4.9 KB 7 months ago comment-author-avatar.php 2.5 KB 7 months ago comment-author-name.php 2.1 KB 10 months ago comment-content.php 2.4 KB 10 months ago comment-date.php 1.9 KB 10 months ago comment-edit-link.php 1.7 KB 10 months ago comment-reply-link.php 2.1 KB 10 months ago comment-template.php 4.5 KB 10 months ago comments-pagination-next.php 1.9 KB 10 months ago comments-pagination-numbers.php 1.6 KB 10 months ago comments-pagination-previous.php 1.8 KB 10 months ago comments-pagination.php 1.3 KB 10 months ago comments-title.php 2.8 KB 7 months ago comments.php 6.7 KB 10 months ago cover.php 7.3 KB 5 months ago details.php 1.5 KB 5 months ago file.php 1.9 KB 10 months ago footnotes.php 3.8 KB 7 months ago form-input.php 1.2 KB 10 months ago form-submission-notification.php 1.5 KB 10 months ago form.php 5.8 KB 10 months ago gallery.php 8.9 KB 6 months ago heading.php 1.3 KB 10 months ago home-link.php 4.9 KB 5 months ago icon.php 4.0 KB 6 months ago image.php 17.4 KB 4 months ago index.js 2.6 MB 3 months ago index.js.map 3.9 MB 3 months ago index.min.asset.php 696 B 3 months ago index.min.js 1.1 MB 3 months ago index.min.js.map 4.0 MB 3 months ago latest-comments.php 5.4 KB 7 months ago latest-posts.php 8.7 KB 4 months ago list.php 1.3 KB 10 months ago loginout.php 2.1 KB 5 months ago media-text.php 4.2 KB 6 months ago navigation-link.php 15.3 KB 5 months ago navigation-overlay-close.php 1.8 KB 6 months ago navigation-submenu.php 11.0 KB 5 months ago navigation.php 63.6 KB 3 months ago page-list-item.php 385 B 10 months ago page-list.php 14.3 KB 5 months ago paragraph.php 1.2 KB 7 months ago pattern.php 1.8 KB 10 months ago playlist-track.php 2.1 KB 6 months ago playlist.php 4.6 KB 6 months ago post-author-biography.php 1.5 KB 10 months ago post-author-name.php 1.9 KB 10 months ago post-author.php 2.7 KB 10 months ago post-comment.php 429 B 10 months ago post-comments-count.php 1.3 KB 10 months ago post-comments-form.php 2.8 KB 10 months ago post-comments-link.php 2.2 KB 10 months ago post-content.php 2.3 KB 10 months ago post-date.php 3.6 KB 7 months ago post-excerpt.php 4.3 KB 7 months ago post-featured-image.php 9.1 KB 6 months ago post-navigation-link.php 4.7 KB 7 months ago post-template.php 5.9 KB 4 months ago post-terms.php 3.6 KB 10 months ago post-time-to-read.php 6.3 KB 7 months ago post-title.php 2.1 KB 7 months ago query-no-results.php 1.8 KB 10 months ago query-pagination-next.php 3.6 KB 6 months ago query-pagination-numbers.php 4.6 KB 6 months ago query-pagination-previous.php 3.4 KB 6 months ago query-pagination.php 1.2 KB 10 months ago query-title.php 2.7 KB 6 months ago query-total.php 2.5 KB 6 months ago query.php 5.6 KB 10 months ago read-more.php 1.8 KB 10 months ago rss.php 4.5 KB 10 months ago search.php 24.1 KB 4 months ago shortcode.php 779 B 10 months ago site-logo.php 6.4 KB 10 months ago site-tagline.php 1.2 KB 10 months ago site-title.php 1.9 KB 10 months ago social-link.php 66.2 KB 7 months ago tab-list.php 2.1 KB 4 months ago tab-panel.php 2.1 KB 4 months ago tab.php 2.1 KB 4 months ago table-of-contents.php 1.2 KB 10 months ago tabs.php 4.6 KB 4 months ago tag-cloud.php 1.6 KB 10 months ago template-part.php 10.3 KB 6 months ago term-count.php 1.8 KB 10 months ago term-description.php 1.8 KB 10 months ago term-name.php 2.0 KB 7 months ago term-template.php 4.5 KB 7 months ago video.php 2.7 KB 10 months ago

navigation-link.php in Gutenberg 23.2.0, at build/scripts/block-library/navigation-link.php

461 lines 15.3 KB Raw Download Zip
1 <?php
2 /**
3 * Server-side registering and rendering of the `core/navigation-link` block.
4 *
5 * @package WordPress
6 */
7
8 require_once __DIR__ . '/navigation-link/shared/item-should-render.php';
9 require_once __DIR__ . '/navigation-link/shared/render-submenu-icon.php';
10 require_once __DIR__ . '/navigation-link/shared/build-css-font-sizes.php';
11
12 /**
13 * Build an array with CSS classes and inline styles defining the colors
14 * which will be applied to the navigation markup in the front-end.
15 *
16 * @since 5.9.0
17 *
18 * @param array $context Navigation block context.
19 * @param array $attributes Block attributes.
20 * @param bool $is_sub_menu Whether the link is part of a sub-menu. Default false.
21 * @return array Colors CSS classes and inline styles.
22 */
23 function gutenberg_block_core_navigation_link_build_css_colors( $context, $attributes, $is_sub_menu = false ) {
24 $colors = array(
25 'css_classes' => array(),
26 'inline_styles' => '',
27 );
28
29 // Text color.
30 $named_text_color = null;
31 $custom_text_color = null;
32
33 if ( $is_sub_menu && array_key_exists( 'customOverlayTextColor', $context ) ) {
34 $custom_text_color = $context['customOverlayTextColor'];
35 } elseif ( $is_sub_menu && array_key_exists( 'overlayTextColor', $context ) ) {
36 $named_text_color = $context['overlayTextColor'];
37 } elseif ( array_key_exists( 'customTextColor', $context ) ) {
38 $custom_text_color = $context['customTextColor'];
39 } elseif ( array_key_exists( 'textColor', $context ) ) {
40 $named_text_color = $context['textColor'];
41 } elseif ( isset( $context['style']['color']['text'] ) ) {
42 $custom_text_color = $context['style']['color']['text'];
43 }
44
45 // If has text color.
46 if ( ! is_null( $named_text_color ) ) {
47 // Add the color class.
48 array_push( $colors['css_classes'], 'has-text-color', sprintf( 'has-%s-color', $named_text_color ) );
49 } elseif ( ! is_null( $custom_text_color ) ) {
50 // Add the custom color inline style.
51 $colors['css_classes'][] = 'has-text-color';
52 $colors['inline_styles'] .= sprintf( 'color: %s;', $custom_text_color );
53 }
54
55 // Background color.
56 $named_background_color = null;
57 $custom_background_color = null;
58
59 if ( $is_sub_menu && array_key_exists( 'customOverlayBackgroundColor', $context ) ) {
60 $custom_background_color = $context['customOverlayBackgroundColor'];
61 } elseif ( $is_sub_menu && array_key_exists( 'overlayBackgroundColor', $context ) ) {
62 $named_background_color = $context['overlayBackgroundColor'];
63 } elseif ( array_key_exists( 'customBackgroundColor', $context ) ) {
64 $custom_background_color = $context['customBackgroundColor'];
65 } elseif ( array_key_exists( 'backgroundColor', $context ) ) {
66 $named_background_color = $context['backgroundColor'];
67 } elseif ( isset( $context['style']['color']['background'] ) ) {
68 $custom_background_color = $context['style']['color']['background'];
69 }
70
71 // If has background color.
72 if ( ! is_null( $named_background_color ) ) {
73 // Add the background-color class.
74 array_push( $colors['css_classes'], 'has-background', sprintf( 'has-%s-background-color', $named_background_color ) );
75 } elseif ( ! is_null( $custom_background_color ) ) {
76 // Add the custom background-color inline style.
77 $colors['css_classes'][] = 'has-background';
78 $colors['inline_styles'] .= sprintf( 'background-color: %s;', $custom_background_color );
79 }
80
81 return $colors;
82 }
83
84 /**
85 * Decodes a url if it's encoded, returning the same url if not.
86 *
87 * @since 6.2.0
88 *
89 * @param string $url The url to decode.
90 *
91 * @return string $url Returns the decoded url.
92 */
93 function gutenberg_block_core_navigation_link_maybe_urldecode( $url ) {
94 $is_url_encoded = false;
95 $query = parse_url( $url, PHP_URL_QUERY );
96 $query_params = wp_parse_args( $query );
97
98 foreach ( $query_params as $query_param ) {
99 $can_query_param_be_encoded = is_string( $query_param ) && ! empty( $query_param );
100 if ( ! $can_query_param_be_encoded ) {
101 continue;
102 }
103 if ( rawurldecode( $query_param ) !== $query_param ) {
104 $is_url_encoded = true;
105 break;
106 }
107 }
108
109 if ( $is_url_encoded ) {
110 return rawurldecode( $url );
111 }
112
113 return $url;
114 }
115
116
117 /**
118 * Renders the `core/navigation-link` block.
119 *
120 * @since 5.9.0
121 *
122 * @param array $attributes The block attributes.
123 * @param string $content The saved content.
124 * @param WP_Block $block The parsed block.
125 *
126 * @return string Returns the post content with the legacy widget added.
127 */
128 function gutenberg_render_block_core_navigation_link( $attributes, $content, $block ) {
129 // Check if this navigation item should render based on post status.
130 if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
131 if ( ! gutenberg_block_core_shared_navigation_item_should_render( $attributes, $block ) ) {
132 return '';
133 }
134 }
135
136 // Don't render the block's subtree if it has no label.
137 if ( empty( $attributes['label'] ) ) {
138 return '';
139 }
140
141 // The build system prefixes this function with "gutenberg_" to avoid
142 // collisions with the core version. Until this function is backported to
143 // core, we need to guard its use and only call the prefixed name in
144 // the plugin.
145 if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
146 $font_sizes = gutenberg_block_core_shared_navigation_build_css_font_sizes( $block->context );
147 } else {
148 $font_sizes = block_core_shared_navigation_build_css_font_sizes( $block->context );
149 }
150 $classes = array_merge(
151 $font_sizes['css_classes']
152 );
153 $style_attribute = $font_sizes['inline_styles'];
154
155 // Render inner blocks first to check if any menu items will actually display.
156 $inner_blocks_html = '';
157 foreach ( $block->inner_blocks as $inner_block ) {
158 $inner_blocks_html .= $inner_block->render();
159 }
160 $has_submenu = ! empty( trim( $inner_blocks_html ) );
161
162 $css_classes = trim( implode( ' ', $classes ) );
163 $kind = empty( $attributes['kind'] ) ? 'post_type' : str_replace( '-', '_', $attributes['kind'] );
164 $is_active = ! empty( $attributes['id'] ) && get_queried_object_id() === (int) $attributes['id'] && ! empty( get_queried_object()->$kind );
165
166 if ( is_post_type_archive() && ! empty( $attributes['url'] ) ) {
167 $queried_archive_link = get_post_type_archive_link( get_queried_object()->name );
168 if ( $attributes['url'] === $queried_archive_link ) {
169 $is_active = true;
170 }
171 }
172
173 $wrapper_attributes = get_block_wrapper_attributes(
174 array(
175 'class' => $css_classes . ' wp-block-navigation-item' . ( $has_submenu ? ' has-child' : '' ) .
176 ( $is_active ? ' current-menu-item' : '' ),
177 'style' => $style_attribute,
178 )
179 );
180 $html = '<li ' . $wrapper_attributes . '>' .
181 '<a class="wp-block-navigation-item__content" ';
182
183 // Start appending HTML attributes to anchor tag.
184 if ( isset( $attributes['url'] ) ) {
185 $html .= ' href="' . esc_url( gutenberg_block_core_navigation_link_maybe_urldecode( $attributes['url'] ) ) . '"';
186 }
187
188 if ( $is_active ) {
189 $html .= ' aria-current="page"';
190 }
191
192 if ( isset( $attributes['opensInNewTab'] ) && true === $attributes['opensInNewTab'] ) {
193 $html .= ' target="_blank" ';
194 }
195
196 if ( isset( $attributes['rel'] ) ) {
197 $html .= ' rel="' . esc_attr( $attributes['rel'] ) . '"';
198 } elseif ( isset( $attributes['nofollow'] ) && $attributes['nofollow'] ) {
199 $html .= ' rel="nofollow"';
200 }
201
202 if ( isset( $attributes['title'] ) ) {
203 $html .= ' title="' . esc_attr( $attributes['title'] ) . '"';
204 }
205
206 // End appending HTML attributes to anchor tag.
207
208 // Start anchor tag content.
209 $html .= '>' .
210 // Wrap title with span to isolate it from submenu icon.
211 '<span class="wp-block-navigation-item__label">';
212
213 if ( isset( $attributes['label'] ) ) {
214 $html .= wp_kses_post( $attributes['label'] );
215 }
216
217 $html .= '</span>';
218
219 // Add description if available.
220 if ( ! empty( $attributes['description'] ) ) {
221 $html .= '<span class="wp-block-navigation-item__description">';
222 $html .= wp_kses_post( $attributes['description'] );
223 $html .= '</span>';
224 }
225
226 $html .= '</a>';
227 // End anchor tag content.
228
229 if ( isset( $block->context['showSubmenuIcon'] ) && $block->context['showSubmenuIcon'] && $has_submenu ) {
230 // The submenu icon can be hidden by a CSS rule on the Navigation Block.
231 $html .= '<span class="wp-block-navigation__submenu-icon">';
232 if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
233 $html .= gutenberg_block_core_shared_navigation_render_submenu_icon();
234 } else {
235 $html .= block_core_shared_navigation_render_submenu_icon();
236 }
237 $html .= '</span>';
238 }
239
240 if ( $has_submenu ) {
241 $html .= sprintf(
242 '<ul class="wp-block-navigation__submenu-container">%s</ul>',
243 $inner_blocks_html
244 );
245 }
246
247 $html .= '</li>';
248
249 return $html;
250 }
251
252 /**
253 * Returns a navigation link variation
254 *
255 * @since 5.9.0
256 *
257 * @param WP_Taxonomy|WP_Post_Type $entity post type or taxonomy entity.
258 * @param string $kind string of value 'taxonomy' or 'post-type'.
259 *
260 * @return array
261 */
262 function gutenberg_build_variation_for_navigation_link( $entity, $kind ) {
263 $title = '';
264 $description = '';
265
266 // Get default labels based on entity type
267 $default_labels = null;
268 if ( $entity instanceof WP_Post_Type ) {
269 $default_labels = WP_Post_Type::get_default_labels();
270 } elseif ( $entity instanceof WP_Taxonomy ) {
271 $default_labels = WP_Taxonomy::get_default_labels();
272 }
273
274 // Get title and check if it's default
275 $is_default_title = false;
276 if ( property_exists( $entity->labels, 'item_link' ) ) {
277 $title = $entity->labels->item_link;
278 if ( isset( $default_labels['item_link'] ) ) {
279 $is_default_title = in_array( $title, $default_labels['item_link'], true );
280 }
281 }
282
283 // Get description and check if it's default
284 $is_default_description = false;
285 if ( property_exists( $entity->labels, 'item_link_description' ) ) {
286 $description = $entity->labels->item_link_description;
287 if ( isset( $default_labels['item_link_description'] ) ) {
288 $is_default_description = in_array( $description, $default_labels['item_link_description'], true );
289 }
290 }
291
292 // Calculate singular name once (used for both title and description)
293 $singular = $entity->labels->singular_name ?? ucfirst( $entity->name );
294
295 // Set default title if needed
296 if ( $is_default_title || '' === $title ) {
297 /* translators: %s: Singular label of the entity. */
298 $title = sprintf( __( '%s link' ), $singular );
299 }
300
301 // Default description if needed.
302 // Use a single space character instead of an empty string to prevent fallback to the
303 // block.json default description ("Add a page, link, or another item to your navigation.").
304 // An empty string would be treated as missing and trigger the fallback, while a single
305 // space appears blank in the UI but prevents the fallback behavior.
306 // We avoid generating descriptions like "A link to a %s" to prevent grammatical errors
307 // (e.g., "A link to a event" should be "A link to an event").
308 if ( $is_default_description || '' === $description ) {
309 $description = ' ';
310 }
311
312 $variation = array(
313 'name' => $entity->name,
314 'title' => $title,
315 'description' => $description,
316 'attributes' => array(
317 'type' => $entity->name,
318 'kind' => $kind,
319 ),
320 );
321
322 // Tweak some value for the variations.
323 $variation_overrides = array(
324 'post_tag' => array(
325 'name' => 'tag',
326 'attributes' => array(
327 'type' => 'tag',
328 'kind' => $kind,
329 ),
330 ),
331 'post_format' => array(
332 // The item_link and item_link_description for post formats is the
333 // same as for tags, so need to be overridden.
334 'title' => __( 'Post Format Link' ),
335 'description' => __( 'A link to a post format' ),
336 'attributes' => array(
337 'type' => 'post_format',
338 'kind' => $kind,
339 ),
340 ),
341 );
342
343 if ( array_key_exists( $entity->name, $variation_overrides ) ) {
344 $variation = array_merge(
345 $variation,
346 $variation_overrides[ $entity->name ]
347 );
348 }
349
350 return $variation;
351 }
352
353 /**
354 * Filters the registered variations for a block type.
355 * Returns the dynamically built variations for all post-types and taxonomies.
356 *
357 * @since 6.5.0
358 *
359 * @param array $variations Array of registered variations for a block type.
360 * @param WP_Block_Type $block_type The full block type object.
361 * @return array Numerically indexed array of block variations.
362 */
363 function gutenberg_block_core_navigation_link_filter_variations( $variations, $block_type ) {
364 if ( 'core/navigation-link' !== $block_type->name ) {
365 return $variations;
366 }
367
368 $generated_variations = gutenberg_block_core_navigation_link_build_variations();
369
370 /*
371 * IMPORTANT: Order matters for deduplication.
372 *
373 * The variations returned from this filter are bootstrapped to JavaScript and
374 * processed by the block variations reducer. The reducer uses `getUniqueItemsByName()`
375 * (packages/blocks/src/store/reducer.js:51-57) which keeps the FIRST variation with
376 * a given 'name' and discards later duplicates when processing the array in order.
377 *
378 * By placing generated variations first in `array_merge()`, the improved
379 * labels (e.g., "Product link" instead of generic "Post Link") are processed first
380 * and preserved. The generic incoming variations are then discarded as duplicates.
381 *
382 * Why `array_merge()` instead of manual deduplication?
383 * - Both arrays use numeric indices (0, 1, 2...), so `array_merge()` concatenates
384 * and re-indexes them sequentially, preserving order
385 * - The reducer handles deduplication, so it is not needed here
386 * - This keeps the PHP code simple and relies on the established JavaScript behavior
387 *
388 * See: https://github.com/WordPress/gutenberg/pull/72517
389 */
390 return array_merge( $generated_variations, $variations );
391 }
392
393 /**
394 * Returns an array of variations for the navigation link block.
395 *
396 * @since 6.5.0
397 *
398 * @return array
399 */
400 function gutenberg_block_core_navigation_link_build_variations() {
401 $post_types = get_post_types( array( 'show_in_nav_menus' => true ), 'objects' );
402 $taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'objects' );
403
404 /*
405 * Use two separate arrays as a way to order the variations in the UI.
406 * Known variations (like Post Link and Page Link) are added to the
407 * `built_ins` array. Variations for custom post types and taxonomies are
408 * added to the `variations` array and will always appear after `built-ins.
409 */
410 $built_ins = array();
411 $variations = array();
412
413 if ( $post_types ) {
414 foreach ( $post_types as $post_type ) {
415 $variation = gutenberg_build_variation_for_navigation_link( $post_type, 'post-type' );
416 if ( $post_type->_builtin ) {
417 $built_ins[] = $variation;
418 } else {
419 $variations[] = $variation;
420 }
421 }
422 }
423 if ( $taxonomies ) {
424 foreach ( $taxonomies as $taxonomy ) {
425 $variation = gutenberg_build_variation_for_navigation_link( $taxonomy, 'taxonomy' );
426 if ( $taxonomy->_builtin ) {
427 $built_ins[] = $variation;
428 } else {
429 $variations[] = $variation;
430 }
431 }
432 }
433
434 $all_variations = array_merge( $built_ins, $variations );
435
436 return $all_variations;
437 }
438
439 /**
440 * Registers the navigation link block.
441 *
442 * @since 5.9.0
443 *
444 * @uses gutenberg_render_block_core_navigation_link()
445 * @throws WP_Error An WP_Error exception parsing the block definition.
446 */
447 function gutenberg_register_block_core_navigation_link() {
448 register_block_type_from_metadata(
449 __DIR__ . '/navigation-link',
450 array(
451 'render_callback' => 'gutenberg_render_block_core_navigation_link',
452 )
453 );
454 }
455 add_action( 'init', 'gutenberg_register_block_core_navigation_link', 20 );
456 /**
457 * Creates all variations for post types / taxonomies dynamically (= each time when variations are requested).
458 * Do not use variation_callback, to also account for unregistering post types/taxonomies later on.
459 */
460 add_filter( 'get_block_type_variations', 'gutenberg_block_core_navigation_link_filter_variations', 10, 2 );
461