PluginProbe
Gutenberg / 12.4.0
Gutenberg v12.4.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 7.4.0 All 402 releases
gutenberg / lib / navigation.php

navigation.php in Gutenberg 12.4.0, at lib/navigation.php

245 lines 8.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Functions used in making nav menus interopable with block editors.
4 *
5 * @package gutenberg
6 */
7
8 /**
9 * Registers block editor 'wp_navigation' post type.
10 */
11 function gutenberg_register_navigation_post_type() {
12 $labels = array(
13 'name' => __( 'Navigation Menus', 'gutenberg' ),
14 'singular_name' => __( 'Navigation Menu', 'gutenberg' ),
15 'menu_name' => _x( 'Navigation Menus', 'Admin Menu text', 'gutenberg' ),
16 'add_new' => _x( 'Add New', 'Navigation Menu', 'gutenberg' ),
17 'add_new_item' => __( 'Add New Navigation Menu', 'gutenberg' ),
18 'new_item' => __( 'New Navigation Menu', 'gutenberg' ),
19 'edit_item' => __( 'Edit Navigation Menu', 'gutenberg' ),
20 'view_item' => __( 'View Navigation Menu', 'gutenberg' ),
21 'all_items' => __( 'All Navigation Menus', 'gutenberg' ),
22 'search_items' => __( 'Search Navigation Menus', 'gutenberg' ),
23 'parent_item_colon' => __( 'Parent Navigation Menu:', 'gutenberg' ),
24 'not_found' => __( 'No Navigation Menu found.', 'gutenberg' ),
25 'not_found_in_trash' => __( 'No Navigation Menu found in Trash.', 'gutenberg' ),
26 'archives' => __( 'Navigation Menu archives', 'gutenberg' ),
27 'insert_into_item' => __( 'Insert into Navigation Menu', 'gutenberg' ),
28 'uploaded_to_this_item' => __( 'Uploaded to this Navigation Menu', 'gutenberg' ),
29 // Some of these are a bit weird, what are they for?
30 'filter_items_list' => __( 'Filter Navigation Menu list', 'gutenberg' ),
31 'items_list_navigation' => __( 'Navigation Menus list navigation', 'gutenberg' ),
32 'items_list' => __( 'Navigation Menus list', 'gutenberg' ),
33 );
34
35 $args = array(
36 'labels' => $labels,
37 'description' => __( 'Navigation menus.', 'gutenberg' ),
38 'public' => false,
39 'has_archive' => false,
40 // We should disable UI for non-block themes.
41 'show_ui' => wp_is_block_theme(),
42 'show_in_menu' => false,
43 'show_in_admin_bar' => false,
44 'show_in_rest' => true,
45 'map_meta_cap' => true,
46 'rest_base' => 'navigation',
47 'rest_controller_class' => WP_REST_Posts_Controller::class,
48 'supports' => array(
49 'title',
50 'editor',
51 'revisions',
52 ),
53 'capabilities' => array(
54 'edit_others_posts' => 'edit_theme_options',
55 'delete_posts' => 'edit_theme_options',
56 'publish_posts' => 'edit_theme_options',
57 'create_posts' => 'edit_theme_options',
58 'read_private_posts' => 'edit_theme_options',
59 'delete_private_posts' => 'edit_theme_options',
60 'delete_published_posts' => 'edit_theme_options',
61 'delete_others_posts' => 'edit_theme_options',
62 'edit_private_posts' => 'edit_theme_options',
63 'edit_published_posts' => 'edit_theme_options',
64 ),
65 );
66
67 register_post_type( 'wp_navigation', $args );
68 }
69 add_action( 'init', 'gutenberg_register_navigation_post_type' );
70
71 /**
72 * Disable "Post Attributes" for wp_navigation post type.
73 *
74 * The attributes are also conditionally enabled when a site has custom templates.
75 * Block Theme templates can be available for every post type.
76 */
77 add_filter( 'theme_wp_navigation_templates', '__return_empty_array' );
78
79 /**
80 * Disable block editor for wp_navigation type posts so they can be managed via the UI.
81 *
82 * @param bool $value Whether the CPT supports block editor or not.
83 * @param string $post_type Post type.
84 *
85 * @return bool
86 */
87 function gutenberg_disable_block_editor_for_navigation_post_type( $value, $post_type ) {
88 if ( 'wp_navigation' === $post_type ) {
89 return false;
90 }
91
92 return $value;
93 }
94
95 add_filter( 'use_block_editor_for_post_type', 'gutenberg_disable_block_editor_for_navigation_post_type', 10, 2 );
96
97 /**
98 * This callback disables the content editor for wp_navigation type posts.
99 * Content editor cannot handle wp_navigation type posts correctly.
100 * We cannot disable the "editor" feature in the wp_navigation's CPT definition
101 * because it disables the ability to save navigation blocks via REST API.
102 *
103 * @param WP_Post $post An instance of WP_Post class.
104 */
105 function gutenberg_disable_content_editor_for_navigation_post_type( $post ) {
106 $post_type = get_post_type( $post );
107 if ( 'wp_navigation' !== $post_type ) {
108 return;
109 }
110
111 remove_post_type_support( $post_type, 'editor' );
112 }
113
114 add_action( 'edit_form_after_title', 'gutenberg_disable_content_editor_for_navigation_post_type', 10, 1 );
115
116 /**
117 * This callback enables content editor for wp_navigation type posts.
118 * We need to enable it back because we disable it to hide
119 * the content editor for wp_navigation type posts.
120 *
121 * @see gutenberg_disable_content_editor_for_navigation_post_type
122 *
123 * @param WP_Post $post An instance of WP_Post class.
124 */
125 function gutenberg_enable_content_editor_for_navigation_post_type( $post ) {
126 $post_type = get_post_type( $post );
127 if ( 'wp_navigation' !== $post_type ) {
128 return;
129 }
130
131 add_post_type_support( $post_type, 'editor' );
132 }
133
134 add_action( 'edit_form_after_editor', 'gutenberg_enable_content_editor_for_navigation_post_type', 10, 1 );
135
136 /**
137 * Rename the menu title from "All Navigation Menus" to "Navigation Menus".
138 */
139 function gutenberg_rename_navigation_post_type_admin_menu_entry() {
140 global $submenu;
141 if ( ! isset( $submenu['themes.php'] ) ) {
142 return;
143 }
144
145 $post_type = get_post_type_object( 'wp_navigation' );
146 if ( ! $post_type ) {
147 return;
148 }
149
150 $menu_title_index = 0;
151 foreach ( $submenu['themes.php'] as $key => $menu_item ) {
152 if ( $post_type->labels->all_items === $menu_item[ $menu_title_index ] ) {
153 $submenu['themes.php'][ $key ][ $menu_title_index ] = $post_type->labels->menu_name; // phpcs:ignore WordPress.WP.GlobalVariablesOverride
154 return;
155 }
156 }
157 }
158
159 add_action( 'admin_menu', 'gutenberg_rename_navigation_post_type_admin_menu_entry' );
160
161 /**
162 * Registers the navigation areas supported by the current theme. The expected
163 * shape of the argument is:
164 * array(
165 * 'primary' => 'Primary',
166 * 'secondary' => 'Secondary',
167 * 'tertiary' => 'Tertiary',
168 * )
169 *
170 * @param array $new_areas Supported navigation areas.
171 */
172 function gutenberg_register_navigation_areas( $new_areas ) {
173 global $gutenberg_navigation_areas;
174 $gutenberg_navigation_areas = $new_areas;
175 }
176
177 // Register the default navigation areas.
178 gutenberg_register_navigation_areas(
179 array(
180 'primary' => 'Primary',
181 'secondary' => 'Secondary',
182 'tertiary' => 'Tertiary',
183 )
184 );
185
186 /**
187 * Returns the available navigation areas.
188 *
189 * @return array Registered navigation areas.
190 */
191 function gutenberg_get_navigation_areas() {
192 global $gutenberg_navigation_areas;
193 return $gutenberg_navigation_areas;
194 }
195
196 /**
197 * Retrieves navigation areas.
198 *
199 * @return array Navigation areas.
200 */
201 function gutenberg_get_navigation_areas_menus() {
202 $areas = get_option( 'wp_navigation_areas', array() );
203 if ( ! $areas ) {
204 // Original key used `fse` prefix but Core options should use `wp`.
205 // We fallback to the legacy option to catch sites with values in the
206 // original location.
207 $legacy_option_key = 'fse_navigation_areas';
208 $areas = get_option( $legacy_option_key, array() );
209 }
210 return $areas;
211 }
212
213 /**
214 * Shim that hides ability to edit visibility and status for wp_navigation type posts.
215 * When merged to Core, the CSS below should be moved to wp-admin/css/edit.css.
216 *
217 * This shim can be removed when the Gutenberg plugin requires a WordPress
218 * version that has the ticket below.
219 *
220 * @see https://core.trac.wordpress.org/ticket/54407
221 *
222 * @param string $hook The current admin page.
223 */
224 function gutenberg_hide_visibility_and_status_for_navigation_posts( $hook ) {
225 $allowed_hooks = array( 'post.php', 'post-new.php' );
226 if ( ! in_array( $hook, $allowed_hooks, true ) ) {
227 return;
228 }
229
230 /**
231 * HACK: We're hiding the description field using CSS because this
232 * cannot be done using a filter or an action.
233 */
234
235 $css = <<<CSS
236 body.post-type-wp_navigation div#minor-publishing {
237 display: none;
238 }
239 CSS;
240
241 wp_add_inline_style( 'common', $css );
242 }
243
244 add_action( 'admin_enqueue_scripts', 'gutenberg_hide_visibility_and_status_for_navigation_posts' );
245