PluginProbe
Gutenberg / 24.1.0
Gutenberg v24.1.0
24.1.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 All 404 releases
← All changes | lib/compat/wordpress-7.1/view-config-api.php +205 -228 23.5.3 → 24.1.0 View file →
@@ -3,19 +3,121 @@
3 3 * Entity view configuration API.
4 4 *
5 5 * Builds the default view configuration for an entity and exposes it through
6 6 * the dynamic `get_entity_view_config_{$kind}_{$name}` filter so core and third
7 - * parties can provide the configuration for a specific entity.
7 + * parties can provide the configuration for a specific entity. The dynamic
8 + * portions of the hook name are lowercased, e.g.
9 + * `get_entity_view_config_posttype_page` for the `page` post type.
8 10 *
9 11 * @package gutenberg
10 12 */
11 13
12 14 /**
15 + * Builds the name of the dynamic filter that provides the view configuration
16 + * for an entity.
17 + *
18 + * The entity kind and name are embedded in the hook name lowercased, so the
19 + * hook follows the WordPress convention of lowercase hook names regardless of
20 + * how the entity identifiers are spelled: the `postType`/`page` entity maps to
21 + * the `get_entity_view_config_posttype_page` hook.
22 + *
23 + * @param string $kind The entity kind (e.g. `postType`).
24 + * @param string $name The entity name (e.g. `page`).
25 + * @return string The filter name.
26 + */
27 +function gutenberg_get_entity_view_config_hook_name( $kind, $name ) {
28 + return strtolower( "get_entity_view_config_{$kind}_{$name}" );
29 +}
30 +
31 +/**
32 + * Builds the default `form` configuration for post types that don't provide their own.
33 + *
34 + * It is a sensible default for `post`, `page`, and custom post types alike rather
35 + * than being tailored per type. Post types that need a different shape can replace
36 + * it entirely with a dedicated `form` through their own filter callback.
37 + *
38 + * It is intentionally NOT gated by `supports`. The registered fields are the
39 + * single source of truth for what applies: each field is registered for a post
40 + * type based on its `supports` (and related flags such as `theme_supports`), and
41 + * the editor drops any form field whose definition is absent or whose `isVisible`
42 + * returns `false`.
43 + *
44 + * @return array The default form configuration.
45 + */
46 +function _gutenberg_get_default_posttype_form() {
47 + return array(
48 + 'layout' => array( 'type' => 'panel' ),
49 + 'fields' => array(
50 + array(
51 + 'id' => 'featured_media',
52 + 'layout' => array(
53 + 'type' => 'regular',
54 + 'labelPosition' => 'none',
55 + ),
56 + ),
57 + array(
58 + 'id' => 'post-content-info',
59 + 'layout' => array(
60 + 'type' => 'regular',
61 + 'labelPosition' => 'none',
62 + ),
63 + ),
64 + array(
65 + 'id' => 'excerpt',
66 + 'layout' => array(
67 + 'type' => 'panel',
68 + 'labelPosition' => 'top',
69 + ),
70 + ),
71 + array(
72 + 'id' => 'status',
73 + 'label' => __( 'Status', 'gutenberg' ),
74 + 'children' => array(
75 + array(
76 + 'id' => 'status',
77 + 'layout' => array(
78 + 'type' => 'regular',
79 + 'labelPosition' => 'none',
80 + ),
81 + ),
82 + 'scheduled_date',
83 + 'password',
84 + 'sticky',
85 + ),
86 + ),
87 + 'date',
88 + 'slug',
89 + 'author',
90 + 'template',
91 + array(
92 + 'id' => 'discussion',
93 + 'label' => __( 'Discussion', 'gutenberg' ),
94 + 'children' => array(
95 + array(
96 + 'id' => 'comment_status',
97 + 'layout' => array(
98 + 'type' => 'regular',
99 + 'labelPosition' => 'none',
100 + ),
101 + ),
102 + 'ping_status',
103 + ),
104 + ),
105 + 'parent',
106 + 'format',
107 + 'revisions',
108 + ),
109 + );
110 +}
111 +
112 +/**
13 113 * Returns the view configuration for the given entity.
14 114 *
15 115 * Builds the default configuration shared by all entities and then exposes it
16 - * through the dynamic `get_entity_view_config_{$kind}_{$name}` filter so that core
17 - * and third parties can provide the configuration for a specific entity.
116 + * through the dynamic `get_entity_view_config_{$kind}_{$name}` filter — with the
117 + * dynamic portions lowercased, see gutenberg_get_entity_view_config_hook_name()
118 + * — so that core and third parties can provide the configuration for a
119 + * specific entity.
18 120 *
19 121 * @param string $kind The entity kind (e.g. `postType`).
20 122 * @param string $name The entity name (e.g. `page`).
21 123 * @return array {
@@ -61,61 +163,24 @@
61 163 $config = array(
62 164 'default_view' => $default_view,
63 165 'default_layouts' => $default_layouts,
64 166 'view_list' => $view_list,
65 - 'form' => array(),
167 + 'form' => 'postType' === $kind ? _gutenberg_get_default_posttype_form() : array(),
66 168 );
67 169
68 - /**
69 - * Filters the view configuration for a given entity.
70 - *
71 - * The dynamic portions of the hook name, `$kind` and `$name`, refer to the
72 - * entity kind (e.g. `postType`) and the entity name (e.g. `page`).
73 - *
74 - * @param array $config {
75 - * The view configuration for the entity.
76 - *
77 - * @type array $default_view Default view configuration.
78 - * @type array $default_layouts Default layouts configuration.
79 - * @type array $view_list List of available views.
80 - * @type array $form Form configuration.
81 - * }
82 - * @param array $entity {
83 - * The entity the configuration is built for.
84 - *
85 - * @type string $kind The entity kind.
86 - * @type string $name The entity name.
87 - * }
88 - */
89 - $filtered_config = apply_filters(
90 - "get_entity_view_config_{$kind}_{$name}",
91 - $config,
92 - array(
93 - 'kind' => $kind,
94 - 'name' => $name,
95 - )
96 - );
170 + $data = new Gutenberg_View_Config_Data( $config );
97 171
98 - if ( ! is_array( $filtered_config ) ) {
99 - return $config;
100 - }
101 -
102 - // Backfill any dropped keys with their defaults, then discard any keys the
103 - // filter introduced that are not part of the documented configuration shape.
104 - $filtered_config = array_merge( $config, $filtered_config );
105 - return array_intersect_key( $filtered_config, $config );
172 + return $data->apply_filters( $kind, $name );
106 173 }
107 174
108 175 /**
109 176 * Provides the view configuration for the `page` post type.
110 177 *
111 - * @param array $config {
112 - * The view configuration for the entity.
113 - * }
114 - * @return array The filtered view configuration.
178 + * @param Gutenberg_View_Config_Data $data The view configuration container for the entity.
179 + * @return Gutenberg_View_Config_Data The updated view configuration container.
115 180 */
116 -function _gutenberg_get_entity_view_config_post_type_page( $config ) {
117 - $config['default_layouts'] = array(
181 +function _gutenberg_get_entity_view_config_posttype_page( $data ) {
182 + $default_layouts = array(
118 183 'table' => array(
119 184 'layout' => array(
120 185 'styles' => array(
121 186 'author' => array(
@@ -127,9 +192,9 @@
127 192 'grid' => array(),
128 193 'list' => array(),
129 194 );
130 195
131 - $config['default_view'] = array(
196 + $default_view = array(
132 197 'type' => 'list',
133 198 'filters' => array(),
134 199 'perPage' => 20,
135 200 'sort' => array(
@@ -141,12 +206,9 @@
141 206 'mediaField' => 'featured_media',
142 207 'fields' => array( 'author', 'status' ),
143 208 );
144 209
145 - $config['view_list'] = array(
146 - // Reuse the base "all items" view, whose title is derived from the post
147 - // type's `all_items` label in gutenberg_get_entity_view_config().
148 - $config['view_list'][0],
210 + $view_list = array(
149 211 array(
150 212 'title' => __( 'Published', 'gutenberg' ),
151 213 'slug' => 'published',
152 214 'view' => array(
@@ -220,9 +282,9 @@
220 282 'title' => __( 'Trash', 'gutenberg' ),
221 283 'slug' => 'trash',
222 284 'view' => array(
223 285 'type' => 'table',
224 - 'layout' => $config['default_layouts']['table']['layout'],
286 + 'layout' => $default_layouts['table']['layout'],
225 287 'filters' => array(
226 288 array(
227 289 'field' => 'status',
228 290 'operator' => 'isAny',
@@ -233,161 +295,30 @@
233 295 ),
234 296 ),
235 297 );
236 298
237 - $config['form'] = array(
238 - 'layout' => array( 'type' => 'panel' ),
239 - 'fields' => array(
240 - array(
241 - 'id' => 'featured_media',
242 - 'layout' => array(
243 - 'type' => 'regular',
244 - 'labelPosition' => 'none',
245 - ),
246 - ),
247 - array(
248 - 'id' => 'post-content-info',
249 - 'layout' => array(
250 - 'type' => 'regular',
251 - 'labelPosition' => 'none',
252 - ),
253 - ),
254 - array(
255 - 'id' => 'excerpt',
256 - 'layout' => array(
257 - 'type' => 'panel',
258 - 'labelPosition' => 'top',
259 - ),
260 - ),
261 - array(
262 - 'id' => 'status',
263 - 'label' => __( 'Status', 'gutenberg' ),
264 - 'children' => array(
265 - array(
266 - 'id' => 'status',
267 - 'layout' => array(
268 - 'type' => 'regular',
269 - 'labelPosition' => 'none',
270 - ),
271 - ),
272 - 'scheduled_date',
273 - 'password',
274 - 'sticky',
275 - ),
276 - ),
277 - 'date',
278 - 'slug',
279 - 'author',
280 - 'template',
281 - array(
282 - 'id' => 'discussion',
283 - 'label' => __( 'Discussion', 'gutenberg' ),
284 - 'children' => array(
285 - array(
286 - 'id' => 'comment_status',
287 - 'layout' => array(
288 - 'type' => 'regular',
289 - 'labelPosition' => 'none',
290 - ),
291 - ),
292 - 'ping_status',
293 - ),
294 - ),
295 - 'parent',
296 - 'format',
297 - 'revisions',
299 + $data->set(
300 + array(
301 + 'default_view' => $default_view,
302 + 'default_layouts' => $default_layouts,
298 303 ),
304 + 1
299 305 );
306 + // Append the status views, thereby preserving the base "all items" view,
307 + // so its post-type-specific title is kept.
308 + $data->merge( array( 'view_list' => $view_list ), 1 );
300 309
301 - return $config;
310 + return $data;
302 311 }
303 312
304 313 /**
305 - * Provides the view configuration for the `post` post type.
306 - *
307 - * @param array $config {
308 - * The view configuration for the entity.
309 - * }
310 - * @return array The filtered view configuration.
311 - */
312 -function _gutenberg_get_entity_view_config_post_type_post( $config ) {
313 - $config['form'] = array(
314 - 'layout' => array( 'type' => 'panel' ),
315 - 'fields' => array(
316 - array(
317 - 'id' => 'featured_media',
318 - 'layout' => array(
319 - 'type' => 'regular',
320 - 'labelPosition' => 'none',
321 - ),
322 - ),
323 - array(
324 - 'id' => 'post-content-info',
325 - 'layout' => array(
326 - 'type' => 'regular',
327 - 'labelPosition' => 'none',
328 - ),
329 - ),
330 - array(
331 - 'id' => 'excerpt',
332 - 'layout' => array(
333 - 'type' => 'panel',
334 - 'labelPosition' => 'top',
335 - ),
336 - ),
337 - array(
338 - 'id' => 'status',
339 - 'label' => __( 'Status', 'gutenberg' ),
340 - 'children' => array(
341 - array(
342 - 'id' => 'status',
343 - 'layout' => array(
344 - 'type' => 'regular',
345 - 'labelPosition' => 'none',
346 - ),
347 - ),
348 - 'scheduled_date',
349 - 'password',
350 - 'sticky',
351 - ),
352 - ),
353 - 'date',
354 - 'slug',
355 - 'author',
356 - 'template',
357 - array(
358 - 'id' => 'discussion',
359 - 'label' => __( 'Discussion', 'gutenberg' ),
360 - 'children' => array(
361 - array(
362 - 'id' => 'comment_status',
363 - 'layout' => array(
364 - 'type' => 'regular',
365 - 'labelPosition' => 'none',
366 - ),
367 - ),
368 - 'ping_status',
369 - ),
370 - ),
371 - 'parent',
372 - 'format',
373 - 'revisions',
374 - ),
375 - );
376 -
377 - return $config;
378 -}
379 -
380 -/**
381 314 * Provides the view configuration for the `wp_block` post type.
382 315 *
383 - * @param array $config {
384 - * The view configuration for the entity.
385 - * }
386 - * @return array The filtered view configuration.
316 + * @param Gutenberg_View_Config_Data $data The view configuration container for the entity.
317 + * @return Gutenberg_View_Config_Data The updated view configuration container.
387 318 */
388 -function _gutenberg_get_entity_view_config_post_type_wp_block( $config ) {
389 - $config['default_layouts'] = array(
319 +function _gutenberg_get_entity_view_config_posttype_wp_block( $data ) {
320 + $default_layouts = array(
390 321 'table' => array(
391 322 'layout' => array(
392 323 'styles' => array(
393 324 'author' => array(
@@ -402,9 +333,9 @@
402 333 ),
403 334 ),
404 335 );
405 336
406 - $config['default_view'] = array(
337 + $default_view = array(
407 338 'type' => 'grid',
408 339 'perPage' => 20,
409 340 'titleField' => 'title',
410 341 'mediaField' => 'preview',
@@ -409,9 +340,9 @@
409 340 'titleField' => 'title',
410 341 'mediaField' => 'preview',
411 342 'fields' => array( 'sync-status' ),
412 343 'filters' => array(),
413 - 'layout' => $config['default_layouts']['grid']['layout'],
344 + 'layout' => $default_layouts['grid']['layout'],
414 345 );
415 346
416 347 $view_list = array(
417 348 array(
@@ -459,23 +390,51 @@
459 390 'slug' => $category_name,
460 391 );
461 392 }
462 393
463 - $config['view_list'] = $view_list;
394 + $form = array(
395 + 'layout' => array( 'type' => 'panel' ),
396 + 'fields' => array(
397 + array(
398 + 'id' => 'excerpt',
399 + 'layout' => array(
400 + 'type' => 'panel',
401 + 'labelPosition' => 'top',
402 + ),
403 + ),
404 + array(
405 + 'id' => 'post-content-info',
406 + 'layout' => array(
407 + 'type' => 'regular',
408 + 'labelPosition' => 'none',
409 + ),
410 + ),
411 + 'sync-status',
412 + 'revisions',
413 + ),
414 + );
464 415
465 - return $config;
416 + $data->set(
417 + array(
418 + 'default_view' => $default_view,
419 + 'default_layouts' => $default_layouts,
420 + 'view_list' => $view_list,
421 + 'form' => $form,
422 + ),
423 + 1
424 + );
425 +
426 + return $data;
466 427 }
467 428
468 429 /**
469 430 * Provides the view configuration for the `wp_template_part` post type.
470 431 *
471 - * @param array $config {
472 - * The view configuration for the entity.
473 - * }
474 - * @return array The filtered view configuration.
432 + * @param Gutenberg_View_Config_Data $data The view configuration container for the entity.
433 + * @return Gutenberg_View_Config_Data The updated view configuration container.
475 434 */
476 -function _gutenberg_get_entity_view_config_post_type_wp_template_part( $config ) {
477 - $config['default_layouts'] = array(
435 +function _gutenberg_get_entity_view_config_posttype_wp_template_part( $data ) {
436 + $default_layouts = array(
478 437 'table' => array(
479 438 'layout' => array(
480 439 'styles' => array(
481 440 'author' => array(
@@ -488,9 +447,9 @@
488 447 'layout' => array(),
489 448 ),
490 449 );
491 450
492 - $config['default_view'] = array(
451 + $default_view = array(
493 452 'type' => 'grid',
494 453 'perPage' => 20,
495 454 'titleField' => 'title',
496 455 'mediaField' => 'preview',
@@ -495,9 +454,9 @@
495 454 'titleField' => 'title',
496 455 'mediaField' => 'preview',
497 456 'fields' => array( 'author' ),
498 457 'filters' => array(),
499 - 'layout' => $config['default_layouts']['grid']['layout'],
458 + 'layout' => $default_layouts['grid']['layout'],
500 459 );
501 460
502 461 $view_list = array(
503 462 array(
@@ -539,11 +498,9 @@
539 498 ),
540 499 );
541 500 }
542 501
543 - $config['view_list'] = $view_list;
544 -
545 - $config['form'] = array(
502 + $form = array(
546 503 'layout' => array( 'type' => 'panel' ),
547 504 'fields' => array(
548 505 array(
549 506 'id' => 'last_edited_date',
@@ -555,21 +512,29 @@
555 512 'revisions',
556 513 ),
557 514 );
558 515
559 - return $config;
516 + $data->set(
517 + array(
518 + 'default_view' => $default_view,
519 + 'default_layouts' => $default_layouts,
520 + 'view_list' => $view_list,
521 + 'form' => $form,
522 + ),
523 + 1
524 + );
525 +
526 + return $data;
560 527 }
561 528
562 529 /**
563 530 * Provides the view configuration for the `wp_template` post type.
564 531 *
565 - * @param array $config {
566 - * The view configuration for the entity.
567 - * }
568 - * @return array The filtered view configuration.
532 + * @param Gutenberg_View_Config_Data $data The view configuration container for the entity.
533 + * @return Gutenberg_View_Config_Data The updated view configuration container.
569 534 */
570 -function _gutenberg_get_entity_view_config_post_type_wp_template( $config ) {
571 - $config['default_view'] = array(
535 +function _gutenberg_get_entity_view_config_posttype_wp_template( $data ) {
536 + $default_view = array(
572 537 'type' => 'grid',
573 538 'perPage' => 20,
574 539 'sort' => array(
575 540 'field' => 'title',
@@ -582,9 +547,9 @@
582 547 'filters' => array(),
583 548 'showMedia' => true,
584 549 );
585 550
586 - $config['default_layouts'] = array(
551 + $default_layouts = array(
587 552 'table' => array( 'showMedia' => false ),
588 553 'grid' => array( 'showMedia' => true ),
589 554 'list' => array( 'showMedia' => false ),
590 555 );
@@ -726,11 +691,9 @@
726 691 }
727 692 }
728 693 }
729 694
730 - $config['view_list'] = array_merge( $view_list, $registered_authors, $user_authors );
731 -
732 - $config['form'] = array(
695 + $form = array(
733 696 'layout' => array( 'type' => 'panel' ),
734 697 'fields' => array(
735 698 array(
736 699 'id' => 'description',
@@ -763,9 +726,19 @@
763 726 'default_comment_status',
764 727 ),
765 728 );
766 729
767 - return $config;
730 + $data->set(
731 + array(
732 + 'default_view' => $default_view,
733 + 'default_layouts' => $default_layouts,
734 + 'view_list' => array_merge( $view_list, $registered_authors, $user_authors ),
735 + 'form' => $form,
736 + ),
737 + 1
738 + );
739 +
740 + return $data;
768 741 }
769 742
770 743 /**
771 744 * Registers the Gutenberg entity view configuration filters, overriding any
@@ -770,13 +743,17 @@
770 743 /**
771 744 * Registers the Gutenberg entity view configuration filters, overriding any
772 745 * defaults that WordPress core may have already registered.
773 746 *
774 - * Core registers its own `_wp_get_entity_view_config_post_type_*` callbacks on
747 + * Core registers its own `_wp_get_entity_view_config_posttype_*` callbacks on
775 748 * the shared `get_entity_view_config_{$kind}_{$name}` hooks. The Gutenberg
776 749 * plugin always ships the newest configuration, so it removes the core defaults
777 750 * and installs its own `_gutenberg_*` callbacks instead.
778 751 *
752 + * Post types without a dedicated `_gutenberg_*` callback (e.g. `post`) still have
753 + * the core callback removed so they fall back to the default configuration
754 + * built in gutenberg_get_entity_view_config().
755 + *
779 756 * This runs on `init` rather than at file include time so that the core
780 757 * defaults are guaranteed to be registered first, regardless of whether core
781 758 * registers them at include time or lazily on a hook.
782 759 */
@@ -783,11 +760,11 @@
783 760 function gutenberg_register_entity_view_config_filters() {
784 761 $post_types = array( 'page', 'post', 'wp_block', 'wp_template_part', 'wp_template' );
785 762
786 763 foreach ( $post_types as $post_type ) {
787 - $hook = "get_entity_view_config_postType_{$post_type}";
788 - $wp_callback = "_wp_get_entity_view_config_post_type_{$post_type}";
789 - $gb_callback = "_gutenberg_get_entity_view_config_post_type_{$post_type}";
764 + $hook = gutenberg_get_entity_view_config_hook_name( 'postType', $post_type );
765 + $wp_callback = "_wp_get_entity_view_config_posttype_{$post_type}";
766 + $gb_callback = "_gutenberg_get_entity_view_config_posttype_{$post_type}";
790 767
791 768 // has_filter() returns the priority the callback was registered at.
792 769 $wp_priority = has_filter( $hook, $wp_callback );
793 770 if ( false !== $wp_priority ) {