Skip to content

Commit

Permalink
Create endpoint to fetch menu custom items
Browse files Browse the repository at this point in the history
  • Loading branch information
Aljullu committed May 7, 2021
1 parent 1007736 commit c79bae3
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 19 deletions.
78 changes: 78 additions & 0 deletions lib/class-wp-rest-menu-custom-items-controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
/**
* WP_REST_Menu_Custom_Items_Controller class.
*
* @package gutenberg
*/

/**
* Class that returns the menu items added via the
* `customize_nav_menu_available_items` filter.
*/
class WP_REST_Menu_Custom_Items_Controller extends WP_REST_Controller {
/**
* Constructor.
*/
public function __construct() {
$this->namespace = '__experimental';
$this->rest_base = 'menu-custom-items';
}

/**
* Registers the necessary REST API routes.
*
* @access public
*/
public function register_routes() {
register_rest_route(
$this->namespace,
'/' . $this->rest_base,
array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_menu_custom_items' ),
'permission_callback' => array( $this, 'permissions_check' ),
'args' => $this->get_collection_params(),
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);
}

/**
* Checks if a given request has access to read menu items if they have access to edit them.
*
* @return true|WP_Error True if the request has read access, WP_Error object otherwise.
*/
public function permissions_check() {
$post_type = get_post_type_object( 'nav_menu_item' );
if ( ! current_user_can( $post_type->cap->edit_posts ) ) {
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to view menu items.', 'gutenberg' ), array( 'status' => rest_authorization_required_code() ) );
}
return true;
}

/**
* Returns the menu items added via the
* `customize_nav_menu_available_item_types` filter.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_REST_Response|WP_Error Menu custom items, or WP_Error if type could not be found.
*/
public function get_menu_custom_items( $request ) {
$requested_type = $request->get_param( 'type' );
$item_types = apply_filters( 'customize_nav_menu_available_item_types', array() );

if ( is_array( $item_types ) ) {
foreach ( $item_types as $item_type ) {
if ( $item_type['type'] === $requested_type ) {
return rest_ensure_response(
apply_filters( 'customize_nav_menu_available_items', array(), $item_type['type'], $item_type['object'], 0 )
);
}
}
}

return new WP_Error( 'rest_invalid_menu_item_type', __( 'This item type could not be found.', 'gutenberg' ), array( 'status' => 404 ) );
}
}
3 changes: 3 additions & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ function gutenberg_is_experiment_enabled( $name ) {
if ( ! class_exists( 'WP_REST_Menus_Controller' ) ) {
require_once __DIR__ . '/class-wp-rest-menus-controller.php';
}
if ( ! class_exists( 'WP_REST_Menu_Custom_Items_Controller' ) ) {
require_once __DIR__ . '/class-wp-rest-menu-custom-items-controller.php';
}
if ( ! class_exists( 'WP_REST_Menu_Items_Controller' ) ) {
require_once __DIR__ . '/class-wp-rest-menu-items-controller.php';
}
Expand Down
9 changes: 9 additions & 0 deletions lib/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ function gutenberg_register_rest_customizer_nonces() {
}
add_action( 'rest_api_init', 'gutenberg_register_rest_customizer_nonces' );

/**
* Registers the custom menu items REST API route.
*/
function gutenberg_register_rest_menu_custom_items() {
$nav_menu_location = new WP_REST_Menu_Custom_Items_Controller();
$nav_menu_location->register_routes();
}
add_action( 'rest_api_init', 'gutenberg_register_rest_menu_custom_items' );

/**
* Registers the Sidebars & Widgets REST API routes.
*/
Expand Down
36 changes: 22 additions & 14 deletions packages/block-library/src/navigation-link/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ export default function NavigationLinkEdit( {
rel,
title,
kind,
suggestions = [],
} = attributes;
const link = {
url,
Expand All @@ -243,6 +242,16 @@ export default function NavigationLinkEdit( {
const itemLabelPlaceholder = __( 'Add link…' );
const ref = useRef();

const isCustomItemType =
! [
'post',
'page',
'category',
'tag',
'post_format',
'custom',
].includes( type ) && ! [ 'taxonomy', 'post-type' ].includes( kind );

const {
isAtMaxNesting,
isParentOfSelectedBlock,
Expand All @@ -252,13 +261,15 @@ export default function NavigationLinkEdit( {
numberOfDescendants,
userCanCreatePages,
userCanCreatePosts,
fetchMenuCustomItems,
} = useSelect(
( select ) => {
const {
getClientIdsOfDescendants,
hasSelectedInnerBlock,
getSelectedBlockClientId,
getBlockParentsByBlockName,
getSettings,
} = select( blockEditorStore );

const selectedBlockId = getSelectedBlockClientId();
Expand Down Expand Up @@ -291,6 +302,8 @@ export default function NavigationLinkEdit( {
'create',
'posts'
),
fetchMenuCustomItems: getSettings()
.__experimentalFetchMenuCustomItems,
};
},
[ clientId ]
Expand Down Expand Up @@ -450,19 +463,16 @@ export default function NavigationLinkEdit( {
missingText = __( 'Add a link' );
}

const fetchCustomItemTypeSuggestions = ( val ) => {
return Promise.resolve(
suggestions
.filter(
( item ) =>
val === '' || item.title.match( new RegExp( val, 'i' ) )
)
.map( ( item ) => ( {
const fetchCustomItemTypeSuggestions = ( search ) => {
return fetchMenuCustomItems( search, { type } ).then(
( customItems ) => {
return customItems.map( ( item ) => ( {
id: item.id,
title: item.title,
url: item.url,
type: 'URL',
} ) )
} ) );
}
);
};

Expand Down Expand Up @@ -587,9 +597,7 @@ export default function NavigationLinkEdit( {
value={ link }
showInitialSuggestions={ true }
withCreateSuggestion={
suggestions.length > 0
? false
: userCanCreate
isCustomItemType ? false : userCanCreate
}
createSuggestion={ handleCreate }
createSuggestionButtonText={ ( searchTerm ) => {
Expand Down Expand Up @@ -617,7 +625,7 @@ export default function NavigationLinkEdit( {
kind
) }
fetchSuggestions={
suggestions.length > 0
isCustomItemType
? fetchCustomItemTypeSuggestions
: null
}
Expand Down
3 changes: 1 addition & 2 deletions packages/block-library/src/navigation-link/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,7 @@ function register_block_core_navigation_link() {
'title' => $item_type['title'],
'description' => '',
'attributes' => array(
'type' => $item_type['type'],
'suggestions' => apply_filters( 'customize_nav_menu_available_items', array(), $item_type['type'], $item_type['object'] ),
'type' => $item_type['type'],
),
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* WordPress dependencies
*/
import apiFetch from '@wordpress/api-fetch';
import { addQueryArgs } from '@wordpress/url';

const fetchMenuCustomItems = async ( search, { type } ) => {
const path = addQueryArgs( '/__experimental/menu-custom-items', { type } );
return apiFetch( {
path,
} ).then( ( results ) => {
return results.filter(
( result ) =>
search === '' || result.title.match( new RegExp( search, 'i' ) )
);
} );
};

export default fetchMenuCustomItems;
1 change: 1 addition & 0 deletions packages/core-data/src/fetch/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as __experimentalFetchLinkSuggestions } from './__experimental-fetch-link-suggestions';
export { default as __experimentalFetchRemoteUrlData } from './__experimental-fetch-remote-url-data';
export { default as __experimentalFetchMenuCustomItems } from './__experimental-fetch-menu-custom-items';
8 changes: 7 additions & 1 deletion packages/edit-navigation/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
__experimentalRegisterExperimentalCoreBlocks,
} from '@wordpress/block-library';
import { render } from '@wordpress/element';
import { __experimentalFetchLinkSuggestions as fetchLinkSuggestions } from '@wordpress/core-data';
import {
__experimentalFetchLinkSuggestions as fetchLinkSuggestions,
__experimentalFetchMenuCustomItems as fetchMenuCustomItems,
} from '@wordpress/core-data';

/**
* Internal dependencies
Expand All @@ -30,6 +33,9 @@ export function initialize( id, settings ) {
settings.__experimentalFetchLinkSuggestions = ( search, searchOptions ) =>
fetchLinkSuggestions( search, searchOptions, settings );

settings.__experimentalFetchMenuCustomItems = ( search, searchOptions ) =>
fetchMenuCustomItems( search, searchOptions, settings );

render(
<Layout blockEditorSettings={ settings } />,
document.getElementById( id )
Expand Down
7 changes: 6 additions & 1 deletion packages/edit-site/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
__experimentalRegisterExperimentalCoreBlocks,
} from '@wordpress/block-library';
import { render } from '@wordpress/element';
import { __experimentalFetchLinkSuggestions as fetchLinkSuggestions } from '@wordpress/core-data';
import {
__experimentalFetchLinkSuggestions as fetchLinkSuggestions,
__experimentalFetchMenuCustomItems as fetchMenuCustomItems,
} from '@wordpress/core-data';

/**
* Internal dependencies
Expand All @@ -25,6 +28,8 @@ import Editor from './components/editor';
export function initialize( id, settings ) {
settings.__experimentalFetchLinkSuggestions = ( search, searchOptions ) =>
fetchLinkSuggestions( search, searchOptions, settings );
settings.__experimentalFetchMenuCustomItems = ( search, searchOptions ) =>
fetchMenuCustomItems( search, searchOptions, settings );
settings.__experimentalSpotlightEntityBlocks = [ 'core/template-part' ];

registerCoreBlocks();
Expand Down
7 changes: 6 additions & 1 deletion packages/edit-widgets/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import {
__experimentalGetCoreBlocks,
__experimentalRegisterExperimentalCoreBlocks,
} from '@wordpress/block-library';
import { __experimentalFetchLinkSuggestions as fetchLinkSuggestions } from '@wordpress/core-data';
import {
__experimentalFetchLinkSuggestions as fetchLinkSuggestions,
__experimentalFetchMenuCustomItems as fetchMenuCustomItems,
} from '@wordpress/core-data';
import { registerLegacyWidgetVariations } from '@wordpress/widgets';

/**
Expand Down Expand Up @@ -42,6 +45,8 @@ export function initialize( id, settings ) {
registerBlock( widgetArea );
settings.__experimentalFetchLinkSuggestions = ( search, searchOptions ) =>
fetchLinkSuggestions( search, searchOptions, settings );
settings.__experimentalFetchMenuCustomItems = ( search, searchOptions ) =>
fetchMenuCustomItems( search, searchOptions, settings );
render(
<Layout blockEditorSettings={ settings } />,
document.getElementById( id )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
store as coreStore,
__experimentalFetchLinkSuggestions as fetchLinkSuggestions,
__experimentalFetchRemoteUrlData as fetchRemoteUrlData,
__experimentalFetchMenuCustomItems as fetchMenuCustomItems,
} from '@wordpress/core-data';

/**
Expand Down Expand Up @@ -110,6 +111,8 @@ function useBlockEditorSettings( settings, hasTemplate ) {
fetchLinkSuggestions( search, searchOptions, settings ),
__experimentalFetchRemoteUrlData: ( url ) =>
fetchRemoteUrlData( url ),
__experimentalFetchMenuCustomItems: ( search, searchOptions ) =>
fetchMenuCustomItems( search, searchOptions, settings ),
__experimentalCanUserUseUnfilteredHTML: canUseUnfilteredHTML,
__experimentalUndo: undo,
__experimentalShouldInsertAtTheTop: isTitleSelected,
Expand Down

0 comments on commit c79bae3

Please sign in to comment.