PluginProbe
Gutenberg / 12.6.1
Gutenberg v12.6.1
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.6.1, at lib/navigation.php

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